# Modal Context Protocol

## What is MCP?

MCP is an open protocol that standardizes how applications provide context to LLMs. We can think of it like a USB-C port for AI applications. **MCP provides a standardized way to connect AI models to different data sources and tools**.

## Architecture of MCP

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1754025545017/802fedbd-a423-472d-bee2-69c517f5c54d.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1754025579652/718ba4db-c43c-4fea-8111-e48ee3ce24b7.png align="center")

### MCP Hosts and Clients

The MCP host is the program that’s going to access the MCP servers\*\*. The host uses an LLM, which will be able to call tools that are defined in the MCP servers.\*\*

**Example**: Claude Desktop, Cursor, etc

**On a host, we are going to run multiple clients - each client will maintain a relationship to a single MCP server**. When the host starts up, each client will connect to an MCP server.

### MCP Server

The MCP Server is the server that’s going to be running the tools that the host wants to call.

### The Transport and Protocol

The client connects to its server using a transport. It is responsible for senindg messages between the client and server

```typescript
// JSON-RPC 2.0

type Request = {
  jsonrpc: "2.0";
  id: number | string;
  // a method that the server should perform
  method: string;
  // params passes to that method
  params?: object;
};

type Response = {
  jsonrpc: "2.0";
  id: number | string;
  result?: object;
  error?: {
    code: number;
    message: string;
    data?: unknown;
  };
};
```

**Example** - Github MCP

Client asks for a list of tools

```typescript
// Client sends...
{
  "jsonrpc": "2.0",
  "id": 1,
  👉 "method": "tools/list"
}
```

The server sends back

```typescript
{
  "jsonrpc": "2.0",
  "id": 1,
  "tools": [
    {
     👉  "name": "createGitHubIssue",
      "description": "Create a GitHub issue",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": { "type": "string" },
          "body": { "type": "string" },
          "labels": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      }
    }
  ]
}
```

The client calls a tool

```typescript
{
  "jsonrpc": "2.0",
  "id": 2,
  👉 "method": "tools/call",
  "params": {
    👉 "name": "createGitHubIssue",
    👉 "arguments": {
      "title": "My Issue",
      "body": "This is the body of my issue",
      "labels": ["bug"]
    }
  }
}
```

The server sends back

```typescript
{
  "jsonrpc": "2.0",
  "id": 2,
  "content": [
    {
      "type": "text",
      "text": "Issue 143 created successfully!"
    }
  ],
  "isError": false
}
```

## Simple MCP Server

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Init a server
const server = new McpServer({
  name: "Weather Service",
  version: "1.0.0",
});

// Add a tool - it's just a function
server.tool(
  "getWeather",
  {
    city: z.string(),
  },
  async ({ city }) => {
    return {
      content: [
        {
          type: "text",
          text: `The weather in ${city} is sunny!`,
        },
      ],
    };
  },
);

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

// Then we can easily connect to Claude code
claude mcp add "weather-example" npx tsx "/path-to-the-file.ts"
```

## MCP Prompts

**We can use MCP as a prompt directory** - a collection of prompts that users can pull to achieve a goal quickly. Think of it as a prompt template.

```typescript
const server = new McpServer({
  name: "Prompt Directory",
  version: "1.0.0",
});

const getPrompt = (path: string) =>
  `
Clean up the transcript in the file at ${path}
Do not edit the words,
only the formatting and any incorrect transcriptions.
`.trim();

// 👉 use server.prompt instead of server.tool
server.prompt(
  `cleanTranscription`,
  `Clean up a transcript file`,
  { path: z.string() },
  async ({ path }) => {
    return {
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: getPrompt(path),
          },
        },
      ],
    };
  },
);
```

## References

1. [https://modelcontextprotocol.io/docs/getting-started/intro](https://modelcontextprotocol.io/docs/getting-started/intro)
