These are some notes I am taking as I learn about MCP. Much of it I assume will come from the MCP documentation. It's a mix of my own notes as well as copy/pasting from the MCP documentation. It's mostly an exercise to force me to go through the documentation and understand the concepts at a high level. Then the next steps would be building something.
Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs.
The quickstart is broken out in different paths: - for server developers - for client developers - for Claude desktop users
I'm going to start with adding my first MCP server to Claude Desktop. I followed the guide here.
You end up editing the file ~/Library/Application\ Support/Claude/claude_desktop_config.json
Add this content to the file (Make sure to replace username with your computer’s username.) The paths should point to valid directories that you want Claude to be able to access and modify.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/christopher/Desktop",
"/Users/christopher/Downloads"
]
}
}
}
This configuration file tells Claude for Desktop which MCP servers to start up every time you start the application. In this case, we have added one server called “filesystem” that will use the Node npx command to install and run @modelcontextprotocol/server-filesystem. This server, described here, will let you access your file system in Claude for Desktop.
I asked claude to make a text file on my desktop with some ascii art. It figures it can use the file system tools to do this. It asks permission for each step and you have the option to allow always.
I can see how I could achieve the same thing with traditional function/cool calling, but this did feel nice in that it "just worked". Throughout these notes I'm sure Im going to keep coming back to the idea of MCP tools VS Function calling. There is a X post I like here with some nice visuals explaining the differences between the two. I understand that MCP is much more than traditional function calling. I do like the idea of having standardized tools that I can just connect stuff to.
Let's see if I can find another useful MCP server to connect to Claude Desktop.
Another interesting MCP server is the sequential thinking server. I came across it in the MCP docs.
Sequential Thinking MCP Server
After adding it, my claude_desktop_config.json
file looks like this:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/christopher/Desktop",
"/Users/christopher/Downloads"
]
},
"sequential-thinking": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
]
}
}
}
This mcp server allows the LLM to have chain of thought sequential reasoning, I guess.
I wonder how useful this is now that we have really good reasoning models.
I use Cursor on a daily basis but don't use MCPs. Let's see if I can connect the GitHub Remote MCP server to Cursor.
The official GitHub MCP server is here.
They recommend using the remote server in the docs here when connecting to Cursor. While Cursor supports OAuth for some MCP servers, the GitHub server currently requires a Personal Access Token.
The global MCP configuration for Cursor is located at ~/.cursor/mcp.json
.
{
"mcpServers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer YOUR_GITHUB_PAT"
}
}
}
}
If you are running the GitHub MCP server locally in docker you can pass a read only flag. But when running through the remote server, I guess that is not an option. By the way, you can add MCP servers with one click to Cursor here.
I set up a fine grained personal access token and that is how I am controlling the amount of access the MCP server has.
For example, I gave it read/write to one repo for only code, commit statuses, and pull requests. But it cant create repos, delete them, or do all kinds of other things. If you try and use a tool outside of that, it will give you an error. So I highly recommend setting up a fine grained personal access token and use that token for the remote MCP server.
I can ask for example, what were the most recent PR changes:
Previous to testing this MCP server, I always told the Cursor LLM agent to use the GitHub CLI to make pull requests, commits, etc. So at this point, I'm not sure what all the value I would personally get from using the MCP server is (since the GitHub CLI was proving quite useful).
When your host (claude desktop, cursor, vs-code, etc) connects to a MCP server, such as the github MCP server, it instantiates an MCP client object that maintains the connection to the github MCP server. If the host connects to another MCP server, such as the filesystem MCP server, it will instantiate an additional MCP client object. Therefore it ends up maintaining one to one relationships of MCP clients to MCP servers. Here is a diagram taken from the MCP documentation:
MCP consists of two layers
three core primitives that servers can expose
there are methods for discovery (list, get, tools/call, tools/list, etc). Clients use the */list
methods to discover available primitives.
concrete example:
Sampling: Allows servers to request language model completions from the client’s AI application. This is useful when servers authors want access to a language model, but want to stay model independent and not include a language model SDK in their MCP server. They can use the sampling/complete method to request a language model completion from the client’s AI application.
Elicitation: Allows servers to request additional information from users. This is useful when servers authors want to get more information from the user, or ask for confirmation of an action. They can use the elicitation/request method to request additional information from the user.
Logging: Enables servers to send log messages to clients for debugging and monitoring purposes.
MCP supports real time notifications that don't have to be requested. For example the server can send a notification to the client stating that new tools are available etc.
detailed docs here
MCP servers are programs that expose specific capabilities to AI applications through standardized protocol interfaces. Each server provides focused functionality for a particular domain.
Servers provide functionality through three building blocks:
Building Block | Purpose | Who Controls It | Real-World Example |
---|---|---|---|
Tools | For AI actions | Model-controlled | Search flights, send messages, create calendar events |
Resources | For context data | Application-controlled | Documents, calendars, emails, weather data |
Prompts | For interaction templates | User-controlled | "Plan a vacation", "Summarize my meetings", "Draft an email" |
Method | Purpose | Returns |
---|---|---|
tools/list |
Discover available tools | Array of tool definitions with schemas |
tools/call |
Execute a specific tool | Tool execution result |
Example Tool Def:
{
name: "searchFlights",
description: "Search for available flights",
inputSchema: {
type: "object",
properties: {
origin: { type: "string", description: "Departure city" },
destination: { type: "string", description: "Arrival city" },
date: { type: "string", format: "date", description: "Travel date" }
},
required: ["origin", "destination", "date"]
}
}
see here
Resources provide structured access to information that the host application can retrieve and provide to AI models as context.
Resources use URI-based identification, with each resource having a unique URI such as file:///path/to/document.md
Resource Templates enable dynamic resource access through URI templates. A template like travel://activities/{city}/{category} would access filtered activity data by substituting both {city} and {category} parameters
Method | Purpose | Returns |
---|---|---|
resources/list |
List available direct resources | Array of resource descriptors |
resources/templates/list |
Discover resource templates | Array of resource template definitions |
resources/read |
Retrieve resource contents | Resource data with metadata |
resources/subscribe |
Monitor resource changes | Subscription confirmation |
Method | Purpose | Returns |
---|---|---|
prompts/list |
Discover available prompts | Array of prompt descriptors |
prompts/get |
Retrieve prompt details | Full prompt definition with arguments |
see here
MCP clients are instantiated by host applications to communicate with particular MCP servers. The host application, like Claude.ai or an IDE, manages the overall user experience and coordinates multiple clients. Each client handles one direct communication with one server. Understanding the distinction is important: the host is the application users interact with, while clients are the protocol-level components that enable server connections.
In addition to making use of context provided by servers, clients may provide several features to servers. These client features allow server authors to build richer interactions. For example, clients can allow MCP servers to request additional information from the user via elicitations. Clients can offer the following capabilities:
see simple weather bot example here
Can build rich experiences with MCP servers and clients but most of them only use tools right now
I would be interested in the FastMCP python-sdk here
2.0 offers a complete ecosystem including client libraries, authentication systems, deployment tools, integrations with major AI platforms, testing frameworks, and production-ready infrastructure patterns.
1.0 is in the official MCP SDK
from mcp.server.fastmcp import FastMCP
from fastmcp import FastMCP