Skip to content
MCP Guide

Model Context Protocol: Architecture, Wire Flow, and Migration Plan

MCP is not just another integration spec. It is an operating model for tool connectivity across model providers.

Technical Guide16 min readUpdated Apr 2026
TL;DR
  • -MCP solves integration sprawl more than model quality. It standardizes tool connectivity across model vendors.
  • -Host-client-server boundaries matter because they define ownership of retries, auth, and safety controls.
  • -JSON-RPC correctness is table stakes. Production readiness depends on governance, observability, and rollback behavior.
  • -A phased migration from function calling to MCP reduces breakage and makes connector ownership explicit.
Connectivity

MCP gives one protocol for many models and many tools.

Architecture

Host, client, and server boundaries define operational responsibilities.

Governance

Production MCP still needs deterministic policy controls outside the model runtime.

Common failure pattern

Teams migrate syntax but not ownership. They replace function schemas with MCP servers, then discover nobody owns connector versioning, auth scope drift, or rollback playbooks.

The integration problem

Without MCP, each model provider needs its own tool contract. Every connector multiplies implementation and maintenance cost.

This creates two costs: duplicated code and inconsistent behavior under failure. Retry semantics differ. Validation quality differs. Audit detail differs.

Architecture debt warning

MCP adoption without contract ownership is just new plumbing on old governance debt.

What top sources cover vs miss

SourceStrong coverageMissing piece
MCP Architecture DocsStrong conceptual model for hosts, clients, and servers.No production decision framework for choosing MCP vs simpler patterns.
MCP Server ConceptsClear explanation of tools, resources, prompts, and capability boundaries.No operational ownership map for auth, retries, and safety responsibilities.
Build an MCP Server TutorialGreat first implementation walkthrough and working local setup path.No migration blueprint for teams already running provider-specific tool calling.

MCP architecture in practice

LayerPrimary responsibilityCommon mistake
HostOwns user session, model runtime, and client lifecycle.Treating host as a thin UI and pushing operational logic elsewhere.
MCP ClientMaintains stateful protocol session and transport behavior.Ignoring backpressure, timeout, and reconnect semantics.
MCP ServerExposes tools/resources/prompts with stable contract surface.Mixing tool contract changes with backend experiments without versioning.
Policy/Governance LayerEvaluates tool calls before execution and enforces approvals.Implementing governance in prompt text instead of architecture.

JSON-RPC wire flow

Message flow quality is where integration bugs surface first. Start with predictable initialize and capability negotiation behavior.

initialize-request.json
JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "clientInfo": { "name": "my-host", "version": "1.2.0" },
    "capabilities": {
      "tools": {},
      "resources": {},
      "prompts": {}
    }
  }
}
tools-call.json
JSON
{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "query_database",
    "arguments": {
      "query": "SELECT count(*) AS active_users FROM users WHERE active = true",
      "limit": 1
    }
  }
}
minimal-mcp-server.ts
TypeScript
import { Server } from "@modelcontextprotocol/sdk/server";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";

const server = new Server({
  name: "analytics-server",
  version: "1.0.0",
});

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "query_database",
      description: "Execute read-only SQL against analytics DB",
      inputSchema: {
        type: "object",
        properties: {
          query: { type: "string" },
          limit: { type: "number", default: 100 },
        },
        required: ["query"],
      },
    },
  ],
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  if (name !== "query_database") {
    throw new Error("Unknown tool");
  }

  const rows = await analyticsDb.query(args.query, args.limit);
  return { content: [{ type: "text", text: JSON.stringify(rows) }] };
});

await server.connect(new StdioServerTransport());

MCP vs alternatives

DimensionMCPProvider Function CallingDirect API SDK
Provider lock-inLowHighMedium
Tool discoveryDynamic capability listingStatic schema in app codeManual docs and custom adapters
Migration costMedium upfront, lower long-termLow upfront, higher at scaleVariable and often repetitive
Cross-model reuseHighLowHigh but non-standard for LLM tools
Governance insertion pointNatural pre-dispatch boundaryCustom per providerGateway-centric, not model-aware

Migration plan

Do not migrate everything in one cut. Phase by risk and ownership.

PhasePrimary taskExit criteria
Phase 1: InventoryList existing function calls, owners, auth scopes, and failure modes.Every call path has an owner and risk classification.
Phase 2: WrapExpose high-value read-only calls via MCP servers first.Read traffic runs through MCP with no regression in latency SLO.
Phase 3: GovernInsert policy checks, approvals, and output safety before write rollout.No unapproved high-risk write can execute.
Phase 4: CutoverDecommission duplicated provider-specific function schemas.Single MCP contract is source of truth per tool domain.

Limitations and tradeoffs

Higher upfront architecture effort

MCP standardization pays off later, but onboarding is not free.

Contract governance becomes mandatory

Tool schemas now behave like public APIs and need version discipline.

Operational maturity requirement

You need observability and policy controls or failures stay invisible for too long.

Frequently Asked Questions

What problem does MCP solve first?
Connector sprawl. It gives teams one standard contract for tool access across multiple model vendors.
Should I replace all function calling immediately?
No. Start with read-only paths, stabilize, then migrate high-impact write flows with governance in place.
Is MCP enough for production safety by itself?
No. You still need policy enforcement, approvals, output safety, and audit-grade observability.
When is MCP overkill?
Very small single-model applications with one or two simple tools can stay on native function calling for a while.
What breaks most migrations?
Unclear ownership of tool contracts and silent schema drift without versioning or compatibility checks.
Next step

Pick one connector this week and migrate it end to end through MCP with contract ownership, policy checks, and rollback notes. Treat that migration as your template for the rest.