Sword-swift posting of pretty tweets to X — Tollbooth-monetized FastMCP server
git clone https://github.com/lonniev/excalibur-mcp{
"mcpServers": {
"excalibur-mcp": {
"command": "node",
"args": ["/path/to/excalibur-mcp/dist/index.js"]
}
}
}MCP Servers overview
# eXcalibur MCP Sword-swift posting of pretty tweets to X (Twitter) via AI agents, monetized with Bitcoin Lightning micropayments through the DPYC(TM) Tollbooth protocol. [](https://github.com/lonniev/excalibur-mcp) [](https://python.org) [](LICENSE) eXcalibur is a [FastMCP](https://github.com/jlowin/fastmcp) server that lets AI agents post to X (Twitter) with rich Unicode formatting and optional images. Patron authentication for X uses OAuth2 Authorization Code + PKCE -- no credentials appear in chat. Operator credentials (X app keys, BTCPay) arrive via human-in-the-loop Secure Courier and are stored in the operator's per-operator Neon vault schema. Tool calls are metered with [Tollbooth DPYC(TM)](https://github.com/lonniev/tollbooth-dpyc) pre-funded Lightning balances -- Don't Pester Your Customer. Part of the [DPYC(TM) Social Contract](https://github.com/lonniev/dpyc-community). ## Getting Started Connect via Horizon -- no local install needed: ``` https://www.fastmcp.cloud/mcp/lonniev/excalibur-mcp ``` ### Step 1: Check Session Call `excalibur_session_status` to see your current session state. If you have an active session with funded credits, you are ready to post. ### Step 2: X OAuth2 + PKCE (Patron Credentials for X) 1. Get your Nostr npub -- use the dpyc-oracle's `how_to_join()` tool, or any Nostr client. 2. Call `excalibur_begin_oauth(npub=<npub>)` -- returns an `authorize_url`. Open the primary `authorize_url` (not a shortlink) in your browser and authorize the app on X. 3. Call `excalibur_check_oauth_status(npub=<npub>)` -- completes the code exchange, vaults the tokens, and activates your session. Sessions are keyed by npub. Tokens are stored in the Neon vault and auto-refresh on expiry. ### Step 3: Secure Courier (Operator Credentials) Operator credentials (X OAuth2 app keys, BTCPay connection) are delivered via Secure Courier (`service="excalibur-operator"`). This is a human-in-the-loop flow: the operator consciously approves each credential delivery via their Nostr client. On `receive_credentials`, the relay DM is destructively drained -- credentials exist only in the Neon vault after receipt. ## Credits Model Tool calls cost `api_sats` per call. Credits have a `tranche_lifetime` -- each purchase creates a tranche that expires after the configured lifetime. Auth and balance tools are always free. Use `excalibur_check_balance` to see your balance and tranche expiry. Top up via `excalibur_purchase_credits`. ## Available Tools ### Standard Tools (from the wheel) Standard DPYC(TM) tools are registered by `register_standard_tools()` from [tollbooth-dpyc](https://github.com/lonniev/tollbooth-dpyc). These include session management, credit operations, Secure Courier, pricing, notarization, and Oracle delegation. Each tool is identified by a deterministic UUID v5. | Category | Tools | |----------|-------| | Session & Billing | `session_status`, `check_balance`, `account_statement`, `account_statement_infographic`, `restore_credits`, `service_status`, `check_price`, `check_authority_balance` | | Secure Courier | `request_credential_channel`, `receive_credentials`, `forget_credentials` | | Npub Proof | `request_npub_proof`, `receive_npub_proof` | | Purchase | `purchase_credits`, `check_payment` | | Pricing & Constraints | `get_pricing_model`, `set_pricing_model`, `reset_pricing_model`, `list_constraint_types` | | Notarization | `notarize_ledger`, `list_notarizations`, `get_notarization_proof` | | Onboarding | `get_operator_onboarding_status`, `get_patron_onboarding_status` | | OAuth (X) | `begin_oauth`, `check_oauth_status` | | Oracle (delegated) | `oracle_about`, `oracle_how_to_join`, `oracle_lookup_member`, `oracle_get_tax_rate`, `oracle_network_advisory` | ### Domain Tools (eXcalibur-specific) Domain tools are defined in `server.py` (with storage handlers under `tools/`). Prices are set by the operator's pricing model -- preview any call with `check_price`. Read and auth tools are free. **Posting to X** | Tool | Description | |------|-------------| | `post_tweet` | Post a text tweet with markdown-to-Unicode rich text formatting | | `post_tweet_image` | Post a tweet with a hero banner image (image URL or SVG rendered to PNG) | | `get_x_profile` | Fetch the connected X account's handle and name for this patron (free) | **Stored posts (drafts & scheduling)** | Tool | Description | |------|-------------| | `create_post` | Store a new post (draft or scheduled); returns its `post_id` | | `get_post` | Read one stored post by id (owner-scoped) | | `list_posts` | List your stored posts, server-side sorted, filtered, and paginated | | `update_post` | Patch a stored post (`doc`, `publish_at`, `recurrence`, `status`) | | `delete_post` | Delete a stored post (soft delete by default) | **Snippets & Voice** | Tool | Description | |------|-------------| | `list_snippets` | List your saved post snippets (server-side sorted/filtered/paginated) | | `get_snippet` | Read one saved snippet by id | | `save_snippet` | Save a reusable snippet (opening/footer/CTA) | | `delete_snippet` | Delete a saved snippet (free, owner-scoped) | | `get_voice` | Read your saved writing Voice (profile blurb + banned words) | | `save_voice` | Save your per-npub writing Voice | **AI editorial & dynamic blocks** | Tool | Description | |------|-------------| | `refine_post_region` | Refine a flagged region of a post with an LLM, server-side | | `resolve_dynamic_block` | Start resolving a dynamic (prompt-backed) post block; returns a claim check | | `fetch_dynamic_block` | Redeem a `resolve_dynamic_block` claim check (free, proof-gated) | **Scheduler** | Tool | Description | |------|-------------| | `process_scheduled_posts` | Publish every due scheduled post (operator-only) | | `get_scheduler_log` | Read recent scheduler-tick outcomes | | `scheduler_status` | The scheduler's configuration and current status (free; any proven patron) | | `scheduler_pending` | What the scheduled-post cron Worker is waiting on (operator-only) | | `scheduler_check_now` | Run one scheduler tick now (operator-only) | OAuth flow tools (`begin_oauth`, `check_oauth_status`) are now standard tools provided by the wheel (see the Standard Tools table above). All tools that take an `npub` also accept a `proof: str` parameter for kind-27235 Schnorr proof attestation. ## Security - **Npub identity** -- Patrons are identified by a Nostr public key (`npub`), not an email or password. One keypair per role, managed by the user. - **Kind-27235 Schnorr proof** -- Tool calls carry an NIP-98-style Schnorr signature proving the caller controls the claimed npub. Proof is cached for ~1 hour; renew via `request_npub_proof` / `receive_npub_proof`. - **Human-in-the-loop Secure Courier** -- Credential delivery requires conscious operator approval via Nostr DM. On receipt, the relay message is destructively drained so secrets exist only in the encrypted Neon vault. - **Per-operator Neon schema** -- Each operator's credentials are stored in an isolated Postgres schema with a dedicated LOGIN role. No cross-operator access. ## Architecture ``` src/excalibur_mcp/ server.py FastMCP server -- domain tools + register_standard_tools() config.py Pydantic settings from environment variables oauth_flow.py X-specific OAuth2 Authorization Code + PKCE wrapper x_client.py X API v2 client with OAuth 2.0 Bearer token auth formatter.py Markdown -> Unicode rich text (bold, italic, headers) refine.py Server-side editorial refinement for the post editor resolve.py Server-side resolution of dynamic (prompt-backed) post blocks scheduler.py Scheduled-post firing (publishes due posts on the owner's behalf) tools/ Domain storage handlers (posts, snippets, voices) db/ eXcalibur persistence on the wheel's NeonVault (posts, scheduler runs, migrations) ``` **Key design choices:** - **OAuth2 Authorization Code + PKCE** -- Patron tokens acquired via browser flow. `begin_oauth` returns the primary `authorize_url` (not a shortlink); `check_oauth_status` completes the exchange. Tokens stored in Neon vault, auto-refreshed on expiry. No OAuth 1.0a. - **UUID v5 tool identity** -- Every tool (standard and domain) has a deterministic UUID derived from its capability name. Pricing, constraints, and billing all key on UUID. - **Standard tools from the wheel** -- `register_standard_tools()` provides all DPYC(TM) infrastructure tools. Only domain-specific X/Twitter tools are defined in `server.py`. - **Markdown to Unicode** -- Converts `**bold**`, `*italic*`, and `# headers` to Unicode characters that render in tweets without markup syntax. ## Self-Hosting ### Environment Variables #### DPYC(TM) Identity (required to boot) | Variable | Required | Description | |----------|----------|-------------| | `TOLLBOOTH_NOSTR_OPERATOR_NSEC` | Yes | Operator's Nostr secret key for identity bootstrap and DM encryption | This is the only env var required to start. All other secrets (X app keys, BTCPay credentials) arrive via Secure Courier credential templates and are stored in the per-operator Neon vault schema. #### Operator Credentials (via Secure Courier) These are delivered via Secure Courier (`service="excalibur-operator"`), not set as environment variables: | Credential | Description | |------------|-------------| | `client_id` | X OAuth2 Client ID (from X Developer Portal) | | `client_secret` | X OAuth2 Client Secret (from X Developer Portal) | | `btcpay_host` | BTCPay Server URL | | `btcpay_store_id` | Store ID for invoices | | `btcpay_api_key` | API key with invoice permissions | Certified operators bootstrap their Neon database URL from the Authority via encrypted Nostr DM -- `NEON_DAT
What people ask about excalibur-mcp
What is lonniev/excalibur-mcp?
+
lonniev/excalibur-mcp is mcp servers for the Claude AI ecosystem. Sword-swift posting of pretty tweets to X — Tollbooth-monetized FastMCP server It has 3 GitHub stars and was last updated today.
How do I install excalibur-mcp?
+
You can install excalibur-mcp by cloning the repository (https://github.com/lonniev/excalibur-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is lonniev/excalibur-mcp safe to use?
+
lonniev/excalibur-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains lonniev/excalibur-mcp?
+
lonniev/excalibur-mcp is maintained by lonniev. The last recorded GitHub activity is from today, with 2 open issues.
Are there alternatives to excalibur-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy excalibur-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/lonniev-excalibur-mcp)<a href="https://claudewave.com/repo/lonniev-excalibur-mcp"><img src="https://claudewave.com/api/badge/lonniev-excalibur-mcp" alt="Featured on ClaudeWave: lonniev/excalibur-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!