Skip to main content

Model Context Protocol (MCP) Quickstart

Written by on .

anthropic
mpc
typescript

  1. The Protocol
    1. Server
      1. Client
        1. Transport
          1. Host
          2. Open-Source Components
            1. SDKs
              1. Servers
                1. Community Servers
              2. Early Adoption and Use Cases
                1. Sourcegraph Cody
                  1. Zed Editor
                  2. Testing MCP using Claude Desktop
                    1. Alternatives
                      1. What's Next?
                        1. Early Thoughts

                          When large language models first appeared, users had to copy and paste code into a text interface to interact with them. This quickly proved insufficient, leading to custom integrations for better context loading. However, these were fragmented and required individual development. The Model Context Protocol (MCP) solves this by offering a universal protocol for efficient AI interaction with both local and remote resources.

                          The Protocol

                          High-level overview of the protocol:

                          • Hosts are LLM applications (like Claude Desktop or IDEs) that initiate connections
                          • Clients maintain 1:1 connections with servers, inside the host application
                          • Servers provide context, tools, and prompts to clients

                          Server

                          If you are already familiar with tool use, then MCP will feel familiar.

                          Let's take a quick look at one of the example server implementatations: the Brave Search server.

                          Internally, the server implementation defines tools it has access to, and communicates their availability to the client.

                          server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [WEB_SEARCH_TOOL, LOCAL_SEARCH_TOOL], }));

                          Here, WEB_SEARCH_TOOL is an object that describes the available tool, e.g.

                          { name: "brave_web_search", description: "Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " + "Use this for broad information gathering, recent events, or when you need diverse web sources. " + "Supports pagination, content filtering, and freshness controls. " + "Maximum 20 results per request, with offset for pagination. ", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query (max 400 chars, 50 words)" }, count: { type: "number", description: "Number of results (1-20, default 10)", default: 10 }, offset: { type: "number", description: "Pagination offset (max 9, default 0)", default: 0 }, }, required: ["query"], }, }

                          As far as I can tell, this is identical to the Anthropic Claude Tool Use API or OpenAI Function Calling.

                          It then exposes a request handler.

                          server.setRequestHandler(CallToolRequestSchema, async (request) => { // ... });

                          The request handler matches the inbound request to a tool, and then calls whatever function is associated with that tool.

                          case "brave_web_search": { if (!isBraveWebSearchArgs(args)) { throw new Error("Invalid arguments for brave_web_search"); } const { query, count = 10 } = args; const results = await performWebSearch(query, count); return { content: [{ type: "text", text: results }], isError: false, }; }

                          Each MPC server has a URI (e.g., tool://brave_web_search/brave_web_search), runs as a separate process, and communicates with clients via a JSON-RPC. Example, you can launch the Brave Search server via the following command:

                          You can obtain a free Brave Search API key by signing up for a Brave account.

                          $ export BRAVE_API_KEY=your-api-key $ npx -y @modelcontextprotocol/server-brave-search

                          Client

                          The client needs to know what server it can connect to.

                          const transport = new StdioClientTransport({ command: "tool://brave_web_search/brave_web_search" });

                          Then, it needs to connect to the server:

                          await client.connect(transport);

                          The purpose of the connection is to negotiate capabilities through the protocol. During the connection:

                          • Client sends initialize request with protocol version and capabilities
                          • Server responds with its protocol version and capabilities
                          • Client sends initialized notification as acknowledgment
                          • Normal message exchange begins

                          Finally, the client can send messages to the server.

                          const resources = await client.request( { method: "brave_web_search" }, BraveWebSearchResultSchema );

                          There are 4 types of messsages defined by the protocol:

                          • Request: Messages that expect a response
                          • Notification: Messages that do not expect a response
                          • Result: Successful responses to requests
                          • Error: Failure responses to requests

                          Transport

                          MCP supports multiple transport mechanisms:

                          • Stdio transport
                            • Uses standard input/output for communication
                            • Ideal for local processes
                          • HTTP with SSE transport
                            • Uses Server-Sent Events for server-to-client messages
                            • HTTP POST for client-to-server messages

                          All transports use JSON-RPC 2.0 to exchange messages.

                          Host

                          The host is the application that initiates connections to servers.

                          The host is responsible for discovering the capabilities of the servers, and planning how to utilize them to solve end user problems.

                          This part of the protocol is pretty vague. However, as far as I understand, the expectation is that the host implements a custom routing logic. You can see an example of such implementation in my earlier article Implementing Tool Functionality in Conversational AI.

                          Open-Source Components

                          SDKs

                          Servers

                          • Filesystem - Secure file operations with configurable access controls
                          • GitHub - Repository management, file operations, and GitHub API integration
                          • Google Drive - File access and search capabilities for Google Drive
                          • PostgreSQL - Read-only database access with schema inspection
                          • Slack - Channel management and messaging capabilities
                          • Memory - Knowledge graph-based persistent memory system
                          • Puppeteer - Browser automation and web scraping
                          • Brave Search - Web and local search using Brave's Search API
                          • Google Maps - Location services, directions, and place details
                          • Fetch - Web content fetching and conversion for efficient LLM usage

                          Community Servers

                          • MCP YouTube – Uses yt-dlp to download subtitles from YouTube.

                          Early Adoption and Use Cases

                          Several organizations and tools have already adopted MCP:

                          Sourcegraph Cody

                          From the Cody blog post:

                          Here's an example of Cody connecting to a Postgres database to write a Prisma query after looking at the database schema:

                          Cody MCP Postgres
                          Cody connecting to a Postgres database to write a Prisma query after looking at the database schema

                          Zed Editor

                          From the Zed Editor blog post:

                          Here's an example of using a Zed extension for PostgreSQL to instantly inform the model about our entire database schema, so when we ask it to write a query for us, it knows exactly what tables and columns exist, and what their types are.

                          Zed Integration
                          Using the Postgres Context Server to have the Assistant write a schema-aware query.

                          Sourcegraph's blog post also has an example of building Linear integration with TypeScript and MCP.

                          Testing MCP using Claude Desktop

                          Claude Desktop app is the easiest way to test MCP.

                          Open your Claude Desktop App configuration at ~/Library/Application Support/Claude/claude_desktop_config.json in a text editor.

                          ~/Library/Application Support/Claude/claude_desktop_config.json likely will not exist on your machine. You need to create it.

                          ~/Library/Application Support/Claude/config.json is a different, unrelated file. Do not edit it.

                          Add this configuration:

                          { "mcpServers": { "brave_search": { "command": "npx", "args": ["@modelcontextprotocol/server-brave-search"], "env": { "BRAVE_API_KEY": "your-api-key" } } } }

                          This tells Claude Desktop:

                          • There's an MCP server named brave_search
                          • Launch it using npx @modelcontextprotocol/server-brave-search

                          Save the file, and restart Claude Desktop.

                          Now, you can ask Claude Desktop to "search the web for" something.

                          For example, try asking Claude Desktop to "search the web for glama.ai".

                          You will be at first prompted to allow Claude Desktop to use MCP:

                          permission-dialog

                          Permission Dialog
                          Asking Claude Desktop to use MCP

                          Click "Allow for This Chat" to allow Claude Desktop to use MCP.

                          After this, you will see Claude Desktop using the Brave Search MCP server to search the web for "glama.ai" and get the results.

                          Alternatives

                          There are a few open-source projects that come to mind that solve the same problem as MCP.

                          • Web Applets – An open spec & SDK for creating apps that agents can use.

                          What's Next?

                          I don't expect MCP to gain widespread adoption until it has HTTP transport support.

                          However, I do imagine a future where general purpose LLM clients like Glama or Claude Desktop will have a marketplace of MCP servers, and users will be able to plug and play these services into their workflows.

                          Early Thoughts

                          While MCP is positioned as an open standard, its current implementation appears tailored to Anthropic's Claude. Additionally,

                          • There is no clear documentation on compatibility with other LLM providers like AWS Bedrock or Google Vertex AI.
                          • The setup process for MCP servers in the Claude Desktop app is currently manual and lacks user-friendly tooling.
                          • You have to give Claude Desktop permission to use MCP every time you re-open the app.

                          Therefore, we have ways to go before MCP can become a standard.

                          Meanwhile, my money is on the Computer Use becoming the standard for AI-powered automation, including everything that MCP is trying to solve.