Pular para o conteúdo
← Back to Skalablog

Published article

Model Context Protocol: A Practical Developer Guide

AnthropicCursorClaude

The model context protocol (MCP) is an open standard, introduced by Anthropic November 2024, that standardizes how AI applications connect to external systems through servers exposing tools, resources and prompts. This guide explains the architecture, the two transports, and walks through a working server you can run in Cursor.

What Is the Model Context Protocol?

The model context protocol (MCP) is an open standard that standardizes how AI applications supply context to models and let them act on external systems. Anthropic announced it in November 2024 and published the specification and SDKs as open source, so any application or vendor can implement it.

In practice, an MCP server is a small program that a model can talk to. A database server lets the model query Postgres. A Docker server lets it list or restart containers. A filesystem server lets it read your local files. The protocol standardizes the discovery, the call format and the responses, so one host application can work with any compliant server without custom integration code.

How Host, Client and Server Fit Together

The architecture has three roles. The host is the AI application you use, such as Cursor, Claude Desktop, GitHub Copilot or your own product. Inside the host lives the MCP client, which speaks the protocol on the host's behalf. The MCP server is the external process that exposes capabilities, whether local on your machine or remote behind an API.

The flow works like this: the host starts or connects to a server, the client asks it what it can do, and the server returns a list of its capabilities. When you write 'list my running Docker containers', the model sees the available tools from that discovery step, picks one, fills in the arguments, and the client executes the call through the server. The same pattern covers tools that call REST APIs, query databases, or operate Kubernetes clusters.

Tools, Resources and Prompts: Who Controls Each One

The most common mistake is treating MCP as 'tools only'. The protocol defines three primitives, and the difference between them is who decides when each one is invoked. That distinction changes how you design servers and how much of your pipeline they can replace.

Tools perform actions: create a file, call an API, stop a container. The model decides when to call a tool, based on your request and the tool descriptions it discovered. Resources expose data as context, such as files, images or database rows, and the client application decides when to read them, which makes them a lighter alternative to a full RAG pipeline in some workflows. Prompts are reusable, parameterized prompt templates that the user selects manually, useful when you keep retyping the same bug-hunting or code-review instructions.

The three primitives compared:

PrimitivePurposeWho decides when it runsTypical example
ToolsExecute actionsThe model (LLM)Query Postgres, restart a Docker container
ResourcesSupply data as contextThe client applicationRead product prices, load a file
PromptsReusable prompt templatesThe userA saved bug-triage prompt with placeholders

A tool can also read data, but if the point is supplying context, a resource is the right fit because your application, not the model, picks the moment to load it.

stdio vs HTTP Transports for MCP Servers

MCP messages are JSON-RPC, and the protocol defines two transport layers. With stdio, the host launches the server as a local process and exchanges messages over standard input and output. This is the dominant format for servers you install from npm or run with a Docker command, and it is what most examples use.

For remote servers, the original specification used HTTP with Server-Sent Events (SSE), a one-way streaming channel; SSE is unidirectional, unlike WebSockets. In the 2025-03-26 specification revision, the protocol replaced HTTP+SSE with Streamable HTTP, a simpler mechanism on the same HTTP endpoint. Servers built on the older SSE pattern are legacy; current SDKs support Streamable HTTP.

The security burden differs sharply. A stdio server runs on your machine with your permissions, so installing one is like installing any npm package: verify you trust it, because a malicious server can read or delete local files. A remote server faces authentication, authorization, rate limiting and exposure of company data, which is where most real engineering effort goes.

Building a Minimal MCP Server in TypeScript

A server needs only two layers: your existing business code, and a thin MCP wrapper. In the example below, a simple Go REST API holds users in memory on port 8081. The MCP server, written in TypeScript with the official TypeScript SDK, calls that API with Axios and exposes two tools.

The key idea is separation. The getUsers and createUser functions know nothing about MCP; they could serve a plain HTTP handler, a gRPC service or anything else. The MCP layer only registers them and describes their parameters.

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

const API = "[link removed] const server = new McpServer({ name: "users", version: "1.0.0" });

server.tool("get_users", "List all users", {}, async () => { const res = await fetch(${API}/users); return { content: [{ type: "text", text: JSON.stringify(await res.()) }] }; });

server.tool( "create_user", "Create a new user", { user: z.object({ id: z.number(), name: z.string(), email: z.string() }) }, async ({ user }) => { await fetch(${API}/users, { method: "POST", body: JSON.stringify(user) }); return { content: [{ type: "text", text: "User created successfully" }] }; } );

await server.connect(new StdioServerTransport());

Three details matter. The zod schema defines the exact object shape the model must fill in; when you say 'create user ID 2000, name Roberto, email [email]', the model reads that schema and populates each field. The capabilities object on the server instance declares what the server supports (tools, resources, prompts). And the transport at the end is the only line you change to go from stdio to a remote HTTP server.

Registering and Testing MCP Servers in Cursor

Hosts register servers through a JSON config. In Cursor, open the MCP panel in settings and add an entry with a name, a command and its arguments. For the example server, that is node followed by the path to the compiled JavaScript file; for published packages it is npx with the package name, and for containerized servers it is a docker run command that mounts the Docker socket.

Testing is then conversational. Ask 'list all users using the MCP users server' and the model calls the get_users tool with no arguments. Ask to create a user and it calls create_user, filling the schema fields from your sentence. With a Docker MCP server registered, 'list my running containers' triggers a list_containers tool call, and a Postgres server answers questions like 'how many rows are in invoices' by running a generated SELECT count(*) query.

One practical note from the source video, published in April 2025 by the Full Cycle channel: newer models, such as Claude models from Anthropic that implement MCP natively, handle these tool calls well, while some other model providers at that time did not support MCP from the same host, which is worth checking before you pick a model for a tool-heavy workflow.

Where to Find Ready-Made MCP Servers Safely

The official servers repository contains reference servers for filesystem access, Git, GitHub, Google Drive, Postgres, fetch, memory and more, alongside third-party listings. Vendors also publish their own servers for services such as Docker, Cloudflare, Elasticsearch, Grafana and n8n, and community directories like Glama index thousands more by category and language.

Prefer official or vendor-published servers. A community stdio server runs locally with your user's full permissions, so an untrusted one can exfiltrate files or damage your system. The same caution applies to any npm package, but MCP servers feel deceptively like plugins when they are actually arbitrary programs on your machine. Read the repository before installing anything you do not recognize.

FAQ

  • What is the difference between MCP tools and resources? Tools execute actions and the model decides when to call them. Resources supply data as context, and the client application decides when to read them. A tool can read data too, but resources are the intended mechanism for context.
  • Do all MCP servers run locally? No. Local servers communicate over stdio, while remote servers use HTTP. The 2025-03-26 spec revision replaced the original SSE transport with Streamable HTTP for remote connections.
  • Can I write an MCP server in Go or Python? Yes. Official SDKs exist for TypeScript, Python, Go, Java, Kotlin, C# and other languages, and the protocol is language-neutral because messages are JSON-RPC.
  • **Is the model context protocol tied to Claude or Anthropic. Anthropic created the protocol and released it as an open standard in November 2024, and it is now implemented by many independent hosts, editors and model providers.

Turn Your Own Protocol Explainers Into Written Guides

This article exists because a 35-minute video walkthrough of MCP architecture, code and live demos contained knowledge worth reading, not just watching. If you have explained a protocol, a tool or a workflow on YouTube, that same material can become a structured, searchable article.

With Skala Blog, you paste a YouTube URL, the video is transcribed, and you get a drafted article you can review and publish. The chain is simple: video, transcription, article. Your best explanations should not live only inside a play button.

Source video