myibrahim.cloud

Vibe Coding · Editors & Agents

Agents and MCP: the long-running coding session

When 'one chat, ten edits' becomes 'one prompt, a whole feature.' What MCP actually does, and why it's the protocol I expected without realizing I expected it.

For a year I treated AI coding tools like very smart autocomplete. I'd type a comment, accept a suggestion, type more, accept more. The unit was the line.

Then Claude Code arrived and the unit became the task. "Add a settings page that respects the user's existing theme tokens, with form validation." I'd come back fifteen minutes later to a working PR.

Then MCP arrived and the unit started becoming the project.

What MCP actually is#

MCP — the Model Context Protocol — is a small, open standard for how an AI assistant talks to tools. The simplest framing: it's USB for LLMs. Plug in a "filesystem" server, the model can read/write files. Plug in a "Postgres" server, it can query your DB. Plug in a custom one for your internal API, it can use that too.

What's nice about it being a protocol and not "a SDK from a vendor": you write the server once, every MCP-aware client (Claude Code, Cursor, Continue, Zed, etc.) can use it. The integration matrix collapses from N×M to N+M.

What an MCP server looks like#

The mental model: an MCP server is a tiny RPC service that exposes a list of "tools" and "resources." A tool is something the model can call. A resource is something the model can read.

A trivial server in TypeScript (using the official @modelcontextprotocol/sdk):

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

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

server.setRequestHandler("tools/list", () => ({
  tools: [{
    name: "list_customers",
    description: "List customers, optionally filtered by status.",
    inputSchema: {
      type: "object",
      properties: { status: { type: "string", enum: ["active", "trial", "churned"] } },
    },
  }],
}));

server.setRequestHandler("tools/call", async (req) => {
  if (req.params.name !== "list_customers") throw new Error("unknown");
  const customers = await myInternalApi.listCustomers(req.params.arguments);
  return { content: [{ type: "text", text: JSON.stringify(customers, null, 2) }] };
});

await server.connect(new StdioServerTransport());

That's a working MCP server. Drop a config in .claude/mcp.json pointing at it and Claude Code can list customers from inside any conversation.

What this changes about coding sessions#

The shift isn't subtle. Before MCP, getting the model to "look up the customer with id 42 and check whether their last invoice failed" meant either pasting the data manually or asking the model to write a script that hits your API. With an MCP server: it just calls the tool.

The downstream effect on agent loops is large. Anthropic's Claude Code, with a few good MCP servers (filesystem, github, postgres, your-app-specific-tools), runs a recognizably different workflow:

  1. You describe the goal: "Find the bug that's making invoice #1234 show duplicate line items, and write a fix + a test."
  2. The agent reads the relevant code (filesystem MCP).
  3. It checks recent git history for similar issues (git MCP).
  4. It queries the production-replica DB to see invoice #1234's structure (postgres MCP).
  5. It writes the fix, runs the test suite, iterates if needed.
  6. You come back to a PR.

The model isn't more capable than before. It just has the side-channels it needed.

The MCP servers I keep installed#

After a few months of trying lots of them, this is the steady-state set:

Server What it gives When I actually use it
filesystem read/write files every session
github issues, PRs, releases reading bug reports, opening PRs
postgres query a DB wiring up new features against production schema
brave-search web search researching APIs / latest docs
memory persistent notes across sessions stays surprisingly useful
my-company-api our internal CRUD started low, ended high

The "my-company-api" one is the highest-leverage. It's three days of work to expose your most-used internal endpoints over MCP, and it changes what the agent can do for you.

Anthropic: Building agents with MCP

Failure modes#

It's not all warm fuzzies.

Tool spam. When 20 tools are available, the model picks the wrong one or uses several in series before giving up. Curate tools per project. The right tool for this repo is rarely "all 47 I have installed."

Side-effect mistakes. Tools that mutate state (write files, create issues, run migrations) can do damage if the model misreads context. Configure dangerous tools to require explicit confirmation. The default for db.execute should be "ask first."

Rate limits. The model can hammer your APIs with 80 requests in a 30-second flurry. Add per-tool rate limiting in the server itself.

Prompt injection through tool returns. A tool that returns user-controlled text can inject instructions into the conversation. Sanitize tool outputs the way you sanitize user input.

The economics#

Long agent sessions are expensive. A single Claude Code task that touches 30 files, runs 50 tool calls, and writes 2000 lines of diff easily uses 500K tokens — $7.50 at Sonnet rates. Most of that is the input being re-paid each turn.

Two mitigations:

  1. Prompt caching. Anthropic caches stable preludes; agent loops with caching cost ~30% of un-cached.
  2. Smaller models for tool decisions. A two-tier setup where Haiku decides which tool to call and Sonnet writes code drops cost ~40%.

For team-scale use this isn't a deal-breaker, but it's worth doing the math.

Where this is going#

A guess: the unit-of-work for engineering keeps drifting up. Today an agent ships a feature in a session. Tomorrow it ships a feature across PR review feedback. Eventually it's "I want this product to do X" and the agent fans out across repos, services, and test environments.

That trajectory is only navigable because of MCP. Without a stable protocol for tool access, every step would require a new bespoke integration. The boring infrastructure piece — a JSON-RPC convention — is the thing that lets the foreground move.

If you've been waiting for the right time to build an MCP server for your stack, it's now. The protocol is stable, the clients all support it, and the leverage is real.

Further reading#

  • ai
  • tooling
  • mcp
  • claude
  • agents
Need this built? I build ai product or mvp projects for clients worldwide. Tell me about yours.