MCP Server Development - Model Context Protocol Integrations

You need a Model Context Protocol server when your internal tools, data, or business logic should be reachable by Claude, Cursor, ChatGPT, Claude Code, Windsurf, and the next agent client your team has not heard of yet. The right MCP server turns an integration that used to be N custom plugins into one server that any compliant client can connect to. The wrong one becomes a security hole that ships your database to the public internet through a chat window. This page is for engineering leaders deciding whether to build, buy, or hire for an MCP server, and what good actually looks like in 2026.
I build MCP servers as a senior engineer who has been shipping agent infrastructure since before the protocol existed. The spec has moved fast: Anthropic open-sourced MCP in November 2024, the June 2025 revision made OAuth 2.1 the official authorization story for remote servers, Streamable HTTP replaced the legacy SSE transport, and the 2026 release candidate is finalizing stateless cores, MCP Apps for server-rendered UI, and the Tasks extension for long-running work. Production servers built before these revisions need migration. Production servers built today need to anticipate the next one.
What MCP Actually Is and Why It Won
MCP is a JSON-RPC 2.0 protocol that defines three primitives a server can expose to an LLM client: tools (functions the model can call), resources (data the model can read), and prompts (templates the user can invoke). It is intentionally narrow. The whole point is that one server speaks one protocol and every major client (Claude Desktop, Claude Code, Cursor, ChatGPT, Windsurf, Zed, Sourcegraph Cody, Replit) consumes it the same way.
Before MCP, every integration was a bespoke plugin per client, with mismatched schemas and ad-hoc auth. MCP collapses that surface. For a company with internal APIs that should be agent-reachable, this is the difference between writing one server and writing six and a half.
- JSON-RPC 2.0 over Streamable HTTP (remote) or stdio (local) - those are the only two transports that matter in 2026
- Three primitives only: tools, resources, prompts - keep this taxonomy clear or your server gets confusing for agents to use
- OAuth 2.1 with PKCE is the official authorization story for remote servers as of the June 2025 spec
- Streamable HTTP replaced the legacy SSE transport in the November 2025 spec; new servers should not ship SSE
- The 2026-07-28 release candidate adds Mcp-Method and Mcp-Name headers so gateways and rate limiters can route without inspecting the body
- Roots, sampling, and elicitation are client-to-server capabilities that mature servers handle gracefully when the client supports them
When You Need a Custom MCP Server
The honest answer is most teams should start by installing an existing community server before building one. The public registry (Anthropic, Smithery, mcp.so) lists thousands. You build a custom server when the integration is proprietary, the security posture demands first-party control, or the surface area is non-trivial enough that wrapping a third-party server in your own is more work than starting fresh.
- Internal product APIs that Anthropic, OpenAI, or Cursor users on your team should reach through their agent
- Customer-specific data exposure (a CRM tenant, a workspace, a project) where multi-tenant isolation is mandatory
- Domain logic that should not be re-implemented in every agent: pricing rules, eligibility checks, compliance gates
- Internal knowledge bases (Notion, Confluence, GitHub Wiki, custom CMS) where the existing community server is too generic
- Code execution sandboxes, where the security boundary has to be yours and not a third party
- Anything regulated: PHI, PII, financial records, where you cannot ship data through a vendor server you do not own
- Skip the custom build if a community server already does 90% of the job and you trust the maintainer
Tool Design: The Highest-Leverage Work
A well-designed tool is the difference between an agent that succeeds first try and one that loops, retries, and burns tokens until it gives up. The best MCP server in the world is undone by tool definitions the model cannot reason about. Tool design is the bulk of the senior work in any MCP engagement.
- Verb-first names: search_invoices not invoices, send_email not email_handler. The model picks tools by reading names first
- Descriptions written for the model, not your colleagues: include exactly when to use this tool, when not to, and one or two example arguments
- JSON Schema tight on inputs: enums for fixed sets, format hints for dates and emails, min/max for IDs, descriptions on every field
- Structured output: return JSON, not stringified prose. The model parses far better and downstream tools can chain
- Rich, actionable errors: 404 user not found, try search_users with email beats a stack trace every time
- Idempotency keys on write tools: agents retry, and duplicate sends, duplicate charges, and duplicate tickets are the second worst class of MCP bug
- Keep tool count low: 10-20 tools per server is healthy, 50+ degrades model selection accuracy measurably and is a sign the server is doing too much
- Annotations matter: readOnlyHint, destructiveHint, idempotentHint, openWorldHint - they let the client decide whether to gate behind user approval
Resources, Prompts, and the Parts Most Servers Skip
Most public MCP servers expose tools and stop. Resources and prompts are where senior implementations differentiate. Resources let the client surface relevant context proactively (a file tree, a database catalog, recent tickets) without spending tool-call budget. Prompts let your power users invoke parameterized workflows by name.
- Resources are addressable by URI: design URIs you can pattern match on (mycorp://customer/{id}/invoices) and that clients can browse
- List vs read: clients can list available resources without reading them, so cheap list responses keep the catalog usable
- Subscriptions: resources support change notifications, useful for live document collaboration but rarely worth the complexity in V1
- Prompts are user-invoked workflows: think slash commands, like /create-ticket or /summarize-meeting, that take typed arguments
- Sampling lets a server call back into the client LLM, powerful for embedded reasoning but supported by only a subset of clients - degrade gracefully
- Elicitation lets the server ask the user a follow-up question mid-call, far better UX than failing silently when an argument is missing
Auth, Transport, and Production Deployment
A local stdio server inside Claude Desktop is a 30-line script. A remote multi-tenant server that hundreds of customers connect to is real infrastructure. The transport story matured fast: Streamable HTTP is the new default, OAuth 2.1 with dynamic client registration is the auth story, and the 2026 roadmap is pushing the protocol toward stateless cores that scale on ordinary HTTP infrastructure.
- stdio for local dev tools and CLI integrations - one process per client, simple, no auth needed beyond OS permissions
- Streamable HTTP for everything remote - HTTP POST for requests, optional SSE for streaming, behind any load balancer
- OAuth 2.1 with PKCE: the spec requires it for remote servers, and most clients now do dynamic client registration so users do not paste credentials
- Bearer tokens with audience binding: tokens scoped to your MCP server, validated on every request, rotated like any production secret
- Multi-tenant isolation: each token must resolve to one tenant, and tools must enforce tenant scoping in the data layer, not the LLM layer
- Rate limiting per token and per IP: agents loop, and a misbehaving agent will hammer your server harder than any human user
- Audit logging of every tool call: who, when, what arguments, what result hash - non-negotiable for any regulated deployment
- Health endpoints and graceful shutdown: long-lived SSE streams need explicit drain logic during deploy
TypeScript, Python, and the SDKs Worth Using
Anthropic maintains first-party SDKs in TypeScript, Python, Java, Kotlin, C#, Ruby, Swift, and Rust. TypeScript and Python are by far the most active. I default to TypeScript for servers that share types with a frontend or that consume a TS-native API surface, and Python for servers that need to call into ML pipelines, data tooling, or scientific stacks.
- @modelcontextprotocol/sdk (TypeScript) is the reference implementation, with full support for stdio and Streamable HTTP
- mcp Python package via uv or pip, with FastMCP for a higher-level decorator API similar to FastAPI
- Pydantic for schema definition on the Python side, Zod on the TypeScript side, both compile to JSON Schema cleanly
- For deployment: Cloudflare Workers, Vercel Functions, AWS Lambda all support MCP servers; Cloudflare published the most production-ready remote MCP starter
- Frameworks layered on top: Stainless MCP server generator, Smithery hosting platform, Composio for managed multi-tool servers
- Testing: the Inspector tool from Anthropic is essential for local dev, plus contract tests against a recorded session
Security: The Failure Modes That Cost Real Money
MCP servers expand the attack surface in ways most teams underestimate. The same model that writes your code will, if you let it, ship credentials, exfiltrate data, or make irreversible changes on a prompt-injected resource. Senior MCP work assumes the agent is partially adversarial, because any document it reads might contain instructions trying to subvert it.
- Prompt injection via tool results: never trust strings from any source as anything except untyped data. Sanitize before composing into prompts
- Confused deputy: the server holds privileges the user does not. Every tool must check authorization against the calling user, not the server identity
- Token theft: OAuth tokens stored at rest must be encrypted, refresh tokens rotated, scopes minimized
- Destructive tools behind explicit confirmation: deletes, sends, charges should require user-visible approval, gated by destructiveHint
- Output filtering: tools returning PII, secrets, or internal-only fields need redaction layers, not trust in the model to behave
- Network egress controls: if your server makes outbound HTTP, lock the egress allowlist tighter than you would for a normal service
- Audit-grade logs: per request, per tool, per tenant, plus a separate trail of who reviewed which logs
- Threat model the protocol seams: stdio injection on local servers, header smuggling on remote, downgrade attacks across transport versions
Where MCP Is Going in 2026 and Beyond
The protocol is converging fast. The 2026-07-28 release candidate finalizes a stateless core that lets servers run behind ordinary HTTP infrastructure, with new Mcp-Method and Mcp-Name headers so gateways can route on operation. MCP Apps adds a server-rendered UI extension. The Tasks extension formalizes long-running operations beyond the request-response model. Authorization is moving closer to standard OAuth and OpenID Connect.
For buyers, the takeaway: servers built today should anticipate at least one more spec migration. Production design that ignores transport and auth versioning will need rework within 12 months.
- Stateless core: the 2026 roadmap is removing forced session affinity, so MCP servers scale like REST
- MCP Apps: server-rendered UI components that the client can host inside the agent surface - think rich cards, not just text
- Tasks extension: durable long-running operations with progress, pause, resume - the missing piece for agents that do real work
- OpenID Connect alignment: authorization that fits how enterprises already federate identity
- Registry centralization: official Anthropic registry plus Smithery for hosted discovery and one-click install
- Client capabilities matrix is growing: roots, sampling, elicitation, tools, resources, prompts - a mature server detects and degrades by capability
What an Engagement With Me Looks Like
Most MCP engagements I take are between two and eight weeks. The work splits into discovery (one to three days), design (one to two weeks), build (two to four weeks), and a final hardening pass (security review, threat model, load test, docs). I work either as the senior engineer shipping the server end-to-end, or as the architect and reviewer to an internal team that owns the build.
- Discovery: map the integration surface, identify the tools/resources/prompts taxonomy, write a one-page architecture brief
- Design: draft tool schemas, decide local vs remote, pick transport and auth, write the threat model
- Build: TypeScript or Python implementation, full test suite, Inspector-driven smoke tests, Streamable HTTP endpoint behind your gateway
- Hardening: pen test by an outside party if regulated, load test, audit logging end-to-end, runbook for incidents
- Handoff: docs your engineers can extend from, a contributor guide, and on-call documentation
- Optional follow-on: registry submission, client integration testing across Claude Desktop, Claude Code, Cursor, ChatGPT, Windsurf, internal pilots
FAQ
What is the Model Context Protocol in one sentence?
MCP is an open JSON-RPC protocol from Anthropic that defines how an LLM client (Claude, Cursor, ChatGPT) connects to a server that exposes tools, resources, and prompts, so you build one integration that every compliant client can consume.
Should I build a custom MCP server or use a community one?
Start with the community server if one exists for your target system and you trust the maintainer. Build custom when the API is proprietary, the data is regulated, multi-tenant isolation is mandatory, or your domain logic should not live in a third-party server.
TypeScript or Python for an MCP server?
TypeScript if the server shares types with a frontend or wraps a TS-native API. Python if it calls into ML pipelines, data tooling, or scientific stacks. Both have first-party Anthropic SDKs and both deploy cleanly to Cloudflare Workers, Vercel, or Lambda.
What transport should a new MCP server ship with?
Streamable HTTP for remote, stdio for local dev tools. The legacy SSE transport was deprecated in the November 2025 spec. New servers should not ship SSE; existing servers on SSE need a migration plan within 12 months.
How do I authenticate users to a remote MCP server?
OAuth 2.1 with PKCE is the spec-mandated answer for remote servers. Most modern clients support dynamic client registration so users connect without pasting credentials. Bearer tokens are validated per request, scoped per tenant, and rotated like any production secret.
How many tools should one MCP server expose?
Ten to twenty is healthy. Past fifty, tool selection accuracy degrades measurably across all major models. If you need more, split into multiple servers grouped by domain, or expose a small set of high-level tools that internally route to finer-grained logic.
How do I keep an MCP server from being prompt-injected?
Treat every byte returned by any tool, resource, or external API as untyped data. Never compose untrusted strings into a prompt without sanitization. Gate destructive tools behind explicit user approval. Enforce tenant scoping in the data layer, not the model layer. Audit-log every call.
How long does a custom MCP server engagement take?
A focused server with ten to twenty tools, OAuth 2.1, Streamable HTTP, and proper audit logging takes four to eight weeks end to end. Discovery one to three days, design one to two weeks, build two to four weeks, hardening one week. Bigger surfaces or regulated domains add weeks.
Does an MCP server work with ChatGPT, Cursor, and Claude at the same time?
Yes. That is the entire point of the protocol. One server, multiple clients. The differences come down to which client capabilities (sampling, elicitation, roots, MCP Apps) each consumer supports, and a mature server degrades gracefully when a capability is missing.
Next step
Your situation isn't generic.
Neither should the conversation be.
A short call to map what mcp servers looks like for your team. No obligation, no pitch, just clarity.
Senior architect · 16+ years shipping · Direct, no agency layers