All insights

Claude and ChatGPT connectors

Build an MCP server for your product: a production guide

An MCP server should add a new way in to your product, not a new set of rules.

Co-founder and CTO, Datics AI8 min read

In brief

To build an MCP server for an established product, put a thin remote service in front of the APIs you already run, expose a handful of well-described tools chosen from real user questions, and serve them over Streamable HTTP. Every call carries an OAuth token, so it runs as the signed-in user and your existing permission checks decide what comes back. Start read-only, cap every result, log every call and test before real users arrive.

On this page
  1. 01Build an MCP server by mapping your API to tools, resources and prompts
  2. 02Design a small set of tools from real questions
  3. 03Run it remotely over Streamable HTTP
  4. 04Authorize every call as the signed-in user
  5. 05Set limits, watch cost and keep an audit trail
  6. 06Test with the Inspector, then on real questions
  7. 07What we see in production
  8. Frequently asked questions

01Build an MCP server by mapping your API to tools, resources and prompts

The MCP documentation describes three building blocks a server can offer, and the useful distinction is who controls each. Tools are controlled by the model, which decides when to call them. Resources are read-only context the host application chooses to load. Prompts are templates the user picks on purpose.

For a product server, tools carry almost all the value: "which jobs are late today?" is a tool call, because the model decides to ask and chooses the arguments. Resources suit stable reference material, such as a glossary of your status codes. Prompts are optional; add one only when users repeat a multi-step task, such as a weekly account review.

Check what each host supports before you design for it. Anthropic's guide to building an MCP server for Claude says Claude supports tools, prompts and resources but not yet resource subscriptions or sampling, and sets limits of about 150,000 characters per tool result and 240 seconds per tool call on claude.ai and the desktop app.

Architecturally, the server sits between the AI host and your existing API gateway. It validates the token, picks the tool, calls one or two of your endpoints as that user, trims the response to approved fields and returns it. It holds no business logic and no copy of your data.

02Design a small set of tools from real questions

The fastest way to a bad server is one tool per endpoint. OpenAI's guidance on defining tools warns against mirroring an internal API and says to start from the outcomes users expect, keep reads and writes in separate tools, and never make the model guess identifiers or account scope. We go further: pull fifty real questions from support tickets and search logs, cluster them, and write a tool only for clusters that recur.

Three steps from fifty real user questions to recurring clusters to three to five tools
Start from what users ask, not from your list of endpoints.

The MCP tools specification adds two practical details. The tool list may vary by the authorization on the request, so a dispatcher and a billing clerk can see different tools. And servers should return tools in a deterministic order so clients can cache the list.

DecisionDoDo not
Scope of a toolOne user goal, such as list_late_jobsOne endpoint each, such as get_jobs_v2_internal
DescriptionSay when to use it, what it returns and its limitsRestate the tool name or use internal jargon
InputsTyped and bounded, with enums and date rangesFree text the server must parse, or a tenant ID
OutputApproved fields, stable IDs, a row capThe raw API payload with every field
ErrorsA clear tool error the model can act onA stack trace, or an empty list that hides a denial
Reads and writesSeparate tools, writes added laterOne tool that reads or changes based on a flag
AnnotationsreadOnlyHint true only when nothing can changeAnnotations used in place of a permission check

On errors, the specification separates protocol errors from tool execution errors. A bad date or an API timeout should come back as a result with isError set and a plain message, because models can use that feedback to correct themselves. Our guide to LLM tool calling covers descriptions and schemas in more depth.

03Run it remotely over Streamable HTTP

Remote servers use Streamable HTTP: one endpoint, usually /mcp, that accepts POST. The server answers each request with a single JSON object or a short event stream scoped to that request. Servers must validate the Origin header to block DNS rebinding.

Two points are easy to miss. First, versions. The 2026-07-28 revision removed protocol-level sessions, and every request now carries its protocol version. The versioning page explains how one endpoint can serve both this style and the older handshake style. That matters because hosts move at their own pace: Anthropic's build guide lists the 2025 authorization revisions as the ones Claude follows. Test against each real client before you drop any revision.

Second, state. With no protocol session, state that spans calls travels as an explicit handle in tool arguments. The MCP security best practices say servers must not treat possession of a handle as authentication, and should key stored state by the user ID from the verified token. We keep tools stateless wherever we can, which also lets the server scale out behind a load balancer.

Host the server where your API already runs, behind your existing gateway and firewall, at a stable public HTTPS address. OpenAI's MCP server guide notes that a temporary tunnel does not meet public submission requirements.

04Authorize every call as the signed-in user

The MCP authorization specification treats your server as an OAuth 2.1 resource server. In engineering terms:

Four steps of MCP authorization from an unauthenticated request to a call to your API as the signed-in user
The tenant comes from the token, never from the chat.
  1. 01

    Publish Protected Resource Metadata

    and return 401 with a WWW-Authenticate header pointing to it, so clients can find your authorization server.

  2. 02

    Accept only tokens issued for this server.

    Clients send a resource parameter naming your server, and your server checks the token's audience. Tokens never travel in a query string.

  3. 03

    Never pass a client token through to your API.

    The security guidance calls token passthrough explicitly forbidden. Exchange it for a downstream credential your API trusts, so logs show the server acting for a named user.

  4. 04

    Support the registration methods hosts use.

    Claude can identify itself through a Client ID Metadata Document Anthropic hosts, register through Dynamic Client Registration, or use a client you pre-register, as its custom connector page explains, and its build guide lists https://claude.ai/api/mcp/auth_callback as the redirect URI to allow. OpenAI's authentication guide requires PKCE with S256 and says to check signature, issuer, audience, expiry and scopes on every request.

  5. 05

    Keep scopes small.

    Advertise a minimal read scope and ask for more with a 403 insufficient_scope challenge when a user first reaches a write tool.

Tenant isolation follows from the same rule. The customer account comes from the verified token, never from a tool argument. If a tool accepts an account_id, someone will paste another customer's. Your API then applies the same row-level checks it applies to the web app, as we describe in tenant isolation for AI.

Read-only first is practical, not timid. Three read tools cannot change a record by mistake, which shortens security review and shows you what users really ask before you add writes. When writes arrive, give them their own tools, set destructiveHint honestly, require a scope step-up, and recheck permissions in your API on every call.

05Set limits, watch cost and keep an audit trail

The tools specification says servers must validate inputs, implement access controls, rate limit tool invocations and sanitize outputs. Streamable HTTP helps: requests carry Mcp-Method and Mcp-Name headers that mirror the body, so your gateway can rate limit per user, tenant and tool without parsing JSON.

Cost lands in two places. Every tool call is real load on your API, so cap date ranges, rows and page depth. And everything a tool returns enters the model's context, so a 400-row dump is slow and expensive for the user. Return the 25 most relevant rows and a total count, and let the model ask for more.

Log each call with the user, tenant, tool, redacted arguments, downstream endpoints, status and latency, under a correlation ID that also appears in your API logs. Log scope step-ups and denials as their own events. Our guide to an AI audit trail covers what to keep.

06Test with the Inspector, then on real questions

The MCP Inspector is the reference tool. It runs with npx @modelcontextprotocol/inspector, connects to a remote server with --server-url, walks the OAuth flow, and has a --cli mode for CI. On machines without a keychain it saves OAuth tokens to an unencrypted file, so use test accounts in CI.

Our sequence:

  1. 01

    Protocol and auth in the Inspector:

    discovery, 401 challenges, token refresh, tool lists per role, and every tool with valid, invalid and out-of-range inputs.

  2. 02

    An access matrix in CI:

    users from two tenants, each with an allowed and a denied role, against every tool on every build.

  3. 03

    Real questions in real hosts:

    add the staging server to Claude and ChatGPT and run the clustered questions. Score tool choice, arguments, and whether the answer matches a direct query.

  4. 04

    Failure drills:

    slow API, expired token, revoked user, empty results. Each should produce a clear message, not a guess.

Step 3 is the one teams skip, and it finds most description problems. Our article on AI agent testing covers scoring at scale.

Then version with care. The protocol has no tool version field, so treat each tool name as a public contract. Add output fields freely; never change what an existing input means. When behavior must change, add list_late_jobs_v2, mark the old tool deprecated in its description, watch logs until calls stop, then remove it and send a list-changed notification.

07What we see in production

We run a connector like this on our own operations data: our team asks Claude and ChatGPT about projects, people and invoices, and access follows each person's role.

On CleanHaus, a live platform for short-term rental turnovers, the assistant acts through the product's existing APIs under each user's own login, with Cognito identity on every call. Each backend API became a registered tool with a name, description, method, path and parameter schema, and each channel and role gets its own tool allowlist, so a cleaner's session has no owner tools. That is the shape a good MCP server takes: tools filtered by who is calling, permissions enforced by the API underneath.

For Superlinked, we built a Qdrant storage and search connector for their open source framework. It is a different kind of connector, but the contract lesson carries over: it implemented the framework's shared connector interface so existing code kept working, the only agreed change to that interface was adding vector size, and the tests were written in pytest, the style the client asked for. Treat your tool contracts the same way.

If you want this built on your product, our MCP server development work starts with Tenon Starter at $2,500: up to three read-only tools that put your product inside Claude and ChatGPT, with each user signed in with their own account and the connector running in your own cloud by default. Tenon Plus adds actions that create or update records, each waiting for the user's approval.

Frequently asked questions

Should the MCP server live in our main application or run as a separate service?

Run it as a separate service in front of your existing API. That keeps the MCP surface small, lets you deploy and scale it on its own, and leaves your API enforcing permissions exactly as it does for the web app. The server should hold no business logic and no copy of your data.

Can one MCP server work with both Claude and ChatGPT?

Yes. Both connect to remote MCP servers over HTTP with OAuth, so one server can serve both. Plan for differences in each host's OAuth client, such as redirect URIs and client registration, and test in each host before release.

How many tools should our first MCP server have?

Fewer than you think. Three to five tools that answer the most common questions usually beat a long list, because similar tools with overlapping descriptions make the model pick the wrong one. Add tools only when real usage shows a question your set cannot answer.

How Datics helps

Datics specializes in Brownfield AI: production AI inside software people already rely on. Tenon Starter puts your product inside Claude and ChatGPT with up to three read-only tools, signed in with each user's own account, for $2,500.

›References (12)
  1. Model Context Protocol: Understanding MCP servers
  2. MCP specification: Tools
  3. MCP specification: Streamable HTTP transport
  4. MCP specification: Versioning and compatibility
  5. MCP specification: Authorization
  6. MCP: Security best practices
  7. MCP Inspector documentation
  8. Claude: Build an MCP server for Claude
  9. Claude: Add a connector that is not in the directory
  10. OpenAI: Build an MCP server
  11. OpenAI: Authentication
  12. OpenAI: Define tools

Related work

Case studies from our projects on the same subject.

CleanHaus

Property Management · Turnover operations SaaS

Hosts and cleaners manage rental turnovers in chat, within each person's permissions

Owners, managers and cleaners all talk in one property chat. Now an AI there acts for each of them, only within that person's role.

Brownfield AIAgentic workflowsPermission-aware
Read case study

Superlinked

Other software · Vector database connector

Superlinked's framework now stores and searches vectors in Qdrant, matching its other connectors

Qdrant stores data unlike Redis or MongoDB; we settled each gap with Superlinked's engineers first, and the interface gained only a vector size.

Forward deployedData foundationIntegrations
Read case study

Your customers already expect AI from your product.

Let us make it real inside the product you run today.