DEV Community

Minds
Minds

Posted on

What it took to ship a production remote MCP server with OAuth 2.1

Publishing an MCP endpoint is easy. Making it behave consistently across clients is where the work starts.

We recently shipped a hosted MCP server for Minds, an evidence-grounded synthetic market research platform. The server now connects to ChatGPT, Claude, Cursor, Google Antigravity, and clients that support Streamable HTTP.

Here are the implementation lessons that mattered.

1. The transport endpoint is not a landing page

Our MCP client URL is:

https://getminds.ai/mcp
Enter fullscreen mode Exit fullscreen mode

That URL speaks the protocol. A normal browser should instead reach an indexable setup guide. We therefore keep two explicit fields wherever a registry supports them: the remote transport URL for clients and /mcp/setup for humans.

2. Accept both JSON and event-stream responses

One early integration failed with:

Not Acceptable: Client must accept text/event-stream
Enter fullscreen mode Exit fullscreen mode

The robust client request advertises both response types:

Accept: application/json, text/event-stream
Content-Type: application/json
Enter fullscreen mode Exit fullscreen mode

Our current endpoint successfully negotiates a JSON initialize response and returns an Mcp-Session-Id for the session.

3. Let OAuth discovery do the work

The initialize response points clients to OAuth protected-resource metadata. Clients that support dynamic registration can discover the flow without a copied client ID or secret. API keys remain available for environments that securely support custom bearer headers.

4. Keep tool schemas live and documentation descriptive

The server currently exposes 15 tools across audiences, panels, durable studies, study drafts, summaries, method discovery, and export. Clients should inspect the live tools/list response rather than hard-code schemas from an old article.

Our public repository documents the role of every operation, but deliberately treats the running server as the schema authority.

5. Separate planning from durable execution

For multi-question research, the client first calls plan_panel_study. A human can review the plan before run_panel_study starts a durable server-side run. The agent polls get_panel_study instead of assuming a long task finished inside one chat turn.

6. State the research boundary

Synthetic panels are useful for an early decision-support pass: sharpening a question, surfacing objections, comparing plausible reactions, and deciding what deserves real-respondent validation. They are not representative human fieldwork.

The repository and setup guide are public:

If you maintain a remote MCP server, I would be interested in the client-specific edge case that consumed the most time for you.

Top comments (2)

Collapse
 
marcusykim profile image
Marcus Kim

The distinction between a protocol endpoint and a human-facing setup page is easy to overlook, but it probably prevents a surprising amount of client confusion. Supporting both application/json and text/event-stream, while returning an Mcp-Session-Id, also shows how much interoperability work lives outside the headline protocol. I especially like separating plan_panel_study from the durable run_panel_study: for founder-led products, making the expensive or consequential step reviewable is a product decision as much as an architecture decision. The tradeoff is extra state and polling, but that complexity buys recoverability and.

Collapse
 
mads_hansen_27b33ebfee4c9 profile image
Mads Hansen

The protected-resource discovery point is especially important. One extra production test I would add is verifying that every access token is audience-bound to this MCP resource, not merely valid for the same authorization server. That catches confused-deputy paths where a token minted for another API is accepted here. I would also test refresh-token rotation/reuse detection, revoked consent during an active MCP session, resource-metadata cache expiry, and a client that ignores WWW-Authenticate resource metadata. For API-key fallback, keeping it as a separately observable auth mode with narrower capabilities and independent revocation helps prevent the compatibility path from quietly becoming the least-governed production path.