When Anthropic first published the Model Context Protocol spec in late 2024, I read through it in an afternoon and thought: this is either going to be ignored or become the TCP/IP of AI agents. Eighteen months later, 97 million installs have answered that question.

MCP didn’t win because Anthropic marketed it well. It won because it solved a real, painful problem that every team building AI systems was hitting independently.

The Problem Before MCP

If you built an AI assistant or agent before MCP, you know the drill. Every tool integration was bespoke. You wrote a custom function to connect your LLM to your database. Another custom function for your calendar. Another for your file system. Another for your CI/CD pipeline.

Each of these integrations had its own schema, its own error handling, its own authentication story. When you switched LLM providers — or when your provider released a new model — you sometimes had to rewrite everything. The integration layer was fragile, proprietary, and tightly coupled to whichever model you happened to be using.

The deeper problem: there was no standard for how an AI model should discover and invoke external capabilities. Every framework invented its own answer. LangChain had tools. AutoGPT had commands. OpenAI had function calling. These weren’t compatible. A tool written for one ecosystem didn’t work in another.

What MCP Actually Is

MCP is a JSON-RPC-based protocol that standardizes how AI models communicate with external systems. At its core, it defines three things:

Tools — callable functions that an LLM can invoke. A tool has a name, a JSON Schema description of its inputs, and a handler that executes and returns a result.

Resources — read-only data sources that an LLM can access. A resource is identified by a URI and returns structured content.

Prompts — reusable prompt templates that servers can expose, letting the LLM request pre-built context snippets.

Here’s a minimal MCP server in TypeScript that exposes a single tool:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

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

server.setRequestHandler("tools/list", async () => ({
  tools: [{
    name: "get_deploy_status",
    description: "Check deployment status for a given service",
    inputSchema: {
      type: "object",
      properties: {
        service: { type: "string", description: "Service name" }
      },
      required: ["service"]
    }
  }]
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  if (name === "get_deploy_status") {
    const status = await checkDeployment(args.service);
    return { content: [{ type: "text", text: JSON.stringify(status) }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

That server now works with any MCP-compatible client — Claude, GPT-4, Gemini, or any open-source model with MCP support. You wrote the integration once.

Why 97 Million Matters

The number itself is almost beside the point. What matters is the tipping point it signals.

Network effects have kicked in. At 97M installs, there are now thousands of pre-built MCP servers covering everything from GitHub to Postgres to Stripe to Kubernetes. When you start a new project, your first move isn’t “write a custom integration” — it’s “check if an MCP server already exists.” In most cases, it does.

The Linux Foundation adoption changes the governance story. When a protocol moves under open governance, it signals permanence. Enterprise architects who were waiting to see if MCP would outlast Anthropic’s interest now have their answer. This isn’t a vendor feature — it’s shared infrastructure.

Every major AI provider now ships MCP tooling. This means you’re not locked in. The tool you write today for Claude works tomorrow with GPT-5 or Llama 5 or whatever comes next. That’s a fundamentally different investment calculus than 18 months ago.

What I’ve Changed in How I Build

We’ve been running MCP in production for about eight months across three projects. Here’s what’s shifted in our actual development patterns:

Tool-first design

We no longer think “how do I connect the LLM to X?” We think “what tools does this agent need?” Then we define tool contracts before writing a single line of AI logic. The tool schema becomes a specification — it forces you to think clearly about inputs, outputs, and failure modes before the LLM is in the picture at all.

Shared tool libraries

Our team now maintains a private MCP server that exposes internal tools: our deployment pipeline, our incident management system, our cost dashboards. Any agent we build can connect to this server. We wrote these integrations once and they’ve been reused across six different agents.

Composition over monoliths

Because MCP allows an agent to connect to multiple servers simultaneously, we’ve moved away from building large monolithic agents that try to do everything. Instead we compose smaller, focused agents that pull in only the tools they need. This makes testing much cleaner — you can unit test tool servers independently from the agents that use them.

Treating tools as APIs

Tool versioning, backward compatibility, and documentation matter now. An MCP tool that changes its schema breaks agents. We’ve adopted the same practices for tool APIs that we apply to REST APIs: semver, changelogs, deprecation notices.

The Rough Edges (Because It’s Not Perfect)

MCP is genuinely good, but it’s not without friction.

Context window pressure. When an agent has access to many tools, the tool list itself consumes tokens. I’ve seen tool manifests eat 15-20% of available context on complex setups. The upcoming MCP spec work on tool filtering and dynamic discovery will help here.

Authentication is underspecified. The current protocol leaves auth largely to individual server implementations. This means OAuth flows, API key handling, and credential rotation all need to be solved per-server. There’s active work on a standard auth layer, but it’s not there yet.

Streaming is limited. MCP’s current streaming support is basic. For long-running tools that produce incremental output — code execution, web scraping, data processing — you’re often wrapping results in a way that loses the real-time UX benefit.

Error semantics need work. The distinction between “tool failed” and “tool returned bad data” isn’t well-standardized. We’ve had debugging sessions where an agent was silently getting error responses and treating them as success because the response was technically valid JSON.

Where This Goes

The Linux Foundation governance and the 97M install milestone together point to the same future: MCP becomes invisible infrastructure, like HTTP. You won’t think about it — you’ll just use it.

The more interesting question is what gets built on top. With a universal tool layer standardized, the next battleground is orchestration — how agents discover, select, and compose tools dynamically. That’s the problem that frameworks like AWS’s Strands Labs and NVIDIA’s agent tooling are trying to solve now.

For teams building AI systems today, my recommendation is simple: adopt MCP for all new tool integrations, migrate existing ones when you have the bandwidth, and treat your tool servers as first-class production services. The investment pays back quickly in portability and reuse.

The protocol won. Now the interesting work begins.

Export for reading

Comments