MCP - Notes

Introduction

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.

  • MCP Hosts: programs like Claude Desktop, Cursor IDE, AI tools, etc
  • MCP Clients: Protocol clients that maintain 1:1 connection with the servers
    • the client lives within the host
  • MCP servers: lightweight programs that each expose specific capabilities through the MCP standard
  • Local Data Sources: your computers files, databases, and services that MCP servers can securely access
  • Remote Services: external systems available over the internet (e.g. through APIs) that MCP servers can connect to

Quickstart

The quickstart is broken out in different paths: - for server developers - for client developers - for Claude desktop users

Claude Desktop Users

Filesystem MCP Server

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.

Specification

  • much of the above was found from browsing through the MCP documentation link
  • But there is also a specification that has a lot of details too
  • go read th specification for nitty gritty details

Sequential Thinking MCP Server

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.

Cursor IDE as a Host

Remote GitHub MCP Server

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).

Architecture Overview

Scope

Concepts

  • each client has a dedicated 1:1 connection with a server
  • host: The AI application that managed and coordinates one or multiple MCP clients
  • client: maintains the the connection to MCP server and obtains context from the server for the MCP host to use
  • server: program that provides context to MCP clients

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 Server refers to the program that serves the context data, regardless of where it runs
    • MCP servers can be local or remote
      • i.e. the filesystem MCP server is local and uses STDIO transport.
      • a remote server such as the remote version of the github MCP server is remote and uses HTTP transport.

Layers

MCP consists of two layers

  • Data Layer: Defines the JSON-RPC based protocol for client-server communication, including lifecycle management, core primitives, such as tools, resources, and prompts, and notifications. (inner layer)
  • Transport Layer: Defines the communication mechanisms and channels that enable data exchange between clients and servers, including transport-specific connection establishment, message framing, and authorization. (outer layer)

Data Layer

  • lifecycle management: connection initialization, capability negotiation, connection termination between client and server
  • server features: tools for AI actions, resources for context data, prompts for interaction templates from to the client
  • client features: Enables servers to ask the client to sample from the host LLM, elicit input from the user, and log messages to the client
  • utility features: Supports additional capabilities like notifications for real-time updates and progress tracking for long-running operations

Transport Layer

  • manages communication channels and authentication between client and server
    • Stdio transport: Uses standard input/output streams for direct process communication between local processes on the same machine, providing optimal performance with no network overhead.
    • Streamable HTTP transport: Uses HTTP POST for client-to-server messages with optional Server-Sent Events for streaming capabilities. This transport enables remote server communication and supports standard HTTP authentication methods including bearer tokens, API keys, and custom headers. MCP recommends using OAuth to obtain authentication tokens.

Data Layer Protocol

Primitives

  • most important concept within MCP

Server Primitives

  • three core primitives that servers can expose

    • Tools: Executable functions that AI applications can invoke to perform actions (e.g., file operations, API calls, database queries)
    • Resources: Data sources that provide contextual information to AI applications (e.g., file contents, database records, API responses)
    • Prompts: Reusable templates that help structure interactions with language models (e.g., system prompts, few-shot examples)
  • there are methods for discovery (list, get, tools/call, tools/list, etc). Clients use the */list methods to discover available primitives.

  • concrete example:

    • MCP Server that provides context about a database
    • tools for querying the DB
    • resource that explains the schema of the DB
    • prompt that includes few-shot examples for interacting with the tools

Client Primitives

  • 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.

Example

  • see the detailed example to see a step-by-step walkthrough of an MCP client-server interaction, focusing on the data layer protocol. We’ll demonstrate the lifecycle sequence, tool operations, and notifications using JSON-RPC 2.0 messages.

Server Concepts

  • 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.

Core Building Blocks

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"

Tools

  • Most importantly, tool execution requires explicit user approval, ensuring users maintain control over actions taken by a model.
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"]
  }
}
  • Each tool execution requires explicit user approval, ensuring full control over actions taken.
    • I guess the MCP spec can't enforce what the host app logic does but it should be like this (desired)
  • Tools are model-controlled, meaning AI models can discover and invoke them automatically. However, MCP emphasizes human oversight through several mechanisms. Applications should clearly display available tools in the UI and provide visual indicators when tools are being considered or used. Before any tool execution, users must be presented with clear approval dialogs that explain exactly what the tool will do.

Resources (Context Data)

  • 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

Prompts - Interaction Templates

  • see here
  • Prompts are structured templates that define expected inputs and interaction patterns. They are user-controlled, requiring explicit invocation rather than automatic triggering. Prompts can be context-aware, referencing available resources and tools to create comprehensive workflows. Like resources, prompts support parameter completion to help users discover valid argument values.
Method Purpose Returns
prompts/list Discover available prompts Array of prompt descriptors
prompts/get Retrieve prompt details Full prompt definition with arguments

Client Concepts

  • 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:

Sampling

  • here
  • Sampling allows servers to request language model completions through the client, enabling agentic behaviors while maintaining security and user control.
  • Sampling enables servers to perform AI-dependent tasks without directly integrating with or paying for AI models. Instead, servers can request that the client—which already has AI model access—handle these tasks on their behalf. This approach puts the client in complete control of user permissions and security measures. Because sampling requests occur within the context of other operations—like a tool analyzing data—and are processed as separate model calls, they maintain clear boundaries between different contexts, allowing for more efficient use of the context window.
  • consider air line booking example - user asks find best flight and tools are used to fetch 47 flight options - then the server can request AI assistance (via sampling) to analyze the flight data to pick best option. The client asks the user "allow sampling request?"
  • see user interaction notes here

Roots

  • Roots define filesystem boundaries for server operations, allowing clients to specify which directories servers should focus on.
  • see here

Elicitation

  • Elicitation enables servers to request specific information from users during interactions, creating more dynamic and responsive workflows.
  • Elicitation provides a structured way for servers to gather necessary information on demand. Instead of requiring all information up front or failing when data is missing, servers can pause their operations to request specific inputs from users. This creates more flexible interactions where servers adapt to user needs rather than following rigid patterns.
  • see here

Example Clients

here

Building a Server Example

  • see simple weather bot example here

  • Can build rich experiences with MCP servers and clients but most of them only use tools right now

FastMCP

  • I would be interested in the FastMCP python-sdk here

    • While 1.0 provided server-building capabilities (and is now part of the official MCP SDK)
  • 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
  • Third‑party alternative: If you install fastmcp and do
from fastmcp import FastMCP

Links