Most Model Context Protocol (MCP) servers shipped in the last year have a structural flaw: they stop at detection.
They wrap GET endpoints, dump a 20,000-token JSON blob of analytics or search results into your context window, and then force the human to open a browser tab, click through a 6-step wizard, and finish the job manually.
Internally, we call the opposite philosophy Outputmaxxing: every tool surface—especially an MCP server—must end in a concrete output or state transition, not just a diagnostic report.
This week, we shipped and upgraded 4 remote Streamable HTTP MCP servers across our product fleet so developers and founders in Claude Code, Cursor, and Codex can go from discovery to execution in a single chat session:
- LinkDR (Awesome Tools listing) — 14 tools for domain authority, Google top-100 SERPs, AI search citations, in-chat publisher site approvals, and ordering backlinks.
- AI SEO Tracker (Awesome Tools listing) — 12 tools for ChatGPT, Perplexity, Gemini, Copilot & Google AI Overview visibility tracking and missing competitor citation discovery.
- GenPPT (Awesome Tools listing) — 8 tools to turn prompts, URLs, or PDFs into approved slide outlines, rendered 16:9 visuals, and native
.pptx/.pdfexports. - Awesome Tools — 7 keyless public tools (+ 16 admin tools) to search software directories, submit a SaaS tool, and verify backlinks.
Here is the engineering breakdown of how we architected remote Streamable HTTP MCP servers that safely handle mutations and real payments—plus the production traps we hit along the way.
1. Designing for "Outputmaxxing": Read Tools vs. Write Loops
When we audited how developers actually used our v1 MCP servers, we noticed that read-only tools (get_domains, aiseo_list_sources) were always followed by the user asking: "Okay, now add these 15 prompts to my project" or "Approve those two DR 50 publishers and order 3 more links."
To close the loop across all four products, we paired every diagnostic read with a state-mutating write tool:
| Product | Remote MCP Endpoint | Read / Diagnostic Tools | Output / Action Tools |
|---|---|---|---|
| LinkDR | https://linkdr.com/mcp | get_domains, search_domains, search_keywords, get_keyword_serp, get_my_ai_answers, list_my_pending_approvals | create_my_project, update_my_project_strategy, decide_my_site_approval, order_backlinks |
| AI SEO Tracker | https://aiseotracker.com/mcp | aiseo_get_scan, aiseo_list_sources, aiseo_list_missing_sources, aiseo_list_snippets | aiseo_create_project, aiseo_add_prompts, aiseo_activate_plan |
| GenPPT | https://genppt.com/mcp | genppt_account_status, genppt_list_decks, genppt_get_deck | genppt_create_deck, genppt_generate_slides, genppt_export_deck, genppt_upgrade_plan |
| Awesome Tools | https://awesome.tools/mcp | search_tools, get_tool, list_categories, list_tags | submit_tool, verify_my_backlink, submit_feedback |
For example, in AI SEO Tracker, aiseo_list_missing_sources queries every third-party URL cited by ChatGPT, Perplexity, Gemini, Copilot, and Google AI Overviews where your tracked competitors appear and your domain is absent, sorted by totalPromptsWithoutYourSite. You can take that exact list of high-priority URLs and feed it straight into LinkDR's MCP tools in the same workspace.
2. The 2-Step confirmPaymentSpend Safety Pattern
The hardest design problem in agentic commerce is preventing accidental spend without forcing the user out of the terminal.
If a tool immediately charges a saved card on the first call, a hallucinated parameter or eager agent loop can trigger an unwanted $500 invoice. Conversely, if the tool only returns a generic pricing page URL, the agent workflow is broken.
We standardized a 2-step confirmPaymentSpend protocol across order_backlinks (LinkDR), aiseo_activate_plan (AI SEO Tracker), genppt_upgrade_plan (GenPPT), and submit_tool (Awesome Tools):
Step 1: Zero-Side-Effect Quote Preview (confirmPaymentSpend: false)
By default, confirmPaymentSpend is false. Calling the tool in preview mode performs zero billing mutations:
- It does not create unpaid database drafts that pollute abandoned-cart crons or burn daily IP rate limits.
- It calculates the exact itemized price (
totalUsd), checks if the authenticated workspace has a usable payment method on file (brand,last4), and builds a pre-filled 1-click checkout fallback URL.
{ "status": "preview", "requiresConfirmation": true, "quote": { "package": "3x DR 40+ Authority Backlinks", "subtotalUsd": 720, "discountUsd": 25, "totalUsd": 695 }, "savedCard": { "available": true, "brand": "visa", "last4": "4242" }, "checkoutUrl": "https://linkdr.com/agent/checkout?project=acme&pack=dr40x3&code=AGENTIC", "nextStep": "Show the user the itemized quote ($695.00 USD on Visa ••4242) and re-call order_backlinks with confirmPaymentSpend: true and expectedTotalUsd: 695 after explicit approval." } Step 2: Price-Locked Execution (confirmPaymentSpend: true + expectedTotalUsd)
When the human replies "Looks good, place the order", the agent calls the tool a second time with:
confirmPaymentSpend: trueexpectedTotalUsd: 695
On the server, we assert Math.abs(calculatedTotalUsd - expectedTotalUsd) < 0.01 so the price cannot drift between preview and execution.
- If the user has a saved Stripe card on file (LinkDR one-time orders), we create and pay a Stripe Invoice off-session, mark the order paid inline (and idempotently via
invoice.payment_succeeded), and protectsavedCardInvoiceIdrows from 24-hour abandoned-checkout cleanup. - If the card requires 3D Secure (
authentication_required), or if the user is on a keyless/hosted checkout flow (Polar on AI SEO Tracker, Stripe Checkout on GenPPT and Awesome Tools), the server cleanly hands back the hosted payment URL.
3. Dual-Mode Public + Admin Routing on a Single /mcp Endpoint
For Awesome Tools (https://awesome.tools/mcp), we wanted any founder to be able to add https://awesome.tools/mcp to Cursor or Claude Code with zero API key setup to search the directory, submit their product, or verify their backlink—while keeping our 16 operator tools (upsert_tool, review_intake, capture_tool_media) on the same server.
We solved this at the JSON-RPC dispatcher layer:
- No
Authorizationheader: The server exposes the 7 public founder tools (search_tools,get_tool,list_categories,list_tags,submit_tool,verify_my_backlink,submit_feedback). -
Authorization: Bearer $MCP_API_KEY: The server unlocks all 16 admin tools. - Idempotent Draft Reuse: If a founder previews a paid submission (
$49Featured or$149Sponsor) withconfirmPaymentSpend: false, the server returns the price card without reserving the domain or emailing the submitter. When they confirm, it reuses any existing pending draft for that domain+email pair without burning their 3/day IP submission limit, while blocking cross-submitter domain hijacks.
4. Production Gotchas We Hit (So You Don't Have To)
Gotcha 1: Cloudflare 403 error code: 1010 on Headless MCP Clients
Shortly after deploying https://genppt.com/mcp and https://linkdr.com/mcp, we noticed that curl and Node fetch succeeded with 200 OK, but Python-based MCP clients and registry validators (User-Agent: Python-urllib/3.12) were rejected at the Cloudflare edge with 403 Forbidden (error code: 1010).
Why: Cloudflare's Browser Integrity Check (browser_check: on) blocks default Python urllib and certain headless HTTP user agents before the request ever reaches your origin container.
The Fix: Disable browser_check via the Cloudflare Zone Settings API across every domain hosting a public /mcp endpoint:
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/browser_check" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"value":"off"}' Gotcha 2: Key Rotation Race Conditions (SELECT ... FOR UPDATE)
In GenPPT (https://genppt.com/mcp), users can generate and rotate gppt_ MCP API keys from /app/account (POST /api/account/mcp-key). Storing raw tokens in Postgres is a non-starter, so we store SHA-256 hashes and wrap key rotation in a SELECT ... FOR UPDATE transaction lock on the user row so concurrent clicks can never leave two active MCP keys or orphan a revocation. We also added automatic gppt_, bzly_, and Bearer token redaction inside every *_submit_feedback tool so agents cannot accidentally leak credentials into logs or Slack alerts.
Gotcha 3: Stateless Streamable HTTP & JSON-RPC Edge Cases
Many MCP clients probe resources/list and prompts/list immediately after initialize and notifications/initialized. Make sure your Streamable HTTP route:
- Returns
202 Accepted(with an empty body) onnotifications/*. - Returns empty arrays (
{ resources: [] },{ prompts: [] }) or a clean JSON-RPC-32601with HTTP200rather than a hard HTTP500or404. - Enforces a strict request body cap (e.g.,
64 KiB) on public endpoints.
5. Publishing Remote Servers to the Official MCP Registry (/.well-known/mcp-registry-auth)
When publishing remote Streamable HTTP servers (without an npm or PyPI package) to the Official MCP Registry (registry.modelcontextprotocol.io) under reverse-DNS namespaces like com.linkdr/mcp or com.genppt/mcp, you can prove domain ownership over HTTP using an Ed25519 signature:
- Generate a 32-byte Ed25519 keypair.
- Serve the public key at
https://<your-domain>/.well-known/mcp-registry-authas plain text:
v=MCPv1; k=ed25519; p=<base64-encoded-32-byte-public-key> - Authenticate with
mcp-publisher login http --domain=<your-domain> --private-key=<hex-seed>and publish yourserver.jsonpointing to yourstreamable-httpremote URL.
Try the 4 MCP Servers in Claude Code or Cursor
All four remote Streamable HTTP MCP servers are live today:
{ "mcpServers": { "linkdr": { "url": "https://linkdr.com/mcp" }, "aiseotracker": { "url": "https://aiseotracker.com/mcp" }, "genppt": { "url": "https://genppt.com/mcp", "headers": { "Authorization": "Bearer gppt_your_api_key" } }, "awesome-tools": { "url": "https://awesome.tools/mcp" } } } You can also browse all of our MCP-enabled tools under the new MCP tag on Awesome Tools.

