#
tokens: 142016/50000 1/22 files (page 2/2)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 2 of 2. Use http://codebase.md/exa-labs/exa-mcp-server?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .gitignore
├── .npmignore
├── Dockerfile
├── LICENSE
├── llm_mcp_docs.txt
├── mcp_publishing_steps_on_mcpregistry.md
├── package-lock.json
├── package.json
├── README.md
├── server.json
├── smithery-example.json
├── smithery.yaml
├── src
│   ├── index.ts
│   ├── tools
│   │   ├── companyResearch.ts
│   │   ├── config.ts
│   │   ├── crawling.ts
│   │   ├── deepResearchCheck.ts
│   │   ├── deepResearchStart.ts
│   │   ├── exaCode.ts
│   │   ├── linkedInSearch.ts
│   │   └── webSearch.ts
│   ├── types.ts
│   └── utils
│       └── logger.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/llm_mcp_docs.txt:
--------------------------------------------------------------------------------

```
    1 | # Example Clients
    2 | Source: https://modelcontextprotocol.io/clients
    3 | 
    4 | A list of applications that support MCP integrations
    5 | 
    6 | This page provides an overview of applications that support the Model Context Protocol (MCP). Each client may support different MCP features, allowing for varying levels of integration with MCP servers.
    7 | 
    8 | ## Feature support matrix
    9 | 
   10 | <div id="feature-support-matrix-wrapper">
   11 |   {/* prettier-ignore-start */}
   12 | 
   13 |   | Client                                           | [Resources] | [Prompts] | [Tools] | [Discovery] | [Sampling] | [Roots] | Notes                                                                                           |
   14 |   | ------------------------------------------------ | ----------- | --------- | ------- | ----------- | ---------- | ------- | ----------------------------------------------------------------------------------------------- |
   15 |   | [5ire][5ire]                                     | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   16 |   | [AgentAI][AgentAI]                               | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Agent Library written in Rust with tools support                                                |
   17 |   | [AgenticFlow][AgenticFlow]                       | ✅           | ✅         | ✅       | ✅           | ❌          | ❌       | Supports tools, prompts, and resources for no-code AI agents and multi-agent workflows.         |
   18 |   | [Amazon Q CLI][Amazon Q CLI]                     | ❌           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports prompts and tools.                                                                     |
   19 |   | [Apify MCP Tester][Apify MCP Tester]             | ❌           | ❌         | ✅       | ✅           | ❌          | ❌       | Supports remote MCP servers and tool discovery.                                                 |
   20 |   | [Augment Code][AugmentCode]                      | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools in local and remote agents.                                                      |
   21 |   | [BeeAI Framework][BeeAI Framework]               | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools in agentic workflows.                                                            |
   22 |   | [BoltAI][BoltAI]                                 | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   23 |   | [Claude.ai][Claude.ai]                           | ✅           | ✅         | ✅       | ❌           | ❌          | ❌       | Supports tools, prompts, and resources for remote MCP servers.                                  |
   24 |   | [Claude Code][Claude Code]                       | ❌           | ✅         | ✅       | ❌           | ❌          | ❌       | Supports prompts and tools                                                                      |
   25 |   | [Claude Desktop App][Claude Desktop]             | ✅           | ✅         | ✅       | ❌           | ❌          | ❌       | Supports tools, prompts, and resources for local and remote MCP servers.                        |
   26 |   | [Cline][Cline]                                   | ✅           | ❌         | ✅       | ✅           | ❌          | ❌       | Supports tools and resources.                                                                   |
   27 |   | [Continue][Continue]                             | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports tools, prompts, and resources.                                                         |
   28 |   | [Copilot-MCP][CopilotMCP]                        | ✅           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools and resources.                                                                   |
   29 |   | [Cursor][Cursor]                                 | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools.                                                                                 |
   30 |   | [Daydreams Agents][Daydreams]                    | ✅           | ✅         | ✅       | ❌           | ❌          | ❌       | Support for drop in Servers to Daydreams agents                                                 |
   31 |   | [Emacs Mcp][Mcp.el]                              | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools in Emacs.                                                                        |
   32 |   | [fast-agent][fast-agent]                         | ✅           | ✅         | ✅       | ✅           | ✅          | ✅       | Full multimodal MCP support, with end-to-end tests                                              |
   33 |   | [FLUJO][FLUJO]                                   | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Support for resources, Prompts and Roots are coming soon                                        |
   34 |   | [Genkit][Genkit]                                 | ⚠️          | ✅         | ✅       | ❓           | ❌          | ❌       | Supports resource list and lookup through tools.                                                |
   35 |   | [Glama][Glama]                                   | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   36 |   | [GenAIScript][GenAIScript]                       | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   37 |   | [Goose][Goose]                                   | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   38 |   | [gptme][gptme]                                   | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   39 |   | [HyperAgent][HyperAgent]                         | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools.                                                                                 |
   40 |   | [JetBrains AI Assistant][JetBrains AI Assistant] | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools for all JetBrains IDEs.                                                          |
   41 |   | [Klavis AI Slack/Discord/Web][Klavis AI]         | ✅           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools and resources.                                                                   |
   42 |   | [LibreChat][LibreChat]                           | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools for Agents                                                                       |
   43 |   | [Lutra][Lutra]                                   | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports any MCP server for reusable playbook creation.                                         |
   44 |   | [mcp-agent][mcp-agent]                           | ✅           | ✅         | ✅       | ❓           | ⚠️         | ✅       | Supports tools, prompts, resources, roots, server connection management, and agent workflows.   |
   45 |   | [mcp-use][mcp-use]                               | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Support tools, resources, stdio & http connection, local llms-agents.                           |
   46 |   | [MCPHub][MCPHub]                                 | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports tools, resources, and prompts in Neovim                                                |
   47 |   | [MCPOmni-Connect][MCPOmni-Connect]               | ✅           | ✅         | ✅       | ❓           | ✅          | ❌       | Supports tools with agentic mode, ReAct, and orchestrator capabilities.                         |
   48 |   | [Memex][Memex]                                   | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Support tools. Also support *building and testing* MCP server, all-in-one desktop app.          |
   49 |   | [Microsoft Copilot Studio]                       | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools                                                                                  |
   50 |   | [MindPal][MindPal]                               | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools for no-code AI agents and multi-agent workflows.                                 |
   51 |   | [MooPoint][MooPoint]                             | ❌           | ❌         | ✅       | ❓           | ✅          | ❌       | Web-Hosted client with tool calling support                                                     |
   52 |   | [Msty Studio][Msty Studio]                       | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools                                                                                  |
   53 |   | [NVIDIA Agent Intelligence toolkit][AIQ toolkit] | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools in agentic workflows.                                                            |
   54 |   | [OpenSumi][OpenSumi]                             | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools in OpenSumi                                                                      |
   55 |   | [oterm][oterm]                                   | ❌           | ✅         | ✅       | ❓           | ✅          | ❌       | Supports tools, prompts and sampling for Ollama.                                                |
   56 |   | [Postman][postman]                               | ✅           | ✅         | ✅       | ❓           | ❌          | ❌       | Supports tools, resources, prompts, and sampling                                                |
   57 |   | [Roo Code][Roo Code]                             | ✅           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools and resources.                                                                   |
   58 |   | [Slack MCP Client][Slack MCP Client]             | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools and multiple servers.                                                            |
   59 |   | [Sourcegraph Cody][Cody]                         | ✅           | ❌         | ❌       | ❓           | ❌          | ❌       | Supports resources through OpenCTX                                                              |
   60 |   | [SpinAI][SpinAI]                                 | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools for Typescript AI Agents                                                         |
   61 |   | [Superinterface][Superinterface]                 | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools                                                                                  |
   62 |   | [Superjoin][Superjoin]                           | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools and multiple servers.                                                            |
   63 |   | [TheiaAI/TheiaIDE][TheiaAI/TheiaIDE]             | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools for Agents in Theia AI and the AI-powered Theia IDE                              |
   64 |   | [Tome][Tome]                                     | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools, manages MCP servers.                                                            |
   65 |   | [TypingMind App][TypingMind App]                 | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools at app-level (appear as plugins) or when assigned to Agents                      |
   66 |   | [VS Code GitHub Copilot][VS Code]                | ✅           | ✅         | ✅       | ✅           | ✅          | ✅       | Supports dynamic tool/roots discovery, secure secret configuration, and explicit tool prompting |
   67 |   | [Warp][Warp]                                     | ✅           | ❌         | ✅       | ✅           | ❌          | ❌       | Supports tools, resources, and most of the discovery criteria                                   |
   68 |   | [WhatsMCP][WhatsMCP]                             | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools for Remote MCP Servers in WhatsApp                                               |
   69 |   | [Windsurf Editor][Windsurf]                      | ❌           | ❌         | ✅       | ✅           | ❌          | ❌       | Supports tools with AI Flow for collaborative development.                                      |
   70 |   | [Witsy][Witsy]                                   | ❌           | ❌         | ✅       | ❓           | ❌          | ❌       | Supports tools in Witsy.                                                                        |
   71 |   | [Zed][Zed]                                       | ❌           | ✅         | ❌       | ❌           | ❌          | ❌       | Prompts appear as slash commands                                                                |
   72 |   | [Zencoder][Zencoder]                             | ❌           | ❌         | ✅       | ❌           | ❌          | ❌       | Supports tools                                                                                  |
   73 | 
   74 |   {/* prettier-ignore-end */}
   75 | 
   76 |   [Resources]: /docs/concepts/resources
   77 | 
   78 |   [Prompts]: /docs/concepts/prompts
   79 | 
   80 |   [Tools]: /docs/concepts/tools
   81 | 
   82 |   [Discovery]: /docs/concepts/tools#tool-discovery-and-updates
   83 | 
   84 |   [Sampling]: /docs/concepts/sampling
   85 | 
   86 |   [Roots]: /docs/concepts/roots
   87 | 
   88 |   [5ire]: https://github.com/nanbingxyz/5ire
   89 | 
   90 |   [AgentAI]: https://github.com/AdamStrojek/rust-agentai
   91 | 
   92 |   [AgenticFlow]: https://agenticflow.ai/mcp
   93 | 
   94 |   [AIQ toolkit]: https://github.com/NVIDIA/AIQToolkit
   95 | 
   96 |   [Amazon Q CLI]: https://github.com/aws/amazon-q-developer-cli
   97 | 
   98 |   [Apify MCP Tester]: https://apify.com/jiri.spilka/tester-mcp-client
   99 | 
  100 |   [AugmentCode]: https://augmentcode.com
  101 | 
  102 |   [BeeAI Framework]: https://i-am-bee.github.io/beeai-framework
  103 | 
  104 |   [BoltAI]: https://boltai.com
  105 | 
  106 |   [Claude.ai]: https://claude.ai
  107 | 
  108 |   [Claude Code]: https://claude.ai/code
  109 | 
  110 |   [Claude Desktop]: https://claude.ai/download
  111 | 
  112 |   [Cline]: https://github.com/cline/cline
  113 | 
  114 |   [Continue]: https://github.com/continuedev/continue
  115 | 
  116 |   [CopilotMCP]: https://github.com/VikashLoomba/copilot-mcp
  117 | 
  118 |   [Cursor]: https://cursor.com
  119 | 
  120 |   [Daydreams]: https://github.com/daydreamsai/daydreams
  121 | 
  122 |   [Klavis AI]: https://www.klavis.ai/
  123 | 
  124 |   [Mcp.el]: https://github.com/lizqwerscott/mcp.el
  125 | 
  126 |   [fast-agent]: https://github.com/evalstate/fast-agent
  127 | 
  128 |   [FLUJO]: https://github.com/mario-andreschak/flujo
  129 | 
  130 |   [Glama]: https://glama.ai/chat
  131 | 
  132 |   [Genkit]: https://github.com/firebase/genkit
  133 | 
  134 |   [GenAIScript]: https://microsoft.github.io/genaiscript/reference/scripts/mcp-tools/
  135 | 
  136 |   [Goose]: https://block.github.io/goose/docs/goose-architecture/#interoperability-with-extensions
  137 | 
  138 |   [JetBrains AI Assistant]: https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant
  139 | 
  140 |   [LibreChat]: https://github.com/danny-avila/LibreChat
  141 | 
  142 |   [Lutra]: https://lutra.ai
  143 | 
  144 |   [mcp-agent]: https://github.com/lastmile-ai/mcp-agent
  145 | 
  146 |   [mcp-use]: https://github.com/pietrozullo/mcp-use
  147 | 
  148 |   [MCPHub]: https://github.com/ravitemer/mcphub.nvim
  149 | 
  150 |   [MCPOmni-Connect]: https://github.com/Abiorh001/mcp_omni_connect
  151 | 
  152 |   [Memex]: https://memex.tech/
  153 | 
  154 |   [Microsoft Copilot Studio]: https://learn.microsoft.com/en-us/microsoft-copilot-studio/agent-extend-action-mcp
  155 | 
  156 |   [MindPal]: https://mindpal.io
  157 | 
  158 |   [MooPoint]: https://moopoint.io
  159 | 
  160 |   [Msty Studio]: https://msty.ai
  161 | 
  162 |   [OpenSumi]: https://github.com/opensumi/core
  163 | 
  164 |   [oterm]: https://github.com/ggozad/oterm
  165 | 
  166 |   [Postman]: https://postman.com/downloads
  167 | 
  168 |   [Roo Code]: https://roocode.com
  169 | 
  170 |   [Slack MCP Client]: https://github.com/tuannvm/slack-mcp-client
  171 | 
  172 |   [Cody]: https://sourcegraph.com/cody
  173 | 
  174 |   [SpinAI]: https://spinai.dev
  175 | 
  176 |   [Superinterface]: https://superinterface.ai
  177 | 
  178 |   [Superjoin]: https://superjoin.ai
  179 | 
  180 |   [TheiaAI/TheiaIDE]: https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/
  181 | 
  182 |   [Tome]: https://github.com/runebookai/tome
  183 | 
  184 |   [TypingMind App]: https://www.typingmind.com
  185 | 
  186 |   [VS Code]: https://code.visualstudio.com/
  187 | 
  188 |   [Windsurf]: https://codeium.com/windsurf
  189 | 
  190 |   [gptme]: https://github.com/gptme/gptme
  191 | 
  192 |   [Warp]: https://www.warp.dev/
  193 | 
  194 |   [WhatsMCP]: https://wassist.app/mcp/
  195 | 
  196 |   [Witsy]: https://github.com/nbonamy/witsy
  197 | 
  198 |   [Zed]: https://zed.dev
  199 | 
  200 |   [Zencoder]: https://zencoder.ai
  201 | 
  202 |   [HyperAgent]: https://github.com/hyperbrowserai/HyperAgent
  203 | </div>
  204 | 
  205 | ## Client details
  206 | 
  207 | ### 5ire
  208 | 
  209 | [5ire](https://github.com/nanbingxyz/5ire) is an open source cross-platform desktop AI assistant that supports tools through MCP servers.
  210 | 
  211 | **Key features:**
  212 | 
  213 | * Built-in MCP servers can be quickly enabled and disabled.
  214 | * Users can add more servers by modifying the configuration file.
  215 | * It is open-source and user-friendly, suitable for beginners.
  216 | * Future support for MCP will be continuously improved.
  217 | 
  218 | ### AgentAI
  219 | 
  220 | [AgentAI](https://github.com/AdamStrojek/rust-agentai) is a Rust library designed to simplify the creation of AI agents. The library includes seamless integration with MCP Servers.
  221 | 
  222 | [Example of MCP Server integration](https://github.com/AdamStrojek/rust-agentai/blob/master/examples/tools_mcp.rs)
  223 | 
  224 | **Key features:**
  225 | 
  226 | * Multi-LLM – We support most LLM APIs (OpenAI, Anthropic, Gemini, Ollama, and all OpenAI API Compatible).
  227 | * Built-in support for MCP Servers.
  228 | * Create agentic flows in a type- and memory-safe language like Rust.
  229 | 
  230 | ### AgenticFlow
  231 | 
  232 | [AgenticFlow](https://agenticflow.ai/) is a no-code AI platform that helps you build agents that handle sales, marketing, and creative tasks around the clock. Connect 2,500+ APIs and 10,000+ tools securely via MCP.
  233 | 
  234 | **Key features:**
  235 | 
  236 | * No-code AI agent creation and workflow building.
  237 | * Access a vast library of 10,000+ tools and 2,500+ APIs through MCP.
  238 | * Simple 3-step process to connect MCP servers.
  239 | * Securely manage connections and revoke access anytime.
  240 | 
  241 | **Learn more:**
  242 | 
  243 | * [AgenticFlow MCP Integration](https://agenticflow.ai/mcp)
  244 | 
  245 | ### Amazon Q CLI
  246 | 
  247 | [Amazon Q CLI](https://github.com/aws/amazon-q-developer-cli) is an open-source, agentic coding assistant for terminals.
  248 | 
  249 | **Key features:**
  250 | 
  251 | * Full support for MCP servers.
  252 | * Edit prompts using your preferred text editor.
  253 | * Access saved prompts instantly with `@`.
  254 | * Control and organize AWS resources directly from your terminal.
  255 | * Tools, profiles, context management, auto-compact, and so much more!
  256 | 
  257 | **Get Started**
  258 | 
  259 | ```bash
  260 | brew install amazon-q
  261 | ```
  262 | 
  263 | ### Apify MCP Tester
  264 | 
  265 | [Apify MCP Tester](https://github.com/apify/tester-mcp-client) is an open-source client that connects to any MCP server using Server-Sent Events (SSE).
  266 | It is a standalone Apify Actor designed for testing MCP servers over SSE, with support for Authorization headers.
  267 | It uses plain JavaScript (old-school style) and is hosted on Apify, allowing you to run it without any setup.
  268 | 
  269 | **Key features:**
  270 | 
  271 | * Connects to any MCP server via SSE.
  272 | * Works with the [Apify MCP Server](https://apify.com/apify/actors-mcp-server) to interact with one or more Apify [Actors](https://apify.com/store).
  273 | * Dynamically utilizes tools based on context and user queries (if supported by the server).
  274 | 
  275 | ### Augment Code
  276 | 
  277 | [Augment Code](https://augmentcode.com) is an AI-powered coding platform for VS Code and JetBrains with autonomous agents, chat, and completions. Both local and remote agents are backed by full codebase awareness and native support for MCP, enabling enhanced context through external sources and tools.
  278 | 
  279 | **Key features:**
  280 | 
  281 | * Full MCP support in local and remote agents.
  282 | * Add additional context through MCP servers.
  283 | * Automate your development workflows with MCP tools.
  284 | * Works in VS Code and JetBrains IDEs.
  285 | 
  286 | ### BeeAI Framework
  287 | 
  288 | [BeeAI Framework](https://i-am-bee.github.io/beeai-framework) is an open-source framework for building, deploying, and serving powerful agentic workflows at scale. The framework includes the **MCP Tool**, a native feature that simplifies the integration of MCP servers into agentic workflows.
  289 | 
  290 | **Key features:**
  291 | 
  292 | * Seamlessly incorporate MCP tools into agentic workflows.
  293 | * Quickly instantiate framework-native tools from connected MCP client(s).
  294 | * Planned future support for agentic MCP capabilities.
  295 | 
  296 | **Learn more:**
  297 | 
  298 | * [Example of using MCP tools in agentic workflow](https://i-am-bee.github.io/beeai-framework/#/typescript/tools?id=using-the-mcptool-class)
  299 | 
  300 | ### BoltAI
  301 | 
  302 | [BoltAI](https://boltai.com) is a native, all-in-one AI chat client with MCP support. BoltAI supports multiple AI providers (OpenAI, Anthropic, Google AI...), including local AI models (via Ollama, LM Studio or LMX)
  303 | 
  304 | **Key features:**
  305 | 
  306 | * MCP Tool integrations: once configured, user can enable individual MCP server in each chat
  307 | * MCP quick setup: import configuration from Claude Desktop app or Cursor editor
  308 | * Invoke MCP tools inside any app with AI Command feature
  309 | * Integrate with remote MCP servers in the mobile app
  310 | 
  311 | **Learn more:**
  312 | 
  313 | * [BoltAI docs](https://boltai.com/docs/plugins/mcp-servers)
  314 | * [BoltAI website](https://boltai.com)
  315 | 
  316 | ### Claude Code
  317 | 
  318 | Claude Code is an interactive agentic coding tool from Anthropic that helps you code faster through natural language commands. It supports MCP integration for prompts and tools, and also functions as an MCP server to integrate with other clients.
  319 | 
  320 | **Key features:**
  321 | 
  322 | * Tool and prompt support for MCP servers
  323 | * Offers its own tools through an MCP server for integrating with other MCP clients
  324 | 
  325 | ### Claude.ai
  326 | 
  327 | [Claude.ai](https://claude.ai) is Anthropic's web-based AI assistant that provides MCP support for remote servers.
  328 | 
  329 | **Key features:**
  330 | 
  331 | * Support for remote MCP servers via integrations UI in settings
  332 | * Access to tools, prompts, and resources from configured MCP servers
  333 | * Seamless integration with Claude's conversational interface
  334 | * Enterprise-grade security and compliance features
  335 | 
  336 | ### Claude Desktop App
  337 | 
  338 | The Claude desktop application provides comprehensive support for MCP, enabling deep integration with local tools and data sources.
  339 | 
  340 | **Key features:**
  341 | 
  342 | * Full support for resources, allowing attachment of local files and data
  343 | * Support for prompt templates
  344 | * Tool integration for executing commands and scripts
  345 | * Local server connections for enhanced privacy and security
  346 | 
  347 | ### Cline
  348 | 
  349 | [Cline](https://github.com/cline/cline) is an autonomous coding agent in VS Code that edits files, runs commands, uses a browser, and more–with your permission at each step.
  350 | 
  351 | **Key features:**
  352 | 
  353 | * Create and add tools through natural language (e.g. "add a tool that searches the web")
  354 | * Share custom MCP servers Cline creates with others via the `~/Documents/Cline/MCP` directory
  355 | * Displays configured MCP servers along with their tools, resources, and any error logs
  356 | 
  357 | ### Continue
  358 | 
  359 | [Continue](https://github.com/continuedev/continue) is an open-source AI code assistant, with built-in support for all MCP features.
  360 | 
  361 | **Key features:**
  362 | 
  363 | * Type "@" to mention MCP resources
  364 | * Prompt templates surface as slash commands
  365 | * Use both built-in and MCP tools directly in chat
  366 | * Supports VS Code and JetBrains IDEs, with any LLM
  367 | 
  368 | ### Copilot-MCP
  369 | 
  370 | [Copilot-MCP](https://github.com/VikashLoomba/copilot-mcp) enables AI coding assistance via MCP.
  371 | 
  372 | **Key features:**
  373 | 
  374 | * Support for MCP tools and resources
  375 | * Integration with development workflows
  376 | * Extensible AI capabilities
  377 | 
  378 | ### Cursor
  379 | 
  380 | [Cursor](https://docs.cursor.com/advanced/model-context-protocol) is an AI code editor.
  381 | 
  382 | **Key features:**
  383 | 
  384 | * Support for MCP tools in Cursor Composer
  385 | * Support for both STDIO and SSE
  386 | 
  387 | ### Daydreams
  388 | 
  389 | [Daydreams](https://github.com/daydreamsai/daydreams) is a generative agent framework for executing anything onchain
  390 | 
  391 | **Key features:**
  392 | 
  393 | * Supports MCP Servers in config
  394 | * Exposes MCP Client
  395 | 
  396 | ### Emacs Mcp
  397 | 
  398 | [Emacs Mcp](https://github.com/lizqwerscott/mcp.el) is an Emacs client designed to interface with MCP servers, enabling seamless connections and interactions. It provides MCP tool invocation support for AI plugins like [gptel](https://github.com/karthink/gptel) and [llm](https://github.com/ahyatt/llm), adhering to Emacs' standard tool invocation format. This integration enhances the functionality of AI tools within the Emacs ecosystem.
  399 | 
  400 | **Key features:**
  401 | 
  402 | * Provides MCP tool support for Emacs.
  403 | 
  404 | ### fast-agent
  405 | 
  406 | [fast-agent](https://github.com/evalstate/fast-agent) is a Python Agent framework, with simple declarative support for creating Agents and Workflows, with full multi-modal support for Anthropic and OpenAI models.
  407 | 
  408 | **Key features:**
  409 | 
  410 | * PDF and Image support, based on MCP Native types
  411 | * Interactive front-end to develop and diagnose Agent applications, including passthrough and playback simulators
  412 | * Built in support for "Building Effective Agents" workflows.
  413 | * Deploy Agents as MCP Servers
  414 | 
  415 | ### FLUJO
  416 | 
  417 | Think n8n + ChatGPT. FLUJO is an desktop application that integrates with MCP to provide a workflow-builder interface for AI interactions. Built with Next.js and React, it supports both online and offline (ollama) models, it manages API Keys and environment variables centrally and can install MCP Servers from GitHub. FLUJO has an ChatCompletions endpoint and flows can be executed from other AI applications like Cline, Roo or Claude.
  418 | 
  419 | **Key features:**
  420 | 
  421 | * Environment & API Key Management
  422 | * Model Management
  423 | * MCP Server Integration
  424 | * Workflow Orchestration
  425 | * Chat Interface
  426 | 
  427 | ### Genkit
  428 | 
  429 | [Genkit](https://github.com/firebase/genkit) is a cross-language SDK for building and integrating GenAI features into applications. The [genkitx-mcp](https://github.com/firebase/genkit/tree/main/js/plugins/mcp) plugin enables consuming MCP servers as a client or creating MCP servers from Genkit tools and prompts.
  430 | 
  431 | **Key features:**
  432 | 
  433 | * Client support for tools and prompts (resources partially supported)
  434 | * Rich discovery with support in Genkit's Dev UI playground
  435 | * Seamless interoperability with Genkit's existing tools and prompts
  436 | * Works across a wide variety of GenAI models from top providers
  437 | 
  438 | ### Glama
  439 | 
  440 | [Glama](https://glama.ai/chat) is a comprehensive AI workspace and integration platform that offers a unified interface to leading LLM providers, including OpenAI, Anthropic, and others. It supports the Model Context Protocol (MCP) ecosystem, enabling developers and enterprises to easily discover, build, and manage MCP servers.
  441 | 
  442 | **Key features:**
  443 | 
  444 | * Integrated [MCP Server Directory](https://glama.ai/mcp/servers)
  445 | * Integrated [MCP Tool Directory](https://glama.ai/mcp/tools)
  446 | * Host MCP servers and access them via the Chat or SSE endpoints
  447 |   – Ability to chat with multiple LLMs and MCP servers at once
  448 | * Upload and analyze local files and data
  449 | * Full-text search across all your chats and data
  450 | 
  451 | ### GenAIScript
  452 | 
  453 | Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft.github.io/genaiscript/) (in JavaScript). Orchestrate LLMs, tools, and data in JavaScript.
  454 | 
  455 | **Key features:**
  456 | 
  457 | * JavaScript toolbox to work with prompts
  458 | * Abstraction to make it easy and productive
  459 | * Seamless Visual Studio Code integration
  460 | 
  461 | ### Goose
  462 | 
  463 | [Goose](https://github.com/block/goose) is an open source AI agent that supercharges your software development by automating coding tasks.
  464 | 
  465 | **Key features:**
  466 | 
  467 | * Expose MCP functionality to Goose through tools.
  468 | * MCPs can be installed directly via the [extensions directory](https://block.github.io/goose/v1/extensions/), CLI, or UI.
  469 | * Goose allows you to extend its functionality by [building your own MCP servers](https://block.github.io/goose/docs/tutorials/custom-extensions).
  470 | * Includes built-in tools for development, web scraping, automation, memory, and integrations with JetBrains and Google Drive.
  471 | 
  472 | ### gptme
  473 | 
  474 | [gptme](https://github.com/gptme/gptme) is a open-source terminal-based personal AI assistant/agent, designed to assist with programming tasks and general knowledge work.
  475 | 
  476 | **Key features:**
  477 | 
  478 | * CLI-first design with a focus on simplicity and ease of use
  479 | * Rich set of built-in tools for shell commands, Python execution, file operations, and web browsing
  480 | * Local-first approach with support for multiple LLM providers
  481 | * Open-source, built to be extensible and easy to modify
  482 | 
  483 | ### HyperAgent
  484 | 
  485 | [HyperAgent](https://github.com/hyperbrowserai/HyperAgent) is Playwright supercharged with AI. With HyperAgent, you no longer need brittle scripts, just powerful natural language commands. Using MCP servers, you can extend the capability of HyperAgent, without having to write any code.
  486 | 
  487 | **Key features:**
  488 | 
  489 | * AI Commands: Simple APIs like page.ai(), page.extract() and executeTask() for any AI automation
  490 | * Fallback to Regular Playwright: Use regular Playwright when AI isn't needed
  491 | * Stealth Mode – Avoid detection with built-in anti-bot patches
  492 | * Cloud Ready – Instantly scale to hundreds of sessions via [Hyperbrowser](https://www.hyperbrowser.ai/)
  493 | * MCP Client – Connect to tools like Composio for full workflows (e.g. writing web data to Google Sheets)
  494 | 
  495 | ### JetBrains AI Assistant
  496 | 
  497 | [JetBrains AI Assistant](https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant) plugin provides AI-powered features for software development available in all JetBrains IDEs.
  498 | 
  499 | **Key features:**
  500 | 
  501 | * Unlimited code completion powered by Mellum, JetBrains’ proprietary AI model.
  502 | * Context-aware AI chat that understands your code and helps you in real time.
  503 | * Access to top-tier models from OpenAI, Anthropic, and Google.
  504 | * Offline mode with connected local LLMs via Ollama or LM Studio.
  505 | * Deep integration into IDE workflows, including code suggestions in the editor, VCS assistance, runtime error explanation, and more.
  506 | 
  507 | ### Klavis AI Slack/Discord/Web
  508 | 
  509 | [Klavis AI](https://www.klavis.ai/) is an Open-Source Infra to Use, Build & Scale MCPs with ease.
  510 | 
  511 | **Key features:**
  512 | 
  513 | * Slack/Discord/Web MCP clients for using MCPs directly
  514 | * Simple web UI dashboard for easy MCP configuration
  515 | * Direct OAuth integration with Slack & Discord Clients and MCP Servers for secure user authentication
  516 | * SSE transport support
  517 | * Open-source infrastructure ([GitHub repository](https://github.com/Klavis-AI/klavis))
  518 | 
  519 | **Learn more:**
  520 | 
  521 | * [Demo video showing MCP usage in Slack/Discord](https://youtu.be/9-QQAhrQWw8)
  522 | 
  523 | ### LibreChat
  524 | 
  525 | [LibreChat](https://github.com/danny-avila/LibreChat) is an open-source, customizable AI chat UI that supports multiple AI providers, now including MCP integration.
  526 | 
  527 | **Key features:**
  528 | 
  529 | * Extend current tool ecosystem, including [Code Interpreter](https://www.librechat.ai/docs/features/code_interpreter) and Image generation tools, through MCP servers
  530 | * Add tools to customizable [Agents](https://www.librechat.ai/docs/features/agents), using a variety of LLMs from top providers
  531 | * Open-source and self-hostable, with secure multi-user support
  532 | * Future roadmap includes expanded MCP feature support
  533 | 
  534 | ### Lutra
  535 | 
  536 | [Lutra](https://lutra.ai) is an AI agent that transforms conversations into actionable, automated workflows.
  537 | 
  538 | **Key features:**
  539 | 
  540 | * Easy MCP Integration: Connecting Lutra to MCP servers is as simple as providing the server URL; Lutra handles the rest behind the scenes.
  541 | * Chat to Take Action: Lutra understands your conversational context and goals, automatically integrating with your existing apps to perform tasks.
  542 | * Reusable Playbooks: After completing a task, save the steps as reusable, automated workflows—simplifying repeatable processes and reducing manual effort.
  543 | * Shareable Automations: Easily share your saved playbooks with teammates to standardize best practices and accelerate collaborative workflows.
  544 | 
  545 | **Learn more:**
  546 | 
  547 | * [Lutra AI agent explained](https://www.youtube.com/watch?v=W5ZpN0cMY70)
  548 | 
  549 | ### mcp-agent
  550 | 
  551 | [mcp-agent] is a simple, composable framework to build agents using Model Context Protocol.
  552 | 
  553 | **Key features:**
  554 | 
  555 | * Automatic connection management of MCP servers.
  556 | * Expose tools from multiple servers to an LLM.
  557 | * Implements every pattern defined in [Building Effective Agents](https://www.anthropic.com/research/building-effective-agents).
  558 | * Supports workflow pause/resume signals, such as waiting for human feedback.
  559 | 
  560 | ### mcp-use
  561 | 
  562 | [mcp-use] is an open source python library to very easily connect any LLM to any MCP server both locally and remotely.
  563 | 
  564 | **Key features:**
  565 | 
  566 | * Very simple interface to connect any LLM to any MCP.
  567 | * Support the creation of custom agents, workflows.
  568 | * Supports connection to multiple MCP servers simultaneously.
  569 | * Supports all langchain supported models, also locally.
  570 | * Offers efficient tool orchestration and search functionalities.
  571 | 
  572 | ### MCPHub
  573 | 
  574 | [MCPHub] is a powerful Neovim plugin that integrates MCP (Model Context Protocol) servers into your workflow.
  575 | 
  576 | **Key features:**
  577 | 
  578 | * Install, configure and manage MCP servers with an intuitive UI.
  579 | * Built-in Neovim MCP server with support for file operations (read, write, search, replace), command execution, terminal integration, LSP integration, buffers, and diagnostics.
  580 | * Create Lua-based MCP servers directly in Neovim.
  581 | * Inegrates with popular Neovim chat plugins Avante.nvim and CodeCompanion.nvim
  582 | 
  583 | ### MCPOmni-Connect
  584 | 
  585 | [MCPOmni-Connect](https://github.com/Abiorh001/mcp_omni_connect) is a versatile command-line interface (CLI) client designed to connect to various Model Context Protocol (MCP) servers using both stdio and SSE transport.
  586 | 
  587 | **Key features:**
  588 | 
  589 | * Support for resources, prompts, tools, and sampling
  590 | * Agentic mode with ReAct and orchestrator capabilities
  591 | * Seamless integration with OpenAI models and other LLMs
  592 | * Dynamic tool and resource management across multiple servers
  593 | * Support for both stdio and SSE transport protocols
  594 | * Comprehensive tool orchestration and resource analysis capabilities
  595 | 
  596 | ### Memex
  597 | 
  598 | [Memex](https://memex.tech/) is the first MCP client and MCP server builder - all-in-one desktop app. Unlike traditional MCP clients that only consume existing servers, Memex can create custom MCP servers from natural language prompts, immediately integrate them into its toolkit, and use them to solve problems—all within a single conversation.
  599 | 
  600 | **Key features:**
  601 | 
  602 | * **Prompt-to-MCP Server**: Generate fully functional MCP servers from natural language descriptions
  603 | * **Self-Testing & Debugging**: Autonomously test, debug, and improve created MCP servers
  604 | * **Universal MCP Client**: Works with any MCP server through intuitive, natural language integration
  605 | * **Curated MCP Directory**: Access to tested, one-click installable MCP servers (Neon, Netlify, GitHub, Context7, and more)
  606 | * **Multi-Server Orchestration**: Leverage multiple MCP servers simultaneously for complex workflows
  607 | 
  608 | **Learn more:**
  609 | 
  610 | * [Memex Launch 2: MCP Teams and Agent API](https://memex.tech/blog/memex-launch-2-mcp-teams-and-agent-api-private-preview-125f)
  611 | 
  612 | ### Microsoft Copilot Studio
  613 | 
  614 | [Microsoft Copilot Studio] is a robust SaaS platform designed for building custom AI-driven applications and intelligent agents, empowering developers to create, deploy, and manage sophisticated AI solutions.
  615 | 
  616 | **Key features:**
  617 | 
  618 | * Support for MCP tools
  619 | * Extend Copilot Studio agents with MCP servers
  620 | * Leveraging Microsoft unified, governed, and secure API management solutions
  621 | 
  622 | ### MindPal
  623 | 
  624 | [MindPal](https://mindpal.io) is a no-code platform for building and running AI agents and multi-agent workflows for business processes.
  625 | 
  626 | **Key features:**
  627 | 
  628 | * Build custom AI agents with no-code
  629 | * Connect any SSE MCP server to extend agent tools
  630 | * Create multi-agent workflows for complex business processes
  631 | * User-friendly for both technical and non-technical professionals
  632 | * Ongoing development with continuous improvement of MCP support
  633 | 
  634 | **Learn more:**
  635 | 
  636 | * [MindPal MCP Documentation](https://docs.mindpal.io/agent/mcp)
  637 | 
  638 | ### MooPoint
  639 | 
  640 | [MooPoint](https://moopoint.io)
  641 | 
  642 | MooPoint is a web-based AI chat platform built for developers and advanced users, letting you interact with multiple large language models (LLMs) through a single, unified interface. Connect your own API keys (OpenAI, Anthropic, and more) and securely manage custom MCP server integrations.
  643 | 
  644 | **Key features:**
  645 | 
  646 | * Accessible from any PC or smartphone—no installation required
  647 | * Choose your preferred LLM provider
  648 | * Supports `SSE`, `Streamable HTTP`, `npx`, and `uvx` MCP servers
  649 | * OAuth and sampling support
  650 | * New features added daily
  651 | 
  652 | ### Msty Studio
  653 | 
  654 | [Msty Studio](https://msty.ai) is a privacy-first AI productivity platform that seamlessly integrates local and online language models (LLMs) into customizable workflows. Designed for both technical and non-technical users, Msty Studio offers a suite of tools to enhance AI interactions, automate tasks, and maintain full control over data and model behavior.
  655 | 
  656 | **Key features:**
  657 | 
  658 | * **Toolbox & Toolsets**: Connect AI models to local tools and scripts using MCP-compliant configurations. Group tools into Toolsets to enable dynamic, multi-step workflows within conversations.
  659 | * **Turnstiles**: Create automated, multi-step AI interactions, allowing for complex data processing and decision-making flows.
  660 | * **Real-Time Data Integration**: Enhance AI responses with up-to-date information by integrating real-time web search capabilities.
  661 | * **Split Chats & Branching**: Engage in parallel conversations with multiple models simultaneously, enabling comparative analysis and diverse perspectives.
  662 | 
  663 | **Learn more:**
  664 | 
  665 | * [Msty Studio Documentation](https://docs.msty.studio/features/toolbox/tools)
  666 | 
  667 | ### NVIDIA Agent Intelligence (AIQ) toolkit
  668 | 
  669 | [NVIDIA Agent Intelligence (AIQ) toolkit](https://github.com/NVIDIA/AIQToolkit) is a flexible, lightweight, and unifying library that allows you to easily connect existing enterprise agents to data sources and tools across any framework.
  670 | 
  671 | **Key features:**
  672 | 
  673 | * Acts as an MCP **client** to consume remote tools
  674 | * Acts as an MCP **server** to expose tools
  675 | * Framework agnostic and compatible with LangChain, CrewAI, Semantic Kernel, and custom agents
  676 | * Includes built-in observability and evaluation tools
  677 | 
  678 | **Learn more:**
  679 | 
  680 | * [AIQ toolkit GitHub repository](https://github.com/NVIDIA/AIQToolkit)
  681 | * [AIQ toolkit MCP documentation](https://docs.nvidia.com/aiqtoolkit/latest/workflows/mcp/index.html)
  682 | 
  683 | ### OpenSumi
  684 | 
  685 | [OpenSumi](https://github.com/opensumi/core) is a framework helps you quickly build AI Native IDE products.
  686 | 
  687 | **Key features:**
  688 | 
  689 | * Supports MCP tools in OpenSumi
  690 | * Supports built-in IDE MCP servers and custom MCP servers
  691 | 
  692 | ### oterm
  693 | 
  694 | [oterm] is a terminal client for Ollama allowing users to create chats/agents.
  695 | 
  696 | **Key features:**
  697 | 
  698 | * Support for multiple fully customizable chat sessions with Ollama connected with tools.
  699 | * Support for MCP tools.
  700 | 
  701 | ### Roo Code
  702 | 
  703 | [Roo Code](https://roocode.com) enables AI coding assistance via MCP.
  704 | 
  705 | **Key features:**
  706 | 
  707 | * Support for MCP tools and resources
  708 | * Integration with development workflows
  709 | * Extensible AI capabilities
  710 | 
  711 | ### Postman
  712 | 
  713 | [Postman](https://postman.com/downloads) is the most popular API client and now supports MCP server testing and debugging.
  714 | 
  715 | **Key features:**
  716 | 
  717 | * Full support of all major MCP features (tools, prompts, resources, and subscriptions)
  718 | * Fast, seamless UI for debugging MCP capabilities
  719 | * MCP config integration (Claude, VSCode, etc.) for fast first-time experience in testing MCPs
  720 | * Integration with history, variables, and collections for reuse and collaboration
  721 | 
  722 | ### Slack MCP Client
  723 | 
  724 | [Slack MCP Client](https://github.com/tuannvm/slack-mcp-client) acts as a bridge between Slack and Model Context Protocol (MCP) servers. Using Slack as the interface, it enables large language models (LLMs) to connect and interact with various MCP servers through standardized MCP tools.
  725 | 
  726 | **Key features:**
  727 | 
  728 | * **Supports Popular LLM Providers:** Integrates seamlessly with leading large language model providers such as OpenAI, Anthropic, and Ollama, allowing users to leverage advanced conversational AI and orchestration capabilities within Slack.
  729 | * **Dynamic and Secure Integration:** Supports dynamic registration of MCP tools, works in both channels and direct messages and manages credentials securely via environment variables or Kubernetes secrets.
  730 | * **Easy Deployment and Extensibility:** Offers official Docker images, a Helm chart for Kubernetes, and Docker Compose for local development, making it simple to deploy, configure, and extend with additional MCP servers or tools.
  731 | 
  732 | ### Sourcegraph Cody
  733 | 
  734 | [Cody](https://openctx.org/docs/providers/modelcontextprotocol) is Sourcegraph's AI coding assistant, which implements MCP through OpenCTX.
  735 | 
  736 | **Key features:**
  737 | 
  738 | * Support for MCP resources
  739 | * Integration with Sourcegraph's code intelligence
  740 | * Uses OpenCTX as an abstraction layer
  741 | * Future support planned for additional MCP features
  742 | 
  743 | ### SpinAI
  744 | 
  745 | [SpinAI](https://spinai.dev) is an open-source TypeScript framework for building observable AI agents. The framework provides native MCP compatibility, allowing agents to seamlessly integrate with MCP servers and tools.
  746 | 
  747 | **Key features:**
  748 | 
  749 | * Built-in MCP compatibility for AI agents
  750 | * Open-source TypeScript framework
  751 | * Observable agent architecture
  752 | * Native support for MCP tools integration
  753 | 
  754 | ### Superinterface
  755 | 
  756 | [Superinterface](https://superinterface.ai) is AI infrastructure and a developer platform to build in-app AI assistants with support for MCP, interactive components, client-side function calling and more.
  757 | 
  758 | **Key features:**
  759 | 
  760 | * Use tools from MCP servers in assistants embedded via React components or script tags
  761 | * SSE transport support
  762 | * Use any AI model from any AI provider (OpenAI, Anthropic, Ollama, others)
  763 | 
  764 | ### Superjoin
  765 | 
  766 | [Superjoin](https://superjoin.ai) brings the power of MCP directly into Google Sheets extension. With Superjoin, users can access and invoke MCP tools and agents without leaving their spreadsheets, enabling powerful AI workflows and automation right where their data lives.
  767 | 
  768 | **Key features:**
  769 | 
  770 | * Native Google Sheets add-on providing effortless access to MCP capabilities
  771 | * Supports OAuth 2.1 and header-based authentication for secure and flexible connections
  772 | * Compatible with both SSE and Streamable HTTP transport for efficient, real-time streaming communication
  773 | * Fully web-based, cross-platform client requiring no additional software installation
  774 | 
  775 | ### TheiaAI/TheiaIDE
  776 | 
  777 | [Theia AI](https://eclipsesource.com/blogs/2024/10/07/introducing-theia-ai/) is a framework for building AI-enhanced tools and IDEs. The [AI-powered Theia IDE](https://eclipsesource.com/blogs/2024/10/08/introducting-ai-theia-ide/) is an open and flexible development environment built on Theia AI.
  778 | 
  779 | **Key features:**
  780 | 
  781 | * **Tool Integration**: Theia AI enables AI agents, including those in the Theia IDE, to utilize MCP servers for seamless tool interaction.
  782 | * **Customizable Prompts**: The Theia IDE allows users to define and adapt prompts, dynamically integrating MCP servers for tailored workflows.
  783 | * **Custom agents**: The Theia IDE supports creating custom agents that leverage MCP capabilities, enabling users to design dedicated workflows on the fly.
  784 | 
  785 | Theia AI and Theia IDE's MCP integration provide users with flexibility, making them powerful platforms for exploring and adapting MCP.
  786 | 
  787 | **Learn more:**
  788 | 
  789 | * [Theia IDE and Theia AI MCP Announcement](https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/)
  790 | * [Download the AI-powered Theia IDE](https://theia-ide.org/)
  791 | 
  792 | ### Tome
  793 | 
  794 | [Tome](https://github.com/runebookai/tome) is an open source cross-platform desktop app designed for working with local LLMs and MCP servers. It is designed to be beginner friendly and abstract away the nitty gritty of configuration for people getting started with MCP.
  795 | 
  796 | **Key features:**
  797 | 
  798 | * MCP servers are managed by Tome so there is no need to install uv or npm or configure JSON
  799 | * Users can quickly add or remove MCP servers via UI
  800 | * Any tool-supported local model on Ollama is compatible
  801 | 
  802 | ### TypingMind App
  803 | 
  804 | [TypingMind](https://www.typingmind.com) is an advanced frontend for LLMs with MCP support. TypingMind supports all popular LLM providers like OpenAI, Gemini, Claude, and users can use with their own API keys.
  805 | 
  806 | **Key features:**
  807 | 
  808 | * **MCP Tool Integration**: Once MCP is configured, MCP tools will show up as plugins that can be enabled/disabled easily via the main app interface.
  809 | * **Assign MCP Tools to Agents**: TypingMind allows users to create AI agents that have a set of MCP servers assigned.
  810 | * **Remote MCP servers**: Allows users to customize where to run the MCP servers via its MCP Connector configuration, allowing the use of MCP tools across multiple devices (laptop, mobile devices, etc.) or control MCP servers from a remote private server.
  811 | 
  812 | **Learn more:**
  813 | 
  814 | * [TypingMind MCP Document](https://www.typingmind.com/mcp)
  815 | * [Download TypingMind (PWA)](https://www.typingmind.com/)
  816 | 
  817 | ### VS Code GitHub Copilot
  818 | 
  819 | [VS Code](https://code.visualstudio.com/) integrates MCP with GitHub Copilot through [agent mode](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode), allowing direct interaction with MCP-provided tools within your agentic coding workflow. Configure servers in Claude Desktop, workspace or user settings, with guided MCP installation and secure handling of keys in input variables to avoid leaking hard-coded keys.
  820 | 
  821 | **Key features:**
  822 | 
  823 | * Support for stdio and server-sent events (SSE) transport
  824 | * Per-session selection of tools per agent session for optimal performance
  825 | * Easy server debugging with restart commands and output logging
  826 | * Tool calls with editable inputs and always-allow toggle
  827 | * Integration with existing VS Code extension system to register MCP servers from extensions
  828 | 
  829 | ### Warp
  830 | 
  831 | [Warp](https://www.warp.dev/) is the intelligent terminal with AI and your dev team's knowledge built-in. With natural language capabilities integrated directly into an agentic command line, Warp enables developers to code, automate, and collaborate more efficiently -- all within a terminal that features a modern UX.
  832 | 
  833 | **Key features:**
  834 | 
  835 | * **Agent Mode with MCP support**: invoke tools and access data from MCP servers using natural language prompts
  836 | * **Flexible server management**: add and manage CLI or SSE-based MCP servers via Warp's built-in UI
  837 | * **Live tool/resource discovery**: view tools and resources from each running MCP server
  838 | * **Configurable startup**: set MCP servers to start automatically with Warp or launch them manually as needed
  839 | 
  840 | ### WhatsMCP
  841 | 
  842 | [WhatsMCP](https://wassist.app/mcp/) is an MCP client for WhatsApp. WhatsMCP lets you interact with your AI stack from the comfort of a WhatsApp chat.
  843 | 
  844 | **Key features:**
  845 | 
  846 | * Supports MCP tools
  847 | * SSE transport, full OAuth2 support
  848 | * Chat flow management for WhatsApp messages
  849 | * One click setup for connecting to your MCP servers
  850 | * In chat management of MCP servers
  851 | * Oauth flow natively supported in WhatsApp
  852 | 
  853 | ### Windsurf Editor
  854 | 
  855 | [Windsurf Editor](https://codeium.com/windsurf) is an agentic IDE that combines AI assistance with developer workflows. It features an innovative AI Flow system that enables both collaborative and independent AI interactions while maintaining developer control.
  856 | 
  857 | **Key features:**
  858 | 
  859 | * Revolutionary AI Flow paradigm for human-AI collaboration
  860 | * Intelligent code generation and understanding
  861 | * Rich development tools with multi-model support
  862 | 
  863 | ### Witsy
  864 | 
  865 | [Witsy](https://github.com/nbonamy/witsy) is an AI desktop assistant, supporting Anthropic models and MCP servers as LLM tools.
  866 | 
  867 | **Key features:**
  868 | 
  869 | * Multiple MCP servers support
  870 | * Tool integration for executing commands and scripts
  871 | * Local server connections for enhanced privacy and security
  872 | * Easy-install from Smithery.ai
  873 | * Open-source, available for macOS, Windows and Linux
  874 | 
  875 | ### Zed
  876 | 
  877 | [Zed](https://zed.dev/docs/assistant/model-context-protocol) is a high-performance code editor with built-in MCP support, focusing on prompt templates and tool integration.
  878 | 
  879 | **Key features:**
  880 | 
  881 | * Prompt templates surface as slash commands in the editor
  882 | * Tool integration for enhanced coding workflows
  883 | * Tight integration with editor features and workspace context
  884 | * Does not support MCP resources
  885 | 
  886 | ### Zencoder
  887 | 
  888 | [Zencoder](https://zecoder.ai) is a coding agent that's available as an extension for VS Code and JetBrains family of IDEs, meeting developers where they already work. It comes with RepoGrokking (deep contextual codebase understanding), agentic pipeline, and the ability to create and share custom agents.
  889 | 
  890 | **Key features:**
  891 | 
  892 | * RepoGrokking - deep contextual understanding of codebases
  893 | * Agentic pipeline - runs, tests, and executes code before outputting it
  894 | * Zen Agents platform - ability to build and create custom agents and share with the team
  895 | * Integrated MCP tool library with one-click installations
  896 | * Specialized agents for Unit and E2E Testing
  897 | 
  898 | **Learn more:**
  899 | 
  900 | * [Zencoder Documentation](https://docs.zencoder.ai)
  901 | 
  902 | ## Adding MCP support to your application
  903 | 
  904 | If you've added MCP support to your application, we encourage you to submit a pull request to add it to this list. MCP integration can provide your users with powerful contextual AI capabilities and make your application part of the growing MCP ecosystem.
  905 | 
  906 | Benefits of adding MCP support:
  907 | 
  908 | * Enable users to bring their own context and tools
  909 | * Join a growing ecosystem of interoperable AI applications
  910 | * Provide users with flexible integration options
  911 | * Support local-first AI workflows
  912 | 
  913 | To get started with implementing MCP in your application, check out our [Python](https://github.com/modelcontextprotocol/python-sdk) or [TypeScript SDK Documentation](https://github.com/modelcontextprotocol/typescript-sdk)
  914 | 
  915 | ## Updates and corrections
  916 | 
  917 | This list is maintained by the community. If you notice any inaccuracies or would like to update information about MCP support in your application, please submit a pull request or [open an issue in our documentation repository](https://github.com/modelcontextprotocol/modelcontextprotocol/issues).
  918 | 
  919 | 
  920 | # Contributing
  921 | Source: https://modelcontextprotocol.io/development/contributing
  922 | 
  923 | How to participate in Model Context Protocol development
  924 | 
  925 | We welcome contributions from the community! Please review our [contributing guidelines](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/CONTRIBUTING.md) for details on how to submit changes.
  926 | 
  927 | All contributors must adhere to our [Code of Conduct](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/CODE_OF_CONDUCT.md).
  928 | 
  929 | For questions and discussions, please use [GitHub Discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions).
  930 | 
  931 | 
  932 | # Roadmap
  933 | Source: https://modelcontextprotocol.io/development/roadmap
  934 | 
  935 | Our plans for evolving Model Context Protocol
  936 | 
  937 | <Info>Last updated: **2025-03-27**</Info>
  938 | 
  939 | The Model Context Protocol is rapidly evolving. This page outlines our current thinking on key priorities and direction for approximately **the next six months**, though these may change significantly as the project develops. To see what's changed recently, check out the **[specification changelog](/specification/2025-06-18/changelog/)**.
  940 | 
  941 | <Note>
  942 |   The ideas presented here are not commitments—we may solve these challenges differently than described, or some may not materialize at all. This is also not an *exhaustive* list; we may incorporate work that isn't mentioned here.
  943 | </Note>
  944 | 
  945 | We value community participation! Each section links to relevant discussions where you can learn more and contribute your thoughts.
  946 | 
  947 | For a technical view of our standardization process, visit the [Standards Track](https://github.com/orgs/modelcontextprotocol/projects/2/views/2) on GitHub, which tracks how proposals progress toward inclusion in the official [MCP specification](https://spec.modelcontextprotocol.io).
  948 | 
  949 | ## Validation
  950 | 
  951 | To foster a robust developer ecosystem, we plan to invest in:
  952 | 
  953 | * **Reference Client Implementations**: demonstrating protocol features with high-quality AI applications
  954 | * **Compliance Test Suites**: automated verification that clients, servers, and SDKs properly implement the specification
  955 | 
  956 | These tools will help developers confidently implement MCP while ensuring consistent behavior across the ecosystem.
  957 | 
  958 | ## Registry
  959 | 
  960 | For MCP to reach its full potential, we need streamlined ways to distribute and discover MCP servers.
  961 | 
  962 | We plan to develop an [**MCP Registry**](https://github.com/orgs/modelcontextprotocol/discussions/159) that will enable centralized server discovery and metadata. This registry will primarily function as an API layer that third-party marketplaces and discovery services can build upon.
  963 | 
  964 | ## Agents
  965 | 
  966 | As MCP increasingly becomes part of agentic workflows, we're exploring [improvements](https://github.com/modelcontextprotocol/specification/discussions/111) such as:
  967 | 
  968 | * **[Agent Graphs](https://github.com/modelcontextprotocol/specification/discussions/94)**: enabling complex agent topologies through namespacing and graph-aware communication patterns
  969 | * **Interactive Workflows**: improving human-in-the-loop experiences with granular permissioning, standardized interaction patterns, and [ways to directly communicate](https://github.com/modelcontextprotocol/specification/issues/97) with the end user
  970 | 
  971 | ## Multimodality
  972 | 
  973 | Supporting the full spectrum of AI capabilities in MCP, including:
  974 | 
  975 | * **Additional Modalities**: video and other media types
  976 | * **[Streaming](https://github.com/modelcontextprotocol/specification/issues/117)**: multipart, chunked messages, and bidirectional communication for interactive experiences
  977 | 
  978 | ## Governance
  979 | 
  980 | We're implementing governance structures that prioritize:
  981 | 
  982 | * **Community-Led Development**: fostering a collaborative ecosystem where community members and AI developers can all participate in MCP's evolution, ensuring it serves diverse applications and use cases
  983 | * **Transparent Standardization**: establishing clear processes for contributing to the specification, while exploring formal standardization via industry bodies
  984 | 
  985 | ## Get Involved
  986 | 
  987 | We welcome your contributions to MCP's future! Join our [GitHub Discussions](https://github.com/orgs/modelcontextprotocol/discussions) to share ideas, provide feedback, or participate in the development process.
  988 | 
  989 | 
  990 | # Core architecture
  991 | Source: https://modelcontextprotocol.io/docs/concepts/architecture
  992 | 
  993 | Understand how MCP connects clients, servers, and LLMs
  994 | 
  995 | The Model Context Protocol (MCP) is built on a flexible, extensible architecture that enables seamless communication between LLM applications and integrations. This document covers the core architectural components and concepts.
  996 | 
  997 | ## Overview
  998 | 
  999 | MCP follows a client-server architecture where:
 1000 | 
 1001 | * **Hosts** are LLM applications (like Claude Desktop or IDEs) that initiate connections
 1002 | * **Clients** maintain 1:1 connections with servers, inside the host application
 1003 | * **Servers** provide context, tools, and prompts to clients
 1004 | 
 1005 | ```mermaid
 1006 | flowchart LR
 1007 |     subgraph "Host"
 1008 |         client1[MCP Client]
 1009 |         client2[MCP Client]
 1010 |     end
 1011 |     subgraph "Server Process"
 1012 |         server1[MCP Server]
 1013 |     end
 1014 |     subgraph "Server Process"
 1015 |         server2[MCP Server]
 1016 |     end
 1017 | 
 1018 |     client1 <-->|Transport Layer| server1
 1019 |     client2 <-->|Transport Layer| server2
 1020 | ```
 1021 | 
 1022 | ## Core components
 1023 | 
 1024 | ### Protocol layer
 1025 | 
 1026 | The protocol layer handles message framing, request/response linking, and high-level communication patterns.
 1027 | 
 1028 | <Tabs>
 1029 |   <Tab title="TypeScript">
 1030 |     ```typescript
 1031 |     class Protocol<Request, Notification, Result> {
 1032 |         // Handle incoming requests
 1033 |         setRequestHandler<T>(schema: T, handler: (request: T, extra: RequestHandlerExtra) => Promise<Result>): void
 1034 | 
 1035 |         // Handle incoming notifications
 1036 |         setNotificationHandler<T>(schema: T, handler: (notification: T) => Promise<void>): void
 1037 | 
 1038 |         // Send requests and await responses
 1039 |         request<T>(request: Request, schema: T, options?: RequestOptions): Promise<T>
 1040 | 
 1041 |         // Send one-way notifications
 1042 |         notification(notification: Notification): Promise<void>
 1043 |     }
 1044 |     ```
 1045 |   </Tab>
 1046 | 
 1047 |   <Tab title="Python">
 1048 |     ```python
 1049 |     class Session(BaseSession[RequestT, NotificationT, ResultT]):
 1050 |         async def send_request(
 1051 |             self,
 1052 |             request: RequestT,
 1053 |             result_type: type[Result]
 1054 |         ) -> Result:
 1055 |             """Send request and wait for response. Raises McpError if response contains error."""
 1056 |             # Request handling implementation
 1057 | 
 1058 |         async def send_notification(
 1059 |             self,
 1060 |             notification: NotificationT
 1061 |         ) -> None:
 1062 |             """Send one-way notification that doesn't expect response."""
 1063 |             # Notification handling implementation
 1064 | 
 1065 |         async def _received_request(
 1066 |             self,
 1067 |             responder: RequestResponder[ReceiveRequestT, ResultT]
 1068 |         ) -> None:
 1069 |             """Handle incoming request from other side."""
 1070 |             # Request handling implementation
 1071 | 
 1072 |         async def _received_notification(
 1073 |             self,
 1074 |             notification: ReceiveNotificationT
 1075 |         ) -> None:
 1076 |             """Handle incoming notification from other side."""
 1077 |             # Notification handling implementation
 1078 |     ```
 1079 |   </Tab>
 1080 | </Tabs>
 1081 | 
 1082 | Key classes include:
 1083 | 
 1084 | * `Protocol`
 1085 | * `Client`
 1086 | * `Server`
 1087 | 
 1088 | ### Transport layer
 1089 | 
 1090 | The transport layer handles the actual communication between clients and servers. MCP supports multiple transport mechanisms:
 1091 | 
 1092 | 1. **Stdio transport**
 1093 | 
 1094 |    * Uses standard input/output for communication
 1095 |    * Ideal for local processes
 1096 | 
 1097 | 2. **Streamable HTTP transport**
 1098 |    * Uses HTTP with optional Server-Sent Events for streaming
 1099 |    * HTTP POST for client-to-server messages
 1100 | 
 1101 | All transports use [JSON-RPC](https://www.jsonrpc.org/) 2.0 to exchange messages. See the [specification](/specification/) for detailed information about the Model Context Protocol message format.
 1102 | 
 1103 | ### Message types
 1104 | 
 1105 | MCP has these main types of messages:
 1106 | 
 1107 | 1. **Requests** expect a response from the other side:
 1108 | 
 1109 |    ```typescript
 1110 |    interface Request {
 1111 |      method: string;
 1112 |      params?: { ... };
 1113 |    }
 1114 |    ```
 1115 | 
 1116 | 2. **Results** are successful responses to requests:
 1117 | 
 1118 |    ```typescript
 1119 |    interface Result {
 1120 |      [key: string]: unknown;
 1121 |    }
 1122 |    ```
 1123 | 
 1124 | 3. **Errors** indicate that a request failed:
 1125 | 
 1126 |    ```typescript
 1127 |    interface Error {
 1128 |      code: number;
 1129 |      message: string;
 1130 |      data?: unknown;
 1131 |    }
 1132 |    ```
 1133 | 
 1134 | 4. **Notifications** are one-way messages that don't expect a response:
 1135 |    ```typescript
 1136 |    interface Notification {
 1137 |      method: string;
 1138 |      params?: { ... };
 1139 |    }
 1140 |    ```
 1141 | 
 1142 | ## Connection lifecycle
 1143 | 
 1144 | ### 1. Initialization
 1145 | 
 1146 | ```mermaid
 1147 | sequenceDiagram
 1148 |     participant Client
 1149 |     participant Server
 1150 | 
 1151 |     Client->>Server: initialize request
 1152 |     Server->>Client: initialize response
 1153 |     Client->>Server: initialized notification
 1154 | 
 1155 |     Note over Client,Server: Connection ready for use
 1156 | ```
 1157 | 
 1158 | 1. Client sends `initialize` request with protocol version and capabilities
 1159 | 2. Server responds with its protocol version and capabilities
 1160 | 3. Client sends `initialized` notification as acknowledgment
 1161 | 4. Normal message exchange begins
 1162 | 
 1163 | ### 2. Message exchange
 1164 | 
 1165 | After initialization, the following patterns are supported:
 1166 | 
 1167 | * **Request-Response**: Client or server sends requests, the other responds
 1168 | * **Notifications**: Either party sends one-way messages
 1169 | 
 1170 | ### 3. Termination
 1171 | 
 1172 | Either party can terminate the connection:
 1173 | 
 1174 | * Clean shutdown via `close()`
 1175 | * Transport disconnection
 1176 | * Error conditions
 1177 | 
 1178 | ## Error handling
 1179 | 
 1180 | MCP defines these standard error codes:
 1181 | 
 1182 | ```typescript
 1183 | enum ErrorCode {
 1184 |   // Standard JSON-RPC error codes
 1185 |   ParseError = -32700,
 1186 |   InvalidRequest = -32600,
 1187 |   MethodNotFound = -32601,
 1188 |   InvalidParams = -32602,
 1189 |   InternalError = -32603,
 1190 | }
 1191 | ```
 1192 | 
 1193 | SDKs and applications can define their own error codes above -32000.
 1194 | 
 1195 | Errors are propagated through:
 1196 | 
 1197 | * Error responses to requests
 1198 | * Error events on transports
 1199 | * Protocol-level error handlers
 1200 | 
 1201 | ## Implementation example
 1202 | 
 1203 | Here's a basic example of implementing an MCP server:
 1204 | 
 1205 | <Tabs>
 1206 |   <Tab title="TypeScript">
 1207 |     ```typescript
 1208 |     import { Server } from "@modelcontextprotocol/sdk/server/index.js";
 1209 |     import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 1210 | 
 1211 |     const server = new Server({
 1212 |       name: "example-server",
 1213 |       version: "1.0.0"
 1214 |     }, {
 1215 |       capabilities: {
 1216 |         resources: {}
 1217 |       }
 1218 |     });
 1219 | 
 1220 |     // Handle requests
 1221 |     server.setRequestHandler(ListResourcesRequestSchema, async () => {
 1222 |       return {
 1223 |         resources: [
 1224 |           {
 1225 |             uri: "example://resource",
 1226 |             name: "Example Resource"
 1227 |           }
 1228 |         ]
 1229 |       };
 1230 |     });
 1231 | 
 1232 |     // Connect transport
 1233 |     const transport = new StdioServerTransport();
 1234 |     await server.connect(transport);
 1235 |     ```
 1236 |   </Tab>
 1237 | 
 1238 |   <Tab title="Python">
 1239 |     ```python
 1240 |     import asyncio
 1241 |     import mcp.types as types
 1242 |     from mcp.server import Server
 1243 |     from mcp.server.stdio import stdio_server
 1244 | 
 1245 |     app = Server("example-server")
 1246 | 
 1247 |     @app.list_resources()
 1248 |     async def list_resources() -> list[types.Resource]:
 1249 |         return [
 1250 |             types.Resource(
 1251 |                 uri="example://resource",
 1252 |                 name="Example Resource"
 1253 |             )
 1254 |         ]
 1255 | 
 1256 |     async def main():
 1257 |         async with stdio_server() as streams:
 1258 |             await app.run(
 1259 |                 streams[0],
 1260 |                 streams[1],
 1261 |                 app.create_initialization_options()
 1262 |             )
 1263 | 
 1264 |     if __name__ == "__main__":
 1265 |         asyncio.run(main())
 1266 |     ```
 1267 |   </Tab>
 1268 | </Tabs>
 1269 | 
 1270 | ## Best practices
 1271 | 
 1272 | ### Transport selection
 1273 | 
 1274 | 1. **Local communication**
 1275 | 
 1276 |    * Use stdio transport for local processes
 1277 |    * Efficient for same-machine communication
 1278 |    * Simple process management
 1279 | 
 1280 | 2. **Remote communication**
 1281 |    * Use Streamable HTTP for scenarios requiring HTTP compatibility
 1282 |    * Consider security implications including authentication and authorization
 1283 | 
 1284 | ### Message handling
 1285 | 
 1286 | 1. **Request processing**
 1287 | 
 1288 |    * Validate inputs thoroughly
 1289 |    * Use type-safe schemas
 1290 |    * Handle errors gracefully
 1291 |    * Implement timeouts
 1292 | 
 1293 | 2. **Progress reporting**
 1294 | 
 1295 |    * Use progress tokens for long operations
 1296 |    * Report progress incrementally
 1297 |    * Include total progress when known
 1298 | 
 1299 | 3. **Error management**
 1300 |    * Use appropriate error codes
 1301 |    * Include helpful error messages
 1302 |    * Clean up resources on errors
 1303 | 
 1304 | ## Security considerations
 1305 | 
 1306 | 1. **Transport security**
 1307 | 
 1308 |    * Use TLS for remote connections
 1309 |    * Validate connection origins
 1310 |    * Implement authentication when needed
 1311 | 
 1312 | 2. **Message validation**
 1313 | 
 1314 |    * Validate all incoming messages
 1315 |    * Sanitize inputs
 1316 |    * Check message size limits
 1317 |    * Verify JSON-RPC format
 1318 | 
 1319 | 3. **Resource protection**
 1320 | 
 1321 |    * Implement access controls
 1322 |    * Validate resource paths
 1323 |    * Monitor resource usage
 1324 |    * Rate limit requests
 1325 | 
 1326 | 4. **Error handling**
 1327 |    * Don't leak sensitive information
 1328 |    * Log security-relevant errors
 1329 |    * Implement proper cleanup
 1330 |    * Handle DoS scenarios
 1331 | 
 1332 | ## Debugging and monitoring
 1333 | 
 1334 | 1. **Logging**
 1335 | 
 1336 |    * Log protocol events
 1337 |    * Track message flow
 1338 |    * Monitor performance
 1339 |    * Record errors
 1340 | 
 1341 | 2. **Diagnostics**
 1342 | 
 1343 |    * Implement health checks
 1344 |    * Monitor connection state
 1345 |    * Track resource usage
 1346 |    * Profile performance
 1347 | 
 1348 | 3. **Testing**
 1349 |    * Test different transports
 1350 |    * Verify error handling
 1351 |    * Check edge cases
 1352 |    * Load test servers
 1353 | 
 1354 | 
 1355 | # Prompts
 1356 | Source: https://modelcontextprotocol.io/docs/concepts/prompts
 1357 | 
 1358 | Create reusable prompt templates and workflows
 1359 | 
 1360 | Prompts enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs. They provide a powerful way to standardize and share common LLM interactions.
 1361 | 
 1362 | <Note>
 1363 |   Prompts are designed to be **user-controlled**, meaning they are exposed from servers to clients with the intention of the user being able to explicitly select them for use.
 1364 | </Note>
 1365 | 
 1366 | ## Overview
 1367 | 
 1368 | Prompts in MCP are predefined templates that can:
 1369 | 
 1370 | * Accept dynamic arguments
 1371 | * Include context from resources
 1372 | * Chain multiple interactions
 1373 | * Guide specific workflows
 1374 | * Surface as UI elements (like slash commands)
 1375 | 
 1376 | ## Prompt structure
 1377 | 
 1378 | Each prompt is defined with:
 1379 | 
 1380 | ```typescript
 1381 | {
 1382 |   name: string;              // Unique identifier for the prompt
 1383 |   description?: string;      // Human-readable description
 1384 |   arguments?: [              // Optional list of arguments
 1385 |     {
 1386 |       name: string;          // Argument identifier
 1387 |       description?: string;  // Argument description
 1388 |       required?: boolean;    // Whether argument is required
 1389 |     }
 1390 |   ]
 1391 | }
 1392 | ```
 1393 | 
 1394 | ## Discovering prompts
 1395 | 
 1396 | Clients can discover available prompts by sending a `prompts/list` request:
 1397 | 
 1398 | ```typescript
 1399 | // Request
 1400 | {
 1401 |   method: "prompts/list";
 1402 | }
 1403 | 
 1404 | // Response
 1405 | {
 1406 |   prompts: [
 1407 |     {
 1408 |       name: "analyze-code",
 1409 |       description: "Analyze code for potential improvements",
 1410 |       arguments: [
 1411 |         {
 1412 |           name: "language",
 1413 |           description: "Programming language",
 1414 |           required: true,
 1415 |         },
 1416 |       ],
 1417 |     },
 1418 |   ];
 1419 | }
 1420 | ```
 1421 | 
 1422 | ## Using prompts
 1423 | 
 1424 | To use a prompt, clients make a `prompts/get` request:
 1425 | 
 1426 | ````typescript
 1427 | // Request
 1428 | {
 1429 |   method: "prompts/get",
 1430 |   params: {
 1431 |     name: "analyze-code",
 1432 |     arguments: {
 1433 |       language: "python"
 1434 |     }
 1435 |   }
 1436 | }
 1437 | 
 1438 | // Response
 1439 | {
 1440 |   description: "Analyze Python code for potential improvements",
 1441 |   messages: [
 1442 |     {
 1443 |       role: "user",
 1444 |       content: {
 1445 |         type: "text",
 1446 |         text: "Please analyze the following Python code for potential improvements:\n\n```python\ndef calculate_sum(numbers):\n    total = 0\n    for num in numbers:\n        total = total + num\n    return total\n\nresult = calculate_sum([1, 2, 3, 4, 5])\nprint(result)\n```"
 1447 |       }
 1448 |     }
 1449 |   ]
 1450 | }
 1451 | ````
 1452 | 
 1453 | ## Dynamic prompts
 1454 | 
 1455 | Prompts can be dynamic and include:
 1456 | 
 1457 | ### Embedded resource context
 1458 | 
 1459 | ```json
 1460 | {
 1461 |   "name": "analyze-project",
 1462 |   "description": "Analyze project logs and code",
 1463 |   "arguments": [
 1464 |     {
 1465 |       "name": "timeframe",
 1466 |       "description": "Time period to analyze logs",
 1467 |       "required": true
 1468 |     },
 1469 |     {
 1470 |       "name": "fileUri",
 1471 |       "description": "URI of code file to review",
 1472 |       "required": true
 1473 |     }
 1474 |   ]
 1475 | }
 1476 | ```
 1477 | 
 1478 | When handling the `prompts/get` request:
 1479 | 
 1480 | ```json
 1481 | {
 1482 |   "messages": [
 1483 |     {
 1484 |       "role": "user",
 1485 |       "content": {
 1486 |         "type": "text",
 1487 |         "text": "Analyze these system logs and the code file for any issues:"
 1488 |       }
 1489 |     },
 1490 |     {
 1491 |       "role": "user",
 1492 |       "content": {
 1493 |         "type": "resource",
 1494 |         "resource": {
 1495 |           "uri": "logs://recent?timeframe=1h",
 1496 |           "text": "[2024-03-14 15:32:11] ERROR: Connection timeout in network.py:127\n[2024-03-14 15:32:15] WARN: Retrying connection (attempt 2/3)\n[2024-03-14 15:32:20] ERROR: Max retries exceeded",
 1497 |           "mimeType": "text/plain"
 1498 |         }
 1499 |       }
 1500 |     },
 1501 |     {
 1502 |       "role": "user",
 1503 |       "content": {
 1504 |         "type": "resource",
 1505 |         "resource": {
 1506 |           "uri": "file:///path/to/code.py",
 1507 |           "text": "def connect_to_service(timeout=30):\n    retries = 3\n    for attempt in range(retries):\n        try:\n            return establish_connection(timeout)\n        except TimeoutError:\n            if attempt == retries - 1:\n                raise\n            time.sleep(5)\n\ndef establish_connection(timeout):\n    # Connection implementation\n    pass",
 1508 |           "mimeType": "text/x-python"
 1509 |         }
 1510 |       }
 1511 |     }
 1512 |   ]
 1513 | }
 1514 | ```
 1515 | 
 1516 | ### Multi-step workflows
 1517 | 
 1518 | ```typescript
 1519 | const debugWorkflow = {
 1520 |   name: "debug-error",
 1521 |   async getMessages(error: string) {
 1522 |     return [
 1523 |       {
 1524 |         role: "user",
 1525 |         content: {
 1526 |           type: "text",
 1527 |           text: `Here's an error I'm seeing: ${error}`,
 1528 |         },
 1529 |       },
 1530 |       {
 1531 |         role: "assistant",
 1532 |         content: {
 1533 |           type: "text",
 1534 |           text: "I'll help analyze this error. What have you tried so far?",
 1535 |         },
 1536 |       },
 1537 |       {
 1538 |         role: "user",
 1539 |         content: {
 1540 |           type: "text",
 1541 |           text: "I've tried restarting the service, but the error persists.",
 1542 |         },
 1543 |       },
 1544 |     ];
 1545 |   },
 1546 | };
 1547 | ```
 1548 | 
 1549 | ## Example implementation
 1550 | 
 1551 | Here's a complete example of implementing prompts in an MCP server:
 1552 | 
 1553 | <Tabs>
 1554 |   <Tab title="TypeScript">
 1555 |     ```typescript
 1556 |     import { Server } from "@modelcontextprotocol/sdk/server";
 1557 |     import {
 1558 |       ListPromptsRequestSchema,
 1559 |       GetPromptRequestSchema
 1560 |     } from "@modelcontextprotocol/sdk/types";
 1561 | 
 1562 |     const PROMPTS = {
 1563 |       "git-commit": {
 1564 |         name: "git-commit",
 1565 |         description: "Generate a Git commit message",
 1566 |         arguments: [
 1567 |           {
 1568 |             name: "changes",
 1569 |             description: "Git diff or description of changes",
 1570 |             required: true
 1571 |           }
 1572 |         ]
 1573 |       },
 1574 |       "explain-code": {
 1575 |         name: "explain-code",
 1576 |         description: "Explain how code works",
 1577 |         arguments: [
 1578 |           {
 1579 |             name: "code",
 1580 |             description: "Code to explain",
 1581 |             required: true
 1582 |           },
 1583 |           {
 1584 |             name: "language",
 1585 |             description: "Programming language",
 1586 |             required: false
 1587 |           }
 1588 |         ]
 1589 |       }
 1590 |     };
 1591 | 
 1592 |     const server = new Server({
 1593 |       name: "example-prompts-server",
 1594 |       version: "1.0.0"
 1595 |     }, {
 1596 |       capabilities: {
 1597 |         prompts: {}
 1598 |       }
 1599 |     });
 1600 | 
 1601 |     // List available prompts
 1602 |     server.setRequestHandler(ListPromptsRequestSchema, async () => {
 1603 |       return {
 1604 |         prompts: Object.values(PROMPTS)
 1605 |       };
 1606 |     });
 1607 | 
 1608 |     // Get specific prompt
 1609 |     server.setRequestHandler(GetPromptRequestSchema, async (request) => {
 1610 |       const prompt = PROMPTS[request.params.name];
 1611 |       if (!prompt) {
 1612 |         throw new Error(`Prompt not found: ${request.params.name}`);
 1613 |       }
 1614 | 
 1615 |       if (request.params.name === "git-commit") {
 1616 |         return {
 1617 |           messages: [
 1618 |             {
 1619 |               role: "user",
 1620 |               content: {
 1621 |                 type: "text",
 1622 |                 text: `Generate a concise but descriptive commit message for these changes:\n\n${request.params.arguments?.changes}`
 1623 |               }
 1624 |             }
 1625 |           ]
 1626 |         };
 1627 |       }
 1628 | 
 1629 |       if (request.params.name === "explain-code") {
 1630 |         const language = request.params.arguments?.language || "Unknown";
 1631 |         return {
 1632 |           messages: [
 1633 |             {
 1634 |               role: "user",
 1635 |               content: {
 1636 |                 type: "text",
 1637 |                 text: `Explain how this ${language} code works:\n\n${request.params.arguments?.code}`
 1638 |               }
 1639 |             }
 1640 |           ]
 1641 |         };
 1642 |       }
 1643 | 
 1644 |       throw new Error("Prompt implementation not found");
 1645 |     });
 1646 |     ```
 1647 |   </Tab>
 1648 | 
 1649 |   <Tab title="Python">
 1650 |     ```python
 1651 |     from mcp.server import Server
 1652 |     import mcp.types as types
 1653 | 
 1654 |     # Define available prompts
 1655 |     PROMPTS = {
 1656 |         "git-commit": types.Prompt(
 1657 |             name="git-commit",
 1658 |             description="Generate a Git commit message",
 1659 |             arguments=[
 1660 |                 types.PromptArgument(
 1661 |                     name="changes",
 1662 |                     description="Git diff or description of changes",
 1663 |                     required=True
 1664 |                 )
 1665 |             ],
 1666 |         ),
 1667 |         "explain-code": types.Prompt(
 1668 |             name="explain-code",
 1669 |             description="Explain how code works",
 1670 |             arguments=[
 1671 |                 types.PromptArgument(
 1672 |                     name="code",
 1673 |                     description="Code to explain",
 1674 |                     required=True
 1675 |                 ),
 1676 |                 types.PromptArgument(
 1677 |                     name="language",
 1678 |                     description="Programming language",
 1679 |                     required=False
 1680 |                 )
 1681 |             ],
 1682 |         )
 1683 |     }
 1684 | 
 1685 |     # Initialize server
 1686 |     app = Server("example-prompts-server")
 1687 | 
 1688 |     @app.list_prompts()
 1689 |     async def list_prompts() -> list[types.Prompt]:
 1690 |         return list(PROMPTS.values())
 1691 | 
 1692 |     @app.get_prompt()
 1693 |     async def get_prompt(
 1694 |         name: str, arguments: dict[str, str] | None = None
 1695 |     ) -> types.GetPromptResult:
 1696 |         if name not in PROMPTS:
 1697 |             raise ValueError(f"Prompt not found: {name}")
 1698 | 
 1699 |         if name == "git-commit":
 1700 |             changes = arguments.get("changes") if arguments else ""
 1701 |             return types.GetPromptResult(
 1702 |                 messages=[
 1703 |                     types.PromptMessage(
 1704 |                         role="user",
 1705 |                         content=types.TextContent(
 1706 |                             type="text",
 1707 |                             text=f"Generate a concise but descriptive commit message "
 1708 |                             f"for these changes:\n\n{changes}"
 1709 |                         )
 1710 |                     )
 1711 |                 ]
 1712 |             )
 1713 | 
 1714 |         if name == "explain-code":
 1715 |             code = arguments.get("code") if arguments else ""
 1716 |             language = arguments.get("language", "Unknown") if arguments else "Unknown"
 1717 |             return types.GetPromptResult(
 1718 |                 messages=[
 1719 |                     types.PromptMessage(
 1720 |                         role="user",
 1721 |                         content=types.TextContent(
 1722 |                             type="text",
 1723 |                             text=f"Explain how this {language} code works:\n\n{code}"
 1724 |                         )
 1725 |                     )
 1726 |                 ]
 1727 |             )
 1728 | 
 1729 |         raise ValueError("Prompt implementation not found")
 1730 |     ```
 1731 |   </Tab>
 1732 | </Tabs>
 1733 | 
 1734 | ## Best practices
 1735 | 
 1736 | When implementing prompts:
 1737 | 
 1738 | 1. Use clear, descriptive prompt names
 1739 | 2. Provide detailed descriptions for prompts and arguments
 1740 | 3. Validate all required arguments
 1741 | 4. Handle missing arguments gracefully
 1742 | 5. Consider versioning for prompt templates
 1743 | 6. Cache dynamic content when appropriate
 1744 | 7. Implement error handling
 1745 | 8. Document expected argument formats
 1746 | 9. Consider prompt composability
 1747 | 10. Test prompts with various inputs
 1748 | 
 1749 | ## UI integration
 1750 | 
 1751 | Prompts can be surfaced in client UIs as:
 1752 | 
 1753 | * Slash commands
 1754 | * Quick actions
 1755 | * Context menu items
 1756 | * Command palette entries
 1757 | * Guided workflows
 1758 | * Interactive forms
 1759 | 
 1760 | ## Updates and changes
 1761 | 
 1762 | Servers can notify clients about prompt changes:
 1763 | 
 1764 | 1. Server capability: `prompts.listChanged`
 1765 | 2. Notification: `notifications/prompts/list_changed`
 1766 | 3. Client re-fetches prompt list
 1767 | 
 1768 | ## Security considerations
 1769 | 
 1770 | When implementing prompts:
 1771 | 
 1772 | * Validate all arguments
 1773 | * Sanitize user input
 1774 | * Consider rate limiting
 1775 | * Implement access controls
 1776 | * Audit prompt usage
 1777 | * Handle sensitive data appropriately
 1778 | * Validate generated content
 1779 | * Implement timeouts
 1780 | * Consider prompt injection risks
 1781 | * Document security requirements
 1782 | 
 1783 | 
 1784 | # Resources
 1785 | Source: https://modelcontextprotocol.io/docs/concepts/resources
 1786 | 
 1787 | Expose data and content from your servers to LLMs
 1788 | 
 1789 | Resources are a core primitive in the Model Context Protocol (MCP) that allow servers to expose data and content that can be read by clients and used as context for LLM interactions.
 1790 | 
 1791 | <Note>
 1792 |   Resources are designed to be **application-controlled**, meaning that the client application can decide how and when they should be used.
 1793 |   Different MCP clients may handle resources differently. For example:
 1794 | 
 1795 |   * Claude Desktop currently requires users to explicitly select resources before they can be used
 1796 |   * Other clients might automatically select resources based on heuristics
 1797 |   * Some implementations may even allow the AI model itself to determine which resources to use
 1798 | 
 1799 |   Server authors should be prepared to handle any of these interaction patterns when implementing resource support. In order to expose data to models automatically, server authors should use a **model-controlled** primitive such as [Tools](./tools).
 1800 | </Note>
 1801 | 
 1802 | ## Overview
 1803 | 
 1804 | Resources represent any kind of data that an MCP server wants to make available to clients. This can include:
 1805 | 
 1806 | * File contents
 1807 | * Database records
 1808 | * API responses
 1809 | * Live system data
 1810 | * Screenshots and images
 1811 | * Log files
 1812 | * And more
 1813 | 
 1814 | Each resource is identified by a unique URI and can contain either text or binary data.
 1815 | 
 1816 | ## Resource URIs
 1817 | 
 1818 | Resources are identified using URIs that follow this format:
 1819 | 
 1820 | ```
 1821 | [protocol]://[host]/[path]
 1822 | ```
 1823 | 
 1824 | For example:
 1825 | 
 1826 | * `file:///home/user/documents/report.pdf`
 1827 | * `postgres://database/customers/schema`
 1828 | * `screen://localhost/display1`
 1829 | 
 1830 | The protocol and path structure is defined by the MCP server implementation. Servers can define their own custom URI schemes.
 1831 | 
 1832 | ## Resource types
 1833 | 
 1834 | Resources can contain two types of content:
 1835 | 
 1836 | ### Text resources
 1837 | 
 1838 | Text resources contain UTF-8 encoded text data. These are suitable for:
 1839 | 
 1840 | * Source code
 1841 | * Configuration files
 1842 | * Log files
 1843 | * JSON/XML data
 1844 | * Plain text
 1845 | 
 1846 | ### Binary resources
 1847 | 
 1848 | Binary resources contain raw binary data encoded in base64. These are suitable for:
 1849 | 
 1850 | * Images
 1851 | * PDFs
 1852 | * Audio files
 1853 | * Video files
 1854 | * Other non-text formats
 1855 | 
 1856 | ## Resource discovery
 1857 | 
 1858 | Clients can discover available resources through two main methods:
 1859 | 
 1860 | ### Direct resources
 1861 | 
 1862 | Servers expose a list of resources via the `resources/list` request. Each resource includes:
 1863 | 
 1864 | ```typescript
 1865 | {
 1866 |   uri: string;           // Unique identifier for the resource
 1867 |   name: string;          // Human-readable name
 1868 |   description?: string;  // Optional description
 1869 |   mimeType?: string;     // Optional MIME type
 1870 |   size?: number;         // Optional size in bytes
 1871 | }
 1872 | ```
 1873 | 
 1874 | ### Resource templates
 1875 | 
 1876 | For dynamic resources, servers can expose [URI templates](https://datatracker.ietf.org/doc/html/rfc6570) that clients can use to construct valid resource URIs:
 1877 | 
 1878 | ```typescript
 1879 | {
 1880 |   uriTemplate: string;   // URI template following RFC 6570
 1881 |   name: string;          // Human-readable name for this type
 1882 |   description?: string;  // Optional description
 1883 |   mimeType?: string;     // Optional MIME type for all matching resources
 1884 | }
 1885 | ```
 1886 | 
 1887 | ## Reading resources
 1888 | 
 1889 | To read a resource, clients make a `resources/read` request with the resource URI.
 1890 | 
 1891 | The server responds with a list of resource contents:
 1892 | 
 1893 | ```typescript
 1894 | {
 1895 |   contents: [
 1896 |     {
 1897 |       uri: string;        // The URI of the resource
 1898 |       mimeType?: string;  // Optional MIME type
 1899 | 
 1900 |       // One of:
 1901 |       text?: string;      // For text resources
 1902 |       blob?: string;      // For binary resources (base64 encoded)
 1903 |     }
 1904 |   ]
 1905 | }
 1906 | ```
 1907 | 
 1908 | <Tip>
 1909 |   Servers may return multiple resources in response to one `resources/read` request. This could be used, for example, to return a list of files inside a directory when the directory is read.
 1910 | </Tip>
 1911 | 
 1912 | ## Resource updates
 1913 | 
 1914 | MCP supports real-time updates for resources through two mechanisms:
 1915 | 
 1916 | ### List changes
 1917 | 
 1918 | Servers can notify clients when their list of available resources changes via the `notifications/resources/list_changed` notification.
 1919 | 
 1920 | ### Content changes
 1921 | 
 1922 | Clients can subscribe to updates for specific resources:
 1923 | 
 1924 | 1. Client sends `resources/subscribe` with resource URI
 1925 | 2. Server sends `notifications/resources/updated` when the resource changes
 1926 | 3. Client can fetch latest content with `resources/read`
 1927 | 4. Client can unsubscribe with `resources/unsubscribe`
 1928 | 
 1929 | ## Example implementation
 1930 | 
 1931 | Here's a simple example of implementing resource support in an MCP server:
 1932 | 
 1933 | <Tabs>
 1934 |   <Tab title="TypeScript">
 1935 |     ```typescript
 1936 |     const server = new Server({
 1937 |       name: "example-server",
 1938 |       version: "1.0.0"
 1939 |     }, {
 1940 |       capabilities: {
 1941 |         resources: {}
 1942 |       }
 1943 |     });
 1944 | 
 1945 |     // List available resources
 1946 |     server.setRequestHandler(ListResourcesRequestSchema, async () => {
 1947 |       return {
 1948 |         resources: [
 1949 |           {
 1950 |             uri: "file:///logs/app.log",
 1951 |             name: "Application Logs",
 1952 |             mimeType: "text/plain"
 1953 |           }
 1954 |         ]
 1955 |       };
 1956 |     });
 1957 | 
 1958 |     // Read resource contents
 1959 |     server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
 1960 |       const uri = request.params.uri;
 1961 | 
 1962 |       if (uri === "file:///logs/app.log") {
 1963 |         const logContents = await readLogFile();
 1964 |         return {
 1965 |           contents: [
 1966 |             {
 1967 |               uri,
 1968 |               mimeType: "text/plain",
 1969 |               text: logContents
 1970 |             }
 1971 |           ]
 1972 |         };
 1973 |       }
 1974 | 
 1975 |       throw new Error("Resource not found");
 1976 |     });
 1977 |     ```
 1978 |   </Tab>
 1979 | 
 1980 |   <Tab title="Python">
 1981 |     ```python
 1982 |     app = Server("example-server")
 1983 | 
 1984 |     @app.list_resources()
 1985 |     async def list_resources() -> list[types.Resource]:
 1986 |         return [
 1987 |             types.Resource(
 1988 |                 uri="file:///logs/app.log",
 1989 |                 name="Application Logs",
 1990 |                 mimeType="text/plain"
 1991 |             )
 1992 |         ]
 1993 | 
 1994 |     @app.read_resource()
 1995 |     async def read_resource(uri: AnyUrl) -> str:
 1996 |         if str(uri) == "file:///logs/app.log":
 1997 |             log_contents = await read_log_file()
 1998 |             return log_contents
 1999 | 
 2000 |         raise ValueError("Resource not found")
 2001 | 
 2002 |     # Start server
 2003 |     async with stdio_server() as streams:
 2004 |         await app.run(
 2005 |             streams[0],
 2006 |             streams[1],
 2007 |             app.create_initialization_options()
 2008 |         )
 2009 |     ```
 2010 |   </Tab>
 2011 | </Tabs>
 2012 | 
 2013 | ## Best practices
 2014 | 
 2015 | When implementing resource support:
 2016 | 
 2017 | 1. Use clear, descriptive resource names and URIs
 2018 | 2. Include helpful descriptions to guide LLM understanding
 2019 | 3. Set appropriate MIME types when known
 2020 | 4. Implement resource templates for dynamic content
 2021 | 5. Use subscriptions for frequently changing resources
 2022 | 6. Handle errors gracefully with clear error messages
 2023 | 7. Consider pagination for large resource lists
 2024 | 8. Cache resource contents when appropriate
 2025 | 9. Validate URIs before processing
 2026 | 10. Document your custom URI schemes
 2027 | 
 2028 | ## Security considerations
 2029 | 
 2030 | When exposing resources:
 2031 | 
 2032 | * Validate all resource URIs
 2033 | * Implement appropriate access controls
 2034 | * Sanitize file paths to prevent directory traversal
 2035 | * Be cautious with binary data handling
 2036 | * Consider rate limiting for resource reads
 2037 | * Audit resource access
 2038 | * Encrypt sensitive data in transit
 2039 | * Validate MIME types
 2040 | * Implement timeouts for long-running reads
 2041 | * Handle resource cleanup appropriately
 2042 | 
 2043 | 
 2044 | # Roots
 2045 | Source: https://modelcontextprotocol.io/docs/concepts/roots
 2046 | 
 2047 | Understanding roots in MCP
 2048 | 
 2049 | Roots are a concept in MCP that define the boundaries where servers can operate. They provide a way for clients to inform servers about relevant resources and their locations.
 2050 | 
 2051 | ## What are Roots?
 2052 | 
 2053 | A root is a URI that a client suggests a server should focus on. When a client connects to a server, it declares which roots the server should work with. While primarily used for filesystem paths, roots can be any valid URI including HTTP URLs.
 2054 | 
 2055 | For example, roots could be:
 2056 | 
 2057 | ```
 2058 | file:///home/user/projects/myapp
 2059 | https://api.example.com/v1
 2060 | ```
 2061 | 
 2062 | ## Why Use Roots?
 2063 | 
 2064 | Roots serve several important purposes:
 2065 | 
 2066 | 1. **Guidance**: They inform servers about relevant resources and locations
 2067 | 2. **Clarity**: Roots make it clear which resources are part of your workspace
 2068 | 3. **Organization**: Multiple roots let you work with different resources simultaneously
 2069 | 
 2070 | ## How Roots Work
 2071 | 
 2072 | When a client supports roots, it:
 2073 | 
 2074 | 1. Declares the `roots` capability during connection
 2075 | 2. Provides a list of suggested roots to the server
 2076 | 3. Notifies the server when roots change (if supported)
 2077 | 
 2078 | While roots are informational and not strictly enforcing, servers should:
 2079 | 
 2080 | 1. Respect the provided roots
 2081 | 2. Use root URIs to locate and access resources
 2082 | 3. Prioritize operations within root boundaries
 2083 | 
 2084 | ## Common Use Cases
 2085 | 
 2086 | Roots are commonly used to define:
 2087 | 
 2088 | * Project directories
 2089 | * Repository locations
 2090 | * API endpoints
 2091 | * Configuration locations
 2092 | * Resource boundaries
 2093 | 
 2094 | ## Best Practices
 2095 | 
 2096 | When working with roots:
 2097 | 
 2098 | 1. Only suggest necessary resources
 2099 | 2. Use clear, descriptive names for roots
 2100 | 3. Monitor root accessibility
 2101 | 4. Handle root changes gracefully
 2102 | 
 2103 | ## Example
 2104 | 
 2105 | Here's how a typical MCP client might expose roots:
 2106 | 
 2107 | ```json
 2108 | {
 2109 |   "roots": [
 2110 |     {
 2111 |       "uri": "file:///home/user/projects/frontend",
 2112 |       "name": "Frontend Repository"
 2113 |     },
 2114 |     {
 2115 |       "uri": "https://api.example.com/v1",
 2116 |       "name": "API Endpoint"
 2117 |     }
 2118 |   ]
 2119 | }
 2120 | ```
 2121 | 
 2122 | This configuration suggests the server focus on both a local repository and an API endpoint while keeping them logically separated.
 2123 | 
 2124 | 
 2125 | # Sampling
 2126 | Source: https://modelcontextprotocol.io/docs/concepts/sampling
 2127 | 
 2128 | Let your servers request completions from LLMs
 2129 | 
 2130 | Sampling is a powerful MCP feature that allows servers to request LLM completions through the client, enabling sophisticated agentic behaviors while maintaining security and privacy.
 2131 | 
 2132 | <Info>
 2133 |   This feature of MCP is not yet supported in the Claude Desktop client.
 2134 | </Info>
 2135 | 
 2136 | ## How sampling works
 2137 | 
 2138 | The sampling flow follows these steps:
 2139 | 
 2140 | 1. Server sends a `sampling/createMessage` request to the client
 2141 | 2. Client reviews the request and can modify it
 2142 | 3. Client samples from an LLM
 2143 | 4. Client reviews the completion
 2144 | 5. Client returns the result to the server
 2145 | 
 2146 | This human-in-the-loop design ensures users maintain control over what the LLM sees and generates.
 2147 | 
 2148 | ## Message format
 2149 | 
 2150 | Sampling requests use a standardized message format:
 2151 | 
 2152 | ```typescript
 2153 | {
 2154 |   messages: [
 2155 |     {
 2156 |       role: "user" | "assistant",
 2157 |       content: {
 2158 |         type: "text" | "image",
 2159 | 
 2160 |         // For text:
 2161 |         text?: string,
 2162 | 
 2163 |         // For images:
 2164 |         data?: string,             // base64 encoded
 2165 |         mimeType?: string
 2166 |       }
 2167 |     }
 2168 |   ],
 2169 |   modelPreferences?: {
 2170 |     hints?: [{
 2171 |       name?: string                // Suggested model name/family
 2172 |     }],
 2173 |     costPriority?: number,         // 0-1, importance of minimizing cost
 2174 |     speedPriority?: number,        // 0-1, importance of low latency
 2175 |     intelligencePriority?: number  // 0-1, importance of capabilities
 2176 |   },
 2177 |   systemPrompt?: string,
 2178 |   includeContext?: "none" | "thisServer" | "allServers",
 2179 |   temperature?: number,
 2180 |   maxTokens: number,
 2181 |   stopSequences?: string[],
 2182 |   metadata?: Record<string, unknown>
 2183 | }
 2184 | ```
 2185 | 
 2186 | ## Request parameters
 2187 | 
 2188 | ### Messages
 2189 | 
 2190 | The `messages` array contains the conversation history to send to the LLM. Each message has:
 2191 | 
 2192 | * `role`: Either "user" or "assistant"
 2193 | * `content`: The message content, which can be:
 2194 |   * Text content with a `text` field
 2195 |   * Image content with `data` (base64) and `mimeType` fields
 2196 | 
 2197 | ### Model preferences
 2198 | 
 2199 | The `modelPreferences` object allows servers to specify their model selection preferences:
 2200 | 
 2201 | * `hints`: Array of model name suggestions that clients can use to select an appropriate model:
 2202 | 
 2203 |   * `name`: String that can match full or partial model names (e.g. "claude-3", "sonnet")
 2204 |   * Clients may map hints to equivalent models from different providers
 2205 |   * Multiple hints are evaluated in preference order
 2206 | 
 2207 | * Priority values (0-1 normalized):
 2208 |   * `costPriority`: Importance of minimizing costs
 2209 |   * `speedPriority`: Importance of low latency response
 2210 |   * `intelligencePriority`: Importance of advanced model capabilities
 2211 | 
 2212 | Clients make the final model selection based on these preferences and their available models.
 2213 | 
 2214 | ### System prompt
 2215 | 
 2216 | An optional `systemPrompt` field allows servers to request a specific system prompt. The client may modify or ignore this.
 2217 | 
 2218 | ### Context inclusion
 2219 | 
 2220 | The `includeContext` parameter specifies what MCP context to include:
 2221 | 
 2222 | * `"none"`: No additional context
 2223 | * `"thisServer"`: Include context from the requesting server
 2224 | * `"allServers"`: Include context from all connected MCP servers
 2225 | 
 2226 | The client controls what context is actually included.
 2227 | 
 2228 | ### Sampling parameters
 2229 | 
 2230 | Fine-tune the LLM sampling with:
 2231 | 
 2232 | * `temperature`: Controls randomness (0.0 to 1.0)
 2233 | * `maxTokens`: Maximum tokens to generate
 2234 | * `stopSequences`: Array of sequences that stop generation
 2235 | * `metadata`: Additional provider-specific parameters
 2236 | 
 2237 | ## Response format
 2238 | 
 2239 | The client returns a completion result:
 2240 | 
 2241 | ```typescript
 2242 | {
 2243 |   model: string,  // Name of the model used
 2244 |   stopReason?: "endTurn" | "stopSequence" | "maxTokens" | string,
 2245 |   role: "user" | "assistant",
 2246 |   content: {
 2247 |     type: "text" | "image",
 2248 |     text?: string,
 2249 |     data?: string,
 2250 |     mimeType?: string
 2251 |   }
 2252 | }
 2253 | ```
 2254 | 
 2255 | ## Example request
 2256 | 
 2257 | Here's an example of requesting sampling from a client:
 2258 | 
 2259 | ```json
 2260 | {
 2261 |   "method": "sampling/createMessage",
 2262 |   "params": {
 2263 |     "messages": [
 2264 |       {
 2265 |         "role": "user",
 2266 |         "content": {
 2267 |           "type": "text",
 2268 |           "text": "What files are in the current directory?"
 2269 |         }
 2270 |       }
 2271 |     ],
 2272 |     "systemPrompt": "You are a helpful file system assistant.",
 2273 |     "includeContext": "thisServer",
 2274 |     "maxTokens": 100
 2275 |   }
 2276 | }
 2277 | ```
 2278 | 
 2279 | ## Best practices
 2280 | 
 2281 | When implementing sampling:
 2282 | 
 2283 | 1. Always provide clear, well-structured prompts
 2284 | 2. Handle both text and image content appropriately
 2285 | 3. Set reasonable token limits
 2286 | 4. Include relevant context through `includeContext`
 2287 | 5. Validate responses before using them
 2288 | 6. Handle errors gracefully
 2289 | 7. Consider rate limiting sampling requests
 2290 | 8. Document expected sampling behavior
 2291 | 9. Test with various model parameters
 2292 | 10. Monitor sampling costs
 2293 | 
 2294 | ## Human in the loop controls
 2295 | 
 2296 | Sampling is designed with human oversight in mind:
 2297 | 
 2298 | ### For prompts
 2299 | 
 2300 | * Clients should show users the proposed prompt
 2301 | * Users should be able to modify or reject prompts
 2302 | * System prompts can be filtered or modified
 2303 | * Context inclusion is controlled by the client
 2304 | 
 2305 | ### For completions
 2306 | 
 2307 | * Clients should show users the completion
 2308 | * Users should be able to modify or reject completions
 2309 | * Clients can filter or modify completions
 2310 | * Users control which model is used
 2311 | 
 2312 | ## Security considerations
 2313 | 
 2314 | When implementing sampling:
 2315 | 
 2316 | * Validate all message content
 2317 | * Sanitize sensitive information
 2318 | * Implement appropriate rate limits
 2319 | * Monitor sampling usage
 2320 | * Encrypt data in transit
 2321 | * Handle user data privacy
 2322 | * Audit sampling requests
 2323 | * Control cost exposure
 2324 | * Implement timeouts
 2325 | * Handle model errors gracefully
 2326 | 
 2327 | ## Common patterns
 2328 | 
 2329 | ### Agentic workflows
 2330 | 
 2331 | Sampling enables agentic patterns like:
 2332 | 
 2333 | * Reading and analyzing resources
 2334 | * Making decisions based on context
 2335 | * Generating structured data
 2336 | * Handling multi-step tasks
 2337 | * Providing interactive assistance
 2338 | 
 2339 | ### Context management
 2340 | 
 2341 | Best practices for context:
 2342 | 
 2343 | * Request minimal necessary context
 2344 | * Structure context clearly
 2345 | * Handle context size limits
 2346 | * Update context as needed
 2347 | * Clean up stale context
 2348 | 
 2349 | ### Error handling
 2350 | 
 2351 | Robust error handling should:
 2352 | 
 2353 | * Catch sampling failures
 2354 | * Handle timeout errors
 2355 | * Manage rate limits
 2356 | * Validate responses
 2357 | * Provide fallback behaviors
 2358 | * Log errors appropriately
 2359 | 
 2360 | ## Limitations
 2361 | 
 2362 | Be aware of these limitations:
 2363 | 
 2364 | * Sampling depends on client capabilities
 2365 | * Users control sampling behavior
 2366 | * Context size has limits
 2367 | * Rate limits may apply
 2368 | * Costs should be considered
 2369 | * Model availability varies
 2370 | * Response times vary
 2371 | * Not all content types supported
 2372 | 
 2373 | 
 2374 | # Tools
 2375 | Source: https://modelcontextprotocol.io/docs/concepts/tools
 2376 | 
 2377 | Enable LLMs to perform actions through your server
 2378 | 
 2379 | Tools are a powerful primitive in the Model Context Protocol (MCP) that enable servers to expose executable functionality to clients. Through tools, LLMs can interact with external systems, perform computations, and take actions in the real world.
 2380 | 
 2381 | <Note>
 2382 |   Tools are designed to be **model-controlled**, meaning that tools are exposed from servers to clients with the intention of the AI model being able to automatically invoke them (with a human in the loop to grant approval).
 2383 | </Note>
 2384 | 
 2385 | ## Overview
 2386 | 
 2387 | Tools in MCP allow servers to expose executable functions that can be invoked by clients and used by LLMs to perform actions. Key aspects of tools include:
 2388 | 
 2389 | * **Discovery**: Clients can obtain a list of available tools by sending a `tools/list` request
 2390 | * **Invocation**: Tools are called using the `tools/call` request, where servers perform the requested operation and return results
 2391 | * **Flexibility**: Tools can range from simple calculations to complex API interactions
 2392 | 
 2393 | Like [resources](/docs/concepts/resources), tools are identified by unique names and can include descriptions to guide their usage. However, unlike resources, tools represent dynamic operations that can modify state or interact with external systems.
 2394 | 
 2395 | ## Tool definition structure
 2396 | 
 2397 | Each tool is defined with the following structure:
 2398 | 
 2399 | ```typescript
 2400 | {
 2401 |   name: string;          // Unique identifier for the tool
 2402 |   description?: string;  // Human-readable description
 2403 |   inputSchema: {         // JSON Schema for the tool's parameters
 2404 |     type: "object",
 2405 |     properties: { ... }  // Tool-specific parameters
 2406 |   },
 2407 |   annotations?: {        // Optional hints about tool behavior
 2408 |     title?: string;      // Human-readable title for the tool
 2409 |     readOnlyHint?: boolean;    // If true, the tool does not modify its environment
 2410 |     destructiveHint?: boolean; // If true, the tool may perform destructive updates
 2411 |     idempotentHint?: boolean;  // If true, repeated calls with same args have no additional effect
 2412 |     openWorldHint?: boolean;   // If true, tool interacts with external entities
 2413 |   }
 2414 | }
 2415 | ```
 2416 | 
 2417 | ## Implementing tools
 2418 | 
 2419 | Here's an example of implementing a basic tool in an MCP server:
 2420 | 
 2421 | <Tabs>
 2422 |   <Tab title="TypeScript">
 2423 |     ```typescript
 2424 |     const server = new Server({
 2425 |       name: "example-server",
 2426 |       version: "1.0.0"
 2427 |     }, {
 2428 |       capabilities: {
 2429 |         tools: {}
 2430 |       }
 2431 |     });
 2432 | 
 2433 |     // Define available tools
 2434 |     server.setRequestHandler(ListToolsRequestSchema, async () => {
 2435 |       return {
 2436 |         tools: [{
 2437 |           name: "calculate_sum",
 2438 |           description: "Add two numbers together",
 2439 |           inputSchema: {
 2440 |             type: "object",
 2441 |             properties: {
 2442 |               a: { type: "number" },
 2443 |               b: { type: "number" }
 2444 |             },
 2445 |             required: ["a", "b"]
 2446 |           }
 2447 |         }]
 2448 |       };
 2449 |     });
 2450 | 
 2451 |     // Handle tool execution
 2452 |     server.setRequestHandler(CallToolRequestSchema, async (request) => {
 2453 |       if (request.params.name === "calculate_sum") {
 2454 |         const { a, b } = request.params.arguments;
 2455 |         return {
 2456 |           content: [
 2457 |             {
 2458 |               type: "text",
 2459 |               text: String(a + b)
 2460 |             }
 2461 |           ]
 2462 |         };
 2463 |       }
 2464 |       throw new Error("Tool not found");
 2465 |     });
 2466 |     ```
 2467 |   </Tab>
 2468 | 
 2469 |   <Tab title="Python">
 2470 |     ```python
 2471 |     app = Server("example-server")
 2472 | 
 2473 |     @app.list_tools()
 2474 |     async def list_tools() -> list[types.Tool]:
 2475 |         return [
 2476 |             types.Tool(
 2477 |                 name="calculate_sum",
 2478 |                 description="Add two numbers together",
 2479 |                 inputSchema={
 2480 |                     "type": "object",
 2481 |                     "properties": {
 2482 |                         "a": {"type": "number"},
 2483 |                         "b": {"type": "number"}
 2484 |                     },
 2485 |                     "required": ["a", "b"]
 2486 |                 }
 2487 |             )
 2488 |         ]
 2489 | 
 2490 |     @app.call_tool()
 2491 |     async def call_tool(
 2492 |         name: str,
 2493 |         arguments: dict
 2494 |     ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
 2495 |         if name == "calculate_sum":
 2496 |             a = arguments["a"]
 2497 |             b = arguments["b"]
 2498 |             result = a + b
 2499 |             return [types.TextContent(type="text", text=str(result))]
 2500 |         raise ValueError(f"Tool not found: {name}")
 2501 |     ```
 2502 |   </Tab>
 2503 | </Tabs>
 2504 | 
 2505 | ## Example tool patterns
 2506 | 
 2507 | Here are some examples of types of tools that a server could provide:
 2508 | 
 2509 | ### System operations
 2510 | 
 2511 | Tools that interact with the local system:
 2512 | 
 2513 | ```typescript
 2514 | {
 2515 |   name: "execute_command",
 2516 |   description: "Run a shell command",
 2517 |   inputSchema: {
 2518 |     type: "object",
 2519 |     properties: {
 2520 |       command: { type: "string" },
 2521 |       args: { type: "array", items: { type: "string" } }
 2522 |     }
 2523 |   }
 2524 | }
 2525 | ```
 2526 | 
 2527 | ### API integrations
 2528 | 
 2529 | Tools that wrap external APIs:
 2530 | 
 2531 | ```typescript
 2532 | {
 2533 |   name: "github_create_issue",
 2534 |   description: "Create a GitHub issue",
 2535 |   inputSchema: {
 2536 |     type: "object",
 2537 |     properties: {
 2538 |       title: { type: "string" },
 2539 |       body: { type: "string" },
 2540 |       labels: { type: "array", items: { type: "string" } }
 2541 |     }
 2542 |   }
 2543 | }
 2544 | ```
 2545 | 
 2546 | ### Data processing
 2547 | 
 2548 | Tools that transform or analyze data:
 2549 | 
 2550 | ```typescript
 2551 | {
 2552 |   name: "analyze_csv",
 2553 |   description: "Analyze a CSV file",
 2554 |   inputSchema: {
 2555 |     type: "object",
 2556 |     properties: {
 2557 |       filepath: { type: "string" },
 2558 |       operations: {
 2559 |         type: "array",
 2560 |         items: {
 2561 |           enum: ["sum", "average", "count"]
 2562 |         }
 2563 |       }
 2564 |     }
 2565 |   }
 2566 | }
 2567 | ```
 2568 | 
 2569 | ## Best practices
 2570 | 
 2571 | When implementing tools:
 2572 | 
 2573 | 1. Provide clear, descriptive names and descriptions
 2574 | 2. Use detailed JSON Schema definitions for parameters
 2575 | 3. Include examples in tool descriptions to demonstrate how the model should use them
 2576 | 4. Implement proper error handling and validation
 2577 | 5. Use progress reporting for long operations
 2578 | 6. Keep tool operations focused and atomic
 2579 | 7. Document expected return value structures
 2580 | 8. Implement proper timeouts
 2581 | 9. Consider rate limiting for resource-intensive operations
 2582 | 10. Log tool usage for debugging and monitoring
 2583 | 
 2584 | ## Security considerations
 2585 | 
 2586 | When exposing tools:
 2587 | 
 2588 | ### Input validation
 2589 | 
 2590 | * Validate all parameters against the schema
 2591 | * Sanitize file paths and system commands
 2592 | * Validate URLs and external identifiers
 2593 | * Check parameter sizes and ranges
 2594 | * Prevent command injection
 2595 | 
 2596 | ### Access control
 2597 | 
 2598 | * Implement authentication where needed
 2599 | * Use appropriate authorization checks
 2600 | * Audit tool usage
 2601 | * Rate limit requests
 2602 | * Monitor for abuse
 2603 | 
 2604 | ### Error handling
 2605 | 
 2606 | * Don't expose internal errors to clients
 2607 | * Log security-relevant errors
 2608 | * Handle timeouts appropriately
 2609 | * Clean up resources after errors
 2610 | * Validate return values
 2611 | 
 2612 | ## Tool discovery and updates
 2613 | 
 2614 | MCP supports dynamic tool discovery:
 2615 | 
 2616 | 1. Clients can list available tools at any time
 2617 | 2. Servers can notify clients when tools change using `notifications/tools/list_changed`
 2618 | 3. Tools can be added or removed during runtime
 2619 | 4. Tool definitions can be updated (though this should be done carefully)
 2620 | 
 2621 | ## Error handling
 2622 | 
 2623 | Tool errors should be reported within the result object, not as MCP protocol-level errors. This allows the LLM to see and potentially handle the error. When a tool encounters an error:
 2624 | 
 2625 | 1. Set `isError` to `true` in the result
 2626 | 2. Include error details in the `content` array
 2627 | 
 2628 | Here's an example of proper error handling for tools:
 2629 | 
 2630 | <Tabs>
 2631 |   <Tab title="TypeScript">
 2632 |     ```typescript
 2633 |     try {
 2634 |       // Tool operation
 2635 |       const result = performOperation();
 2636 |       return {
 2637 |         content: [
 2638 |           {
 2639 |             type: "text",
 2640 |             text: `Operation successful: ${result}`
 2641 |           }
 2642 |         ]
 2643 |       };
 2644 |     } catch (error) {
 2645 |       return {
 2646 |         isError: true,
 2647 |         content: [
 2648 |           {
 2649 |             type: "text",
 2650 |             text: `Error: ${error.message}`
 2651 |           }
 2652 |         ]
 2653 |       };
 2654 |     }
 2655 |     ```
 2656 |   </Tab>
 2657 | 
 2658 |   <Tab title="Python">
 2659 |     ```python
 2660 |     try:
 2661 |         # Tool operation
 2662 |         result = perform_operation()
 2663 |         return types.CallToolResult(
 2664 |             content=[
 2665 |                 types.TextContent(
 2666 |                     type="text",
 2667 |                     text=f"Operation successful: {result}"
 2668 |                 )
 2669 |             ]
 2670 |         )
 2671 |     except Exception as error:
 2672 |         return types.CallToolResult(
 2673 |             isError=True,
 2674 |             content=[
 2675 |                 types.TextContent(
 2676 |                     type="text",
 2677 |                     text=f"Error: {str(error)}"
 2678 |                 )
 2679 |             ]
 2680 |         )
 2681 |     ```
 2682 |   </Tab>
 2683 | </Tabs>
 2684 | 
 2685 | This approach allows the LLM to see that an error occurred and potentially take corrective action or request human intervention.
 2686 | 
 2687 | ## Tool annotations
 2688 | 
 2689 | Tool annotations provide additional metadata about a tool's behavior, helping clients understand how to present and manage tools. These annotations are hints that describe the nature and impact of a tool, but should not be relied upon for security decisions.
 2690 | 
 2691 | ### Purpose of tool annotations
 2692 | 
 2693 | Tool annotations serve several key purposes:
 2694 | 
 2695 | 1. Provide UX-specific information without affecting model context
 2696 | 2. Help clients categorize and present tools appropriately
 2697 | 3. Convey information about a tool's potential side effects
 2698 | 4. Assist in developing intuitive interfaces for tool approval
 2699 | 
 2700 | ### Available tool annotations
 2701 | 
 2702 | The MCP specification defines the following annotations for tools:
 2703 | 
 2704 | | Annotation        | Type    | Default | Description                                                                                                                          |
 2705 | | ----------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
 2706 | | `title`           | string  | -       | A human-readable title for the tool, useful for UI display                                                                           |
 2707 | | `readOnlyHint`    | boolean | false   | If true, indicates the tool does not modify its environment                                                                          |
 2708 | | `destructiveHint` | boolean | true    | If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false)                                     |
 2709 | | `idempotentHint`  | boolean | false   | If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false) |
 2710 | | `openWorldHint`   | boolean | true    | If true, the tool may interact with an "open world" of external entities                                                             |
 2711 | 
 2712 | ### Example usage
 2713 | 
 2714 | Here's how to define tools with annotations for different scenarios:
 2715 | 
 2716 | ```typescript
 2717 | // A read-only search tool
 2718 | {
 2719 |   name: "web_search",
 2720 |   description: "Search the web for information",
 2721 |   inputSchema: {
 2722 |     type: "object",
 2723 |     properties: {
 2724 |       query: { type: "string" }
 2725 |     },
 2726 |     required: ["query"]
 2727 |   },
 2728 |   annotations: {
 2729 |     title: "Web Search",
 2730 |     readOnlyHint: true,
 2731 |     openWorldHint: true
 2732 |   }
 2733 | }
 2734 | 
 2735 | // A destructive file deletion tool
 2736 | {
 2737 |   name: "delete_file",
 2738 |   description: "Delete a file from the filesystem",
 2739 |   inputSchema: {
 2740 |     type: "object",
 2741 |     properties: {
 2742 |       path: { type: "string" }
 2743 |     },
 2744 |     required: ["path"]
 2745 |   },
 2746 |   annotations: {
 2747 |     title: "Delete File",
 2748 |     readOnlyHint: false,
 2749 |     destructiveHint: true,
 2750 |     idempotentHint: true,
 2751 |     openWorldHint: false
 2752 |   }
 2753 | }
 2754 | 
 2755 | // A non-destructive database record creation tool
 2756 | {
 2757 |   name: "create_record",
 2758 |   description: "Create a new record in the database",
 2759 |   inputSchema: {
 2760 |     type: "object",
 2761 |     properties: {
 2762 |       table: { type: "string" },
 2763 |       data: { type: "object" }
 2764 |     },
 2765 |     required: ["table", "data"]
 2766 |   },
 2767 |   annotations: {
 2768 |     title: "Create Database Record",
 2769 |     readOnlyHint: false,
 2770 |     destructiveHint: false,
 2771 |     idempotentHint: false,
 2772 |     openWorldHint: false
 2773 |   }
 2774 | }
 2775 | ```
 2776 | 
 2777 | ### Integrating annotations in server implementation
 2778 | 
 2779 | <Tabs>
 2780 |   <Tab title="TypeScript">
 2781 |     ```typescript
 2782 |     server.setRequestHandler(ListToolsRequestSchema, async () => {
 2783 |       return {
 2784 |         tools: [{
 2785 |           name: "calculate_sum",
 2786 |           description: "Add two numbers together",
 2787 |           inputSchema: {
 2788 |             type: "object",
 2789 |             properties: {
 2790 |               a: { type: "number" },
 2791 |               b: { type: "number" }
 2792 |             },
 2793 |             required: ["a", "b"]
 2794 |           },
 2795 |           annotations: {
 2796 |             title: "Calculate Sum",
 2797 |             readOnlyHint: true,
 2798 |             openWorldHint: false
 2799 |           }
 2800 |         }]
 2801 |       };
 2802 |     });
 2803 |     ```
 2804 |   </Tab>
 2805 | 
 2806 |   <Tab title="Python">
 2807 |     ```python
 2808 |     from mcp.server.fastmcp import FastMCP
 2809 | 
 2810 |     mcp = FastMCP("example-server")
 2811 | 
 2812 |     @mcp.tool(
 2813 |         annotations={
 2814 |             "title": "Calculate Sum",
 2815 |             "readOnlyHint": True,
 2816 |             "openWorldHint": False
 2817 |         }
 2818 |     )
 2819 |     async def calculate_sum(a: float, b: float) -> str:
 2820 |         """Add two numbers together.
 2821 | 
 2822 |         Args:
 2823 |             a: First number to add
 2824 |             b: Second number to add
 2825 |         """
 2826 |         result = a + b
 2827 |         return str(result)
 2828 |     ```
 2829 |   </Tab>
 2830 | </Tabs>
 2831 | 
 2832 | ### Best practices for tool annotations
 2833 | 
 2834 | 1. **Be accurate about side effects**: Clearly indicate whether a tool modifies its environment and whether those modifications are destructive.
 2835 | 
 2836 | 2. **Use descriptive titles**: Provide human-friendly titles that clearly describe the tool's purpose.
 2837 | 
 2838 | 3. **Indicate idempotency properly**: Mark tools as idempotent only if repeated calls with the same arguments truly have no additional effect.
 2839 | 
 2840 | 4. **Set appropriate open/closed world hints**: Indicate whether a tool interacts with a closed system (like a database) or an open system (like the web).
 2841 | 
 2842 | 5. **Remember annotations are hints**: All properties in ToolAnnotations are hints and not guaranteed to provide a faithful description of tool behavior. Clients should never make security-critical decisions based solely on annotations.
 2843 | 
 2844 | ## Testing tools
 2845 | 
 2846 | A comprehensive testing strategy for MCP tools should cover:
 2847 | 
 2848 | * **Functional testing**: Verify tools execute correctly with valid inputs and handle invalid inputs appropriately
 2849 | * **Integration testing**: Test tool interaction with external systems using both real and mocked dependencies
 2850 | * **Security testing**: Validate authentication, authorization, input sanitization, and rate limiting
 2851 | * **Performance testing**: Check behavior under load, timeout handling, and resource cleanup
 2852 | * **Error handling**: Ensure tools properly report errors through the MCP protocol and clean up resources
 2853 | 
 2854 | 
 2855 | # Transports
 2856 | Source: https://modelcontextprotocol.io/docs/concepts/transports
 2857 | 
 2858 | Learn about MCP's communication mechanisms
 2859 | 
 2860 | Transports in the Model Context Protocol (MCP) provide the foundation for communication between clients and servers. A transport handles the underlying mechanics of how messages are sent and received.
 2861 | 
 2862 | ## Message Format
 2863 | 
 2864 | MCP uses [JSON-RPC](https://www.jsonrpc.org/) 2.0 as its wire format. The transport layer is responsible for converting MCP protocol messages into JSON-RPC format for transmission and converting received JSON-RPC messages back into MCP protocol messages.
 2865 | 
 2866 | There are three types of JSON-RPC messages used:
 2867 | 
 2868 | ### Requests
 2869 | 
 2870 | ```typescript
 2871 | {
 2872 |   jsonrpc: "2.0",
 2873 |   id: number | string,
 2874 |   method: string,
 2875 |   params?: object
 2876 | }
 2877 | ```
 2878 | 
 2879 | ### Responses
 2880 | 
 2881 | ```typescript
 2882 | {
 2883 |   jsonrpc: "2.0",
 2884 |   id: number | string,
 2885 |   result?: object,
 2886 |   error?: {
 2887 |     code: number,
 2888 |     message: string,
 2889 |     data?: unknown
 2890 |   }
 2891 | }
 2892 | ```
 2893 | 
 2894 | ### Notifications
 2895 | 
 2896 | ```typescript
 2897 | {
 2898 |   jsonrpc: "2.0",
 2899 |   method: string,
 2900 |   params?: object
 2901 | }
 2902 | ```
 2903 | 
 2904 | ## Built-in Transport Types
 2905 | 
 2906 | MCP currently defines two standard transport mechanisms:
 2907 | 
 2908 | ### Standard Input/Output (stdio)
 2909 | 
 2910 | The stdio transport enables communication through standard input and output streams. This is particularly useful for local integrations and command-line tools.
 2911 | 
 2912 | Use stdio when:
 2913 | 
 2914 | * Building command-line tools
 2915 | * Implementing local integrations
 2916 | * Needing simple process communication
 2917 | * Working with shell scripts
 2918 | 
 2919 | <Tabs>
 2920 |   <Tab title="TypeScript (Server)">
 2921 |     ```typescript
 2922 |     const server = new Server({
 2923 |       name: "example-server",
 2924 |       version: "1.0.0"
 2925 |     }, {
 2926 |       capabilities: {}
 2927 |     });
 2928 | 
 2929 |     const transport = new StdioServerTransport();
 2930 |     await server.connect(transport);
 2931 |     ```
 2932 |   </Tab>
 2933 | 
 2934 |   <Tab title="TypeScript (Client)">
 2935 |     ```typescript
 2936 |     const client = new Client({
 2937 |       name: "example-client",
 2938 |       version: "1.0.0"
 2939 |     }, {
 2940 |       capabilities: {}
 2941 |     });
 2942 | 
 2943 |     const transport = new StdioClientTransport({
 2944 |       command: "./server",
 2945 |       args: ["--option", "value"]
 2946 |     });
 2947 |     await client.connect(transport);
 2948 |     ```
 2949 |   </Tab>
 2950 | 
 2951 |   <Tab title="Python (Server)">
 2952 |     ```python
 2953 |     app = Server("example-server")
 2954 | 
 2955 |     async with stdio_server() as streams:
 2956 |         await app.run(
 2957 |             streams[0],
 2958 |             streams[1],
 2959 |             app.create_initialization_options()
 2960 |         )
 2961 |     ```
 2962 |   </Tab>
 2963 | 
 2964 |   <Tab title="Python (Client)">
 2965 |     ```python
 2966 |     params = StdioServerParameters(
 2967 |         command="./server",
 2968 |         args=["--option", "value"]
 2969 |     )
 2970 | 
 2971 |     async with stdio_client(params) as streams:
 2972 |         async with ClientSession(streams[0], streams[1]) as session:
 2973 |             await session.initialize()
 2974 |     ```
 2975 |   </Tab>
 2976 | </Tabs>
 2977 | 
 2978 | ### Streamable HTTP
 2979 | 
 2980 | The Streamable HTTP transport uses HTTP POST requests for client-to-server communication and optional Server-Sent Events (SSE) streams for server-to-client communication.
 2981 | 
 2982 | Use Streamable HTTP when:
 2983 | 
 2984 | * Building web-based integrations
 2985 | * Needing client-server communication over HTTP
 2986 | * Requiring stateful sessions
 2987 | * Supporting multiple concurrent clients
 2988 | * Implementing resumable connections
 2989 | 
 2990 | #### How it Works
 2991 | 
 2992 | 1. **Client-to-Server Communication**: Every JSON-RPC message from client to server is sent as a new HTTP POST request to the MCP endpoint
 2993 | 2. **Server Responses**: The server can respond either with:
 2994 |    * A single JSON response (`Content-Type: application/json`)
 2995 |    * An SSE stream (`Content-Type: text/event-stream`) for multiple messages
 2996 | 3. **Server-to-Client Communication**: Servers can send requests/notifications to clients via:
 2997 |    * SSE streams initiated by client requests
 2998 |    * SSE streams from HTTP GET requests to the MCP endpoint
 2999 | 
 3000 | <Tabs>
 3001 |   <Tab title="TypeScript (Server)">
 3002 |     ```typescript
 3003 |     import express from "express";
 3004 | 
 3005 |     const app = express();
 3006 | 
 3007 |     const server = new Server({
 3008 |       name: "example-server",
 3009 |       version: "1.0.0"
 3010 |     }, {
 3011 |       capabilities: {}
 3012 |     });
 3013 | 
 3014 |     // MCP endpoint handles both POST and GET
 3015 |     app.post("/mcp", async (req, res) => {
 3016 |       // Handle JSON-RPC request
 3017 |       const response = await server.handleRequest(req.body);
 3018 | 
 3019 |       // Return single response or SSE stream
 3020 |       if (needsStreaming) {
 3021 |         res.setHeader("Content-Type", "text/event-stream");
 3022 |         // Send SSE events...
 3023 |       } else {
 3024 |         res.json(response);
 3025 |       }
 3026 |     });
 3027 | 
 3028 |     app.get("/mcp", (req, res) => {
 3029 |       // Optional: Support server-initiated SSE streams
 3030 |       res.setHeader("Content-Type", "text/event-stream");
 3031 |       // Send server notifications/requests...
 3032 |     });
 3033 | 
 3034 |     app.listen(3000);
 3035 |     ```
 3036 |   </Tab>
 3037 | 
 3038 |   <Tab title="TypeScript (Client)">
 3039 |     ```typescript
 3040 |     const client = new Client({
 3041 |       name: "example-client",
 3042 |       version: "1.0.0"
 3043 |     }, {
 3044 |       capabilities: {}
 3045 |     });
 3046 | 
 3047 |     const transport = new HttpClientTransport(
 3048 |       new URL("http://localhost:3000/mcp")
 3049 |     );
 3050 |     await client.connect(transport);
 3051 |     ```
 3052 |   </Tab>
 3053 | 
 3054 |   <Tab title="Python (Server)">
 3055 |     ```python
 3056 |     from mcp.server.http import HttpServerTransport
 3057 |     from starlette.applications import Starlette
 3058 |     from starlette.routing import Route
 3059 | 
 3060 |     app = Server("example-server")
 3061 | 
 3062 |     async def handle_mcp(scope, receive, send):
 3063 |         if scope["method"] == "POST":
 3064 |             # Handle JSON-RPC request
 3065 |             response = await app.handle_request(request_body)
 3066 | 
 3067 |             if needs_streaming:
 3068 |                 # Return SSE stream
 3069 |                 await send_sse_response(send, response)
 3070 |             else:
 3071 |                 # Return JSON response
 3072 |                 await send_json_response(send, response)
 3073 | 
 3074 |         elif scope["method"] == "GET":
 3075 |             # Optional: Support server-initiated SSE streams
 3076 |             await send_sse_stream(send)
 3077 | 
 3078 |     starlette_app = Starlette(
 3079 |         routes=[
 3080 |             Route("/mcp", endpoint=handle_mcp, methods=["POST", "GET"]),
 3081 |         ]
 3082 |     )
 3083 |     ```
 3084 |   </Tab>
 3085 | 
 3086 |   <Tab title="Python (Client)">
 3087 |     ```python
 3088 |     async with http_client("http://localhost:8000/mcp") as transport:
 3089 |         async with ClientSession(transport[0], transport[1]) as session:
 3090 |             await session.initialize()
 3091 |     ```
 3092 |   </Tab>
 3093 | </Tabs>
 3094 | 
 3095 | #### Session Management
 3096 | 
 3097 | Streamable HTTP supports stateful sessions to maintain context across multiple requests:
 3098 | 
 3099 | 1. **Session Initialization**: Servers may assign a session ID during initialization by including it in an `Mcp-Session-Id` header
 3100 | 2. **Session Persistence**: Clients must include the session ID in all subsequent requests using the `Mcp-Session-Id` header
 3101 | 3. **Session Termination**: Sessions can be explicitly terminated by sending an HTTP DELETE request with the session ID
 3102 | 
 3103 | Example session flow:
 3104 | 
 3105 | ```typescript
 3106 | // Server assigns session ID during initialization
 3107 | app.post("/mcp", (req, res) => {
 3108 |   if (req.body.method === "initialize") {
 3109 |     const sessionId = generateSecureId();
 3110 |     res.setHeader("Mcp-Session-Id", sessionId);
 3111 |     // Store session state...
 3112 |   }
 3113 |   // Handle request...
 3114 | });
 3115 | 
 3116 | // Client includes session ID in subsequent requests
 3117 | fetch("/mcp", {
 3118 |   method: "POST",
 3119 |   headers: {
 3120 |     "Content-Type": "application/json",
 3121 |     "Mcp-Session-Id": sessionId,
 3122 |   },
 3123 |   body: JSON.stringify(request),
 3124 | });
 3125 | ```
 3126 | 
 3127 | #### Resumability and Redelivery
 3128 | 
 3129 | To support resuming broken connections, Streamable HTTP provides:
 3130 | 
 3131 | 1. **Event IDs**: Servers can attach unique IDs to SSE events for tracking
 3132 | 2. **Resume from Last Event**: Clients can resume by sending the `Last-Event-ID` header
 3133 | 3. **Message Replay**: Servers can replay missed messages from the disconnection point
 3134 | 
 3135 | This ensures reliable message delivery even with unstable network connections.
 3136 | 
 3137 | #### Security Considerations
 3138 | 
 3139 | When implementing Streamable HTTP transport, follow these security best practices:
 3140 | 
 3141 | 1. **Validate Origin Headers**: Always validate the `Origin` header on all incoming connections to prevent DNS rebinding attacks
 3142 | 2. **Bind to Localhost**: When running locally, bind only to localhost (127.0.0.1) rather than all network interfaces (0.0.0.0)
 3143 | 3. **Implement Authentication**: Use proper authentication for all connections
 3144 | 4. **Use HTTPS**: Always use TLS/HTTPS for production deployments
 3145 | 5. **Validate Session IDs**: Ensure session IDs are cryptographically secure and properly validated
 3146 | 
 3147 | Without these protections, attackers could use DNS rebinding to interact with local MCP servers from remote websites.
 3148 | 
 3149 | ### Server-Sent Events (SSE) - Deprecated
 3150 | 
 3151 | <Note>
 3152 |   SSE as a standalone transport is deprecated as of protocol version 2024-11-05.
 3153 |   It has been replaced by Streamable HTTP, which incorporates SSE as an optional
 3154 |   streaming mechanism. For backwards compatibility information, see the
 3155 |   [backwards compatibility](#backwards-compatibility) section below.
 3156 | </Note>
 3157 | 
 3158 | The legacy SSE transport enabled server-to-client streaming with HTTP POST requests for client-to-server communication.
 3159 | 
 3160 | Previously used when:
 3161 | 
 3162 | * Only server-to-client streaming is needed
 3163 | * Working with restricted networks
 3164 | * Implementing simple updates
 3165 | 
 3166 | #### Legacy Security Considerations
 3167 | 
 3168 | The deprecated SSE transport had similar security considerations to Streamable HTTP, particularly regarding DNS rebinding attacks. These same protections should be applied when using SSE streams within the Streamable HTTP transport.
 3169 | 
 3170 | <Tabs>
 3171 |   <Tab title="TypeScript (Server)">
 3172 |     ```typescript
 3173 |     import express from "express";
 3174 | 
 3175 |     const app = express();
 3176 | 
 3177 |     const server = new Server({
 3178 |       name: "example-server",
 3179 |       version: "1.0.0"
 3180 |     }, {
 3181 |       capabilities: {}
 3182 |     });
 3183 | 
 3184 |     let transport: SSEServerTransport | null = null;
 3185 | 
 3186 |     app.get("/sse", (req, res) => {
 3187 |       transport = new SSEServerTransport("/messages", res);
 3188 |       server.connect(transport);
 3189 |     });
 3190 | 
 3191 |     app.post("/messages", (req, res) => {
 3192 |       if (transport) {
 3193 |         transport.handlePostMessage(req, res);
 3194 |       }
 3195 |     });
 3196 | 
 3197 |     app.listen(3000);
 3198 |     ```
 3199 |   </Tab>
 3200 | 
 3201 |   <Tab title="TypeScript (Client)">
 3202 |     ```typescript
 3203 |     const client = new Client({
 3204 |       name: "example-client",
 3205 |       version: "1.0.0"
 3206 |     }, {
 3207 |       capabilities: {}
 3208 |     });
 3209 | 
 3210 |     const transport = new SSEClientTransport(
 3211 |       new URL("http://localhost:3000/sse")
 3212 |     );
 3213 |     await client.connect(transport);
 3214 |     ```
 3215 |   </Tab>
 3216 | 
 3217 |   <Tab title="Python (Server)">
 3218 |     ```python
 3219 |     from mcp.server.sse import SseServerTransport
 3220 |     from starlette.applications import Starlette
 3221 |     from starlette.routing import Route
 3222 | 
 3223 |     app = Server("example-server")
 3224 |     sse = SseServerTransport("/messages")
 3225 | 
 3226 |     async def handle_sse(scope, receive, send):
 3227 |         async with sse.connect_sse(scope, receive, send) as streams:
 3228 |             await app.run(streams[0], streams[1], app.create_initialization_options())
 3229 | 
 3230 |     async def handle_messages(scope, receive, send):
 3231 |         await sse.handle_post_message(scope, receive, send)
 3232 | 
 3233 |     starlette_app = Starlette(
 3234 |         routes=[
 3235 |             Route("/sse", endpoint=handle_sse),
 3236 |             Route("/messages", endpoint=handle_messages, methods=["POST"]),
 3237 |         ]
 3238 |     )
 3239 |     ```
 3240 |   </Tab>
 3241 | 
 3242 |   <Tab title="Python (Client)">
 3243 |     ```python
 3244 |     async with sse_client("http://localhost:8000/sse") as streams:
 3245 |         async with ClientSession(streams[0], streams[1]) as session:
 3246 |             await session.initialize()
 3247 |     ```
 3248 |   </Tab>
 3249 | </Tabs>
 3250 | 
 3251 | ## Custom Transports
 3252 | 
 3253 | MCP makes it easy to implement custom transports for specific needs. Any transport implementation just needs to conform to the Transport interface:
 3254 | 
 3255 | You can implement custom transports for:
 3256 | 
 3257 | * Custom network protocols
 3258 | * Specialized communication channels
 3259 | * Integration with existing systems
 3260 | * Performance optimization
 3261 | 
 3262 | <Tabs>
 3263 |   <Tab title="TypeScript">
 3264 |     ```typescript
 3265 |     interface Transport {
 3266 |       // Start processing messages
 3267 |       start(): Promise<void>;
 3268 | 
 3269 |       // Send a JSON-RPC message
 3270 |       send(message: JSONRPCMessage): Promise<void>;
 3271 | 
 3272 |       // Close the connection
 3273 |       close(): Promise<void>;
 3274 | 
 3275 |       // Callbacks
 3276 |       onclose?: () => void;
 3277 |       onerror?: (error: Error) => void;
 3278 |       onmessage?: (message: JSONRPCMessage) => void;
 3279 |     }
 3280 |     ```
 3281 |   </Tab>
 3282 | 
 3283 |   <Tab title="Python">
 3284 |     Note that while MCP Servers are often implemented with asyncio, we recommend
 3285 |     implementing low-level interfaces like transports with `anyio` for wider compatibility.
 3286 | 
 3287 |     ```python
 3288 |     @contextmanager
 3289 |     async def create_transport(
 3290 |         read_stream: MemoryObjectReceiveStream[JSONRPCMessage | Exception],
 3291 |         write_stream: MemoryObjectSendStream[JSONRPCMessage]
 3292 |     ):
 3293 |         """
 3294 |         Transport interface for MCP.
 3295 | 
 3296 |         Args:
 3297 |             read_stream: Stream to read incoming messages from
 3298 |             write_stream: Stream to write outgoing messages to
 3299 |         """
 3300 |         async with anyio.create_task_group() as tg:
 3301 |             try:
 3302 |                 # Start processing messages
 3303 |                 tg.start_soon(lambda: process_messages(read_stream))
 3304 | 
 3305 |                 # Send messages
 3306 |                 async with write_stream:
 3307 |                     yield write_stream
 3308 | 
 3309 |             except Exception as exc:
 3310 |                 # Handle errors
 3311 |                 raise exc
 3312 |             finally:
 3313 |                 # Clean up
 3314 |                 tg.cancel_scope.cancel()
 3315 |                 await write_stream.aclose()
 3316 |                 await read_stream.aclose()
 3317 |     ```
 3318 |   </Tab>
 3319 | </Tabs>
 3320 | 
 3321 | ## Error Handling
 3322 | 
 3323 | Transport implementations should handle various error scenarios:
 3324 | 
 3325 | 1. Connection errors
 3326 | 2. Message parsing errors
 3327 | 3. Protocol errors
 3328 | 4. Network timeouts
 3329 | 5. Resource cleanup
 3330 | 
 3331 | Example error handling:
 3332 | 
 3333 | <Tabs>
 3334 |   <Tab title="TypeScript">
 3335 |     ```typescript
 3336 |     class ExampleTransport implements Transport {
 3337 |       async start() {
 3338 |         try {
 3339 |           // Connection logic
 3340 |         } catch (error) {
 3341 |           this.onerror?.(new Error(`Failed to connect: ${error}`));
 3342 |           throw error;
 3343 |         }
 3344 |       }
 3345 | 
 3346 |       async send(message: JSONRPCMessage) {
 3347 |         try {
 3348 |           // Sending logic
 3349 |         } catch (error) {
 3350 |           this.onerror?.(new Error(`Failed to send message: ${error}`));
 3351 |           throw error;
 3352 |         }
 3353 |       }
 3354 |     }
 3355 |     ```
 3356 |   </Tab>
 3357 | 
 3358 |   <Tab title="Python">
 3359 |     Note that while MCP Servers are often implemented with asyncio, we recommend
 3360 |     implementing low-level interfaces like transports with `anyio` for wider compatibility.
 3361 | 
 3362 |     ```python
 3363 |     @contextmanager
 3364 |     async def example_transport(scope: Scope, receive: Receive, send: Send):
 3365 |         try:
 3366 |             # Create streams for bidirectional communication
 3367 |             read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
 3368 |             write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
 3369 | 
 3370 |             async def message_handler():
 3371 |                 try:
 3372 |                     async with read_stream_writer:
 3373 |                         # Message handling logic
 3374 |                         pass
 3375 |                 except Exception as exc:
 3376 |                     logger.error(f"Failed to handle message: {exc}")
 3377 |                     raise exc
 3378 | 
 3379 |             async with anyio.create_task_group() as tg:
 3380 |                 tg.start_soon(message_handler)
 3381 |                 try:
 3382 |                     # Yield streams for communication
 3383 |                     yield read_stream, write_stream
 3384 |                 except Exception as exc:
 3385 |                     logger.error(f"Transport error: {exc}")
 3386 |                     raise exc
 3387 |                 finally:
 3388 |                     tg.cancel_scope.cancel()
 3389 |                     await write_stream.aclose()
 3390 |                     await read_stream.aclose()
 3391 |         except Exception as exc:
 3392 |             logger.error(f"Failed to initialize transport: {exc}")
 3393 |             raise exc
 3394 |     ```
 3395 |   </Tab>
 3396 | </Tabs>
 3397 | 
 3398 | ## Best Practices
 3399 | 
 3400 | When implementing or using MCP transport:
 3401 | 
 3402 | 1. Handle connection lifecycle properly
 3403 | 2. Implement proper error handling
 3404 | 3. Clean up resources on connection close
 3405 | 4. Use appropriate timeouts
 3406 | 5. Validate messages before sending
 3407 | 6. Log transport events for debugging
 3408 | 7. Implement reconnection logic when appropriate
 3409 | 8. Handle backpressure in message queues
 3410 | 9. Monitor connection health
 3411 | 10. Implement proper security measures
 3412 | 
 3413 | ## Security Considerations
 3414 | 
 3415 | When implementing transport:
 3416 | 
 3417 | ### Authentication and Authorization
 3418 | 
 3419 | * Implement proper authentication mechanisms
 3420 | * Validate client credentials
 3421 | * Use secure token handling
 3422 | * Implement authorization checks
 3423 | 
 3424 | ### Data Security
 3425 | 
 3426 | * Use TLS for network transport
 3427 | * Encrypt sensitive data
 3428 | * Validate message integrity
 3429 | * Implement message size limits
 3430 | * Sanitize input data
 3431 | 
 3432 | ### Network Security
 3433 | 
 3434 | * Implement rate limiting
 3435 | * Use appropriate timeouts
 3436 | * Handle denial of service scenarios
 3437 | * Monitor for unusual patterns
 3438 | * Implement proper firewall rules
 3439 | * For HTTP-based transports (including Streamable HTTP), validate Origin headers to prevent DNS rebinding attacks
 3440 | * For local servers, bind only to localhost (127.0.0.1) instead of all interfaces (0.0.0.0)
 3441 | 
 3442 | ## Debugging Transport
 3443 | 
 3444 | Tips for debugging transport issues:
 3445 | 
 3446 | 1. Enable debug logging
 3447 | 2. Monitor message flow
 3448 | 3. Check connection states
 3449 | 4. Validate message formats
 3450 | 5. Test error scenarios
 3451 | 6. Use network analysis tools
 3452 | 7. Implement health checks
 3453 | 8. Monitor resource usage
 3454 | 9. Test edge cases
 3455 | 10. Use proper error tracking
 3456 | 
 3457 | ## Backwards Compatibility
 3458 | 
 3459 | To maintain compatibility between different protocol versions:
 3460 | 
 3461 | ### For Servers Supporting Older Clients
 3462 | 
 3463 | Servers wanting to support clients using the deprecated HTTP+SSE transport should:
 3464 | 
 3465 | 1. Host both the old SSE and POST endpoints alongside the new MCP endpoint
 3466 | 2. Handle initialization requests on both endpoints
 3467 | 3. Maintain separate handling logic for each transport type
 3468 | 
 3469 | ### For Clients Supporting Older Servers
 3470 | 
 3471 | Clients wanting to support servers using the deprecated transport should:
 3472 | 
 3473 | 1. Accept server URLs that may use either transport
 3474 | 2. Attempt to POST an `InitializeRequest` with proper `Accept` headers:
 3475 |    * If successful, use Streamable HTTP transport
 3476 |    * If it fails with 4xx status, fall back to legacy SSE transport
 3477 | 3. Issue a GET request expecting an SSE stream with `endpoint` event for legacy servers
 3478 | 
 3479 | Example compatibility detection:
 3480 | 
 3481 | ```typescript
 3482 | async function detectTransport(serverUrl: string): Promise<TransportType> {
 3483 |   try {
 3484 |     // Try Streamable HTTP first
 3485 |     const response = await fetch(serverUrl, {
 3486 |       method: "POST",
 3487 |       headers: {
 3488 |         "Content-Type": "application/json",
 3489 |         Accept: "application/json, text/event-stream",
 3490 |       },
 3491 |       body: JSON.stringify({
 3492 |         jsonrpc: "2.0",
 3493 |         method: "initialize",
 3494 |         params: {
 3495 |           /* ... */
 3496 |         },
 3497 |       }),
 3498 |     });
 3499 | 
 3500 |     if (response.ok) {
 3501 |       return "streamable-http";
 3502 |     }
 3503 |   } catch (error) {
 3504 |     // Fall back to legacy SSE
 3505 |     const sseResponse = await fetch(serverUrl, {
 3506 |       method: "GET",
 3507 |       headers: { Accept: "text/event-stream" },
 3508 |     });
 3509 | 
 3510 |     if (sseResponse.ok) {
 3511 |       return "legacy-sse";
 3512 |     }
 3513 |   }
 3514 | 
 3515 |   throw new Error("Unsupported transport");
 3516 | }
 3517 | ```
 3518 | 
 3519 | 
 3520 | # Debugging
 3521 | Source: https://modelcontextprotocol.io/docs/tools/debugging
 3522 | 
 3523 | A comprehensive guide to debugging Model Context Protocol (MCP) integrations
 3524 | 
 3525 | Effective debugging is essential when developing MCP servers or integrating them with applications. This guide covers the debugging tools and approaches available in the MCP ecosystem.
 3526 | 
 3527 | <Info>
 3528 |   This guide is for macOS. Guides for other platforms are coming soon.
 3529 | </Info>
 3530 | 
 3531 | ## Debugging tools overview
 3532 | 
 3533 | MCP provides several tools for debugging at different levels:
 3534 | 
 3535 | 1. **MCP Inspector**
 3536 | 
 3537 |    * Interactive debugging interface
 3538 |    * Direct server testing
 3539 |    * See the [Inspector guide](/docs/tools/inspector) for details
 3540 | 
 3541 | 2. **Claude Desktop Developer Tools**
 3542 | 
 3543 |    * Integration testing
 3544 |    * Log collection
 3545 |    * Chrome DevTools integration
 3546 | 
 3547 | 3. **Server Logging**
 3548 |    * Custom logging implementations
 3549 |    * Error tracking
 3550 |    * Performance monitoring
 3551 | 
 3552 | ## Debugging in Claude Desktop
 3553 | 
 3554 | ### Checking server status
 3555 | 
 3556 | The Claude.app interface provides basic server status information:
 3557 | 
 3558 | 1. Click the <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/claude-desktop-mcp-plug-icon.svg" style={{display: 'inline', margin: 0, height: '1.3em'}} /> icon to view:
 3559 | 
 3560 |    * Connected servers
 3561 |    * Available prompts and resources
 3562 | 
 3563 | 2. Click the "Search and tools" <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/claude-desktop-mcp-slider.svg" style={{display: 'inline', margin: 0, height: '1.3em'}} /> icon to view:
 3564 |    * Tools made available to the model
 3565 | 
 3566 | ### Viewing logs
 3567 | 
 3568 | Review detailed MCP logs from Claude Desktop:
 3569 | 
 3570 | ```bash
 3571 | # Follow logs in real-time
 3572 | tail -n 20 -F ~/Library/Logs/Claude/mcp*.log
 3573 | ```
 3574 | 
 3575 | The logs capture:
 3576 | 
 3577 | * Server connection events
 3578 | * Configuration issues
 3579 | * Runtime errors
 3580 | * Message exchanges
 3581 | 
 3582 | ### Using Chrome DevTools
 3583 | 
 3584 | Access Chrome's developer tools inside Claude Desktop to investigate client-side errors:
 3585 | 
 3586 | 1. Create a `developer_settings.json` file with `allowDevTools` set to true:
 3587 | 
 3588 | ```bash
 3589 | echo '{"allowDevTools": true}' > ~/Library/Application\ Support/Claude/developer_settings.json
 3590 | ```
 3591 | 
 3592 | 2. Open DevTools: `Command-Option-Shift-i`
 3593 | 
 3594 | Note: You'll see two DevTools windows:
 3595 | 
 3596 | * Main content window
 3597 | * App title bar window
 3598 | 
 3599 | Use the Console panel to inspect client-side errors.
 3600 | 
 3601 | Use the Network panel to inspect:
 3602 | 
 3603 | * Message payloads
 3604 | * Connection timing
 3605 | 
 3606 | ## Common issues
 3607 | 
 3608 | ### Working directory
 3609 | 
 3610 | When using MCP servers with Claude Desktop:
 3611 | 
 3612 | * The working directory for servers launched via `claude_desktop_config.json` may be undefined (like `/` on macOS) since Claude Desktop could be started from anywhere
 3613 | * Always use absolute paths in your configuration and `.env` files to ensure reliable operation
 3614 | * For testing servers directly via command line, the working directory will be where you run the command
 3615 | 
 3616 | For example in `claude_desktop_config.json`, use:
 3617 | 
 3618 | ```json
 3619 | {
 3620 |   "command": "npx",
 3621 |   "args": [
 3622 |     "-y",
 3623 |     "@modelcontextprotocol/server-filesystem",
 3624 |     "/Users/username/data"
 3625 |   ]
 3626 | }
 3627 | ```
 3628 | 
 3629 | Instead of relative paths like `./data`
 3630 | 
 3631 | ### Environment variables
 3632 | 
 3633 | MCP servers inherit only a subset of environment variables automatically, like `USER`, `HOME`, and `PATH`.
 3634 | 
 3635 | To override the default variables or provide your own, you can specify an `env` key in `claude_desktop_config.json`:
 3636 | 
 3637 | ```json
 3638 | {
 3639 |   "myserver": {
 3640 |     "command": "mcp-server-myapp",
 3641 |     "env": {
 3642 |       "MYAPP_API_KEY": "some_key"
 3643 |     }
 3644 |   }
 3645 | }
 3646 | ```
 3647 | 
 3648 | ### Server initialization
 3649 | 
 3650 | Common initialization problems:
 3651 | 
 3652 | 1. **Path Issues**
 3653 | 
 3654 |    * Incorrect server executable path
 3655 |    * Missing required files
 3656 |    * Permission problems
 3657 |    * Try using an absolute path for `command`
 3658 | 
 3659 | 2. **Configuration Errors**
 3660 | 
 3661 |    * Invalid JSON syntax
 3662 |    * Missing required fields
 3663 |    * Type mismatches
 3664 | 
 3665 | 3. **Environment Problems**
 3666 |    * Missing environment variables
 3667 |    * Incorrect variable values
 3668 |    * Permission restrictions
 3669 | 
 3670 | ### Connection problems
 3671 | 
 3672 | When servers fail to connect:
 3673 | 
 3674 | 1. Check Claude Desktop logs
 3675 | 2. Verify server process is running
 3676 | 3. Test standalone with [Inspector](/docs/tools/inspector)
 3677 | 4. Verify protocol compatibility
 3678 | 
 3679 | ## Implementing logging
 3680 | 
 3681 | ### Server-side logging
 3682 | 
 3683 | When building a server that uses the local stdio [transport](/docs/concepts/transports), all messages logged to stderr (standard error) will be captured by the host application (e.g., Claude Desktop) automatically.
 3684 | 
 3685 | <Warning>
 3686 |   Local MCP servers should not log messages to stdout (standard out), as this will interfere with protocol operation.
 3687 | </Warning>
 3688 | 
 3689 | For all [transports](/docs/concepts/transports), you can also provide logging to the client by sending a log message notification:
 3690 | 
 3691 | <Tabs>
 3692 |   <Tab title="Python">
 3693 |     ```python
 3694 |     server.request_context.session.send_log_message(
 3695 |       level="info",
 3696 |       data="Server started successfully",
 3697 |     )
 3698 |     ```
 3699 |   </Tab>
 3700 | 
 3701 |   <Tab title="TypeScript">
 3702 |     ```typescript
 3703 |     server.sendLoggingMessage({
 3704 |       level: "info",
 3705 |       data: "Server started successfully",
 3706 |     });
 3707 |     ```
 3708 |   </Tab>
 3709 | </Tabs>
 3710 | 
 3711 | Important events to log:
 3712 | 
 3713 | * Initialization steps
 3714 | * Resource access
 3715 | * Tool execution
 3716 | * Error conditions
 3717 | * Performance metrics
 3718 | 
 3719 | ### Client-side logging
 3720 | 
 3721 | In client applications:
 3722 | 
 3723 | 1. Enable debug logging
 3724 | 2. Monitor network traffic
 3725 | 3. Track message exchanges
 3726 | 4. Record error states
 3727 | 
 3728 | ## Debugging workflow
 3729 | 
 3730 | ### Development cycle
 3731 | 
 3732 | 1. Initial Development
 3733 | 
 3734 |    * Use [Inspector](/docs/tools/inspector) for basic testing
 3735 |    * Implement core functionality
 3736 |    * Add logging points
 3737 | 
 3738 | 2. Integration Testing
 3739 |    * Test in Claude Desktop
 3740 |    * Monitor logs
 3741 |    * Check error handling
 3742 | 
 3743 | ### Testing changes
 3744 | 
 3745 | To test changes efficiently:
 3746 | 
 3747 | * **Configuration changes**: Restart Claude Desktop
 3748 | * **Server code changes**: Use Command-R to reload
 3749 | * **Quick iteration**: Use [Inspector](/docs/tools/inspector) during development
 3750 | 
 3751 | ## Best practices
 3752 | 
 3753 | ### Logging strategy
 3754 | 
 3755 | 1. **Structured Logging**
 3756 | 
 3757 |    * Use consistent formats
 3758 |    * Include context
 3759 |    * Add timestamps
 3760 |    * Track request IDs
 3761 | 
 3762 | 2. **Error Handling**
 3763 | 
 3764 |    * Log stack traces
 3765 |    * Include error context
 3766 |    * Track error patterns
 3767 |    * Monitor recovery
 3768 | 
 3769 | 3. **Performance Tracking**
 3770 |    * Log operation timing
 3771 |    * Monitor resource usage
 3772 |    * Track message sizes
 3773 |    * Measure latency
 3774 | 
 3775 | ### Security considerations
 3776 | 
 3777 | When debugging:
 3778 | 
 3779 | 1. **Sensitive Data**
 3780 | 
 3781 |    * Sanitize logs
 3782 |    * Protect credentials
 3783 |    * Mask personal information
 3784 | 
 3785 | 2. **Access Control**
 3786 |    * Verify permissions
 3787 |    * Check authentication
 3788 |    * Monitor access patterns
 3789 | 
 3790 | ## Getting help
 3791 | 
 3792 | When encountering issues:
 3793 | 
 3794 | 1. **First Steps**
 3795 | 
 3796 |    * Check server logs
 3797 |    * Test with [Inspector](/docs/tools/inspector)
 3798 |    * Review configuration
 3799 |    * Verify environment
 3800 | 
 3801 | 2. **Support Channels**
 3802 | 
 3803 |    * GitHub issues
 3804 |    * GitHub discussions
 3805 | 
 3806 | 3. **Providing Information**
 3807 |    * Log excerpts
 3808 |    * Configuration files
 3809 |    * Steps to reproduce
 3810 |    * Environment details
 3811 | 
 3812 | ## Next steps
 3813 | 
 3814 | <CardGroup cols={2}>
 3815 |   <Card title="MCP Inspector" icon="magnifying-glass" href="/docs/tools/inspector">
 3816 |     Learn to use the MCP Inspector
 3817 |   </Card>
 3818 | </CardGroup>
 3819 | 
 3820 | 
 3821 | # Inspector
 3822 | Source: https://modelcontextprotocol.io/docs/tools/inspector
 3823 | 
 3824 | In-depth guide to using the MCP Inspector for testing and debugging Model Context Protocol servers
 3825 | 
 3826 | The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) is an interactive developer tool for testing and debugging MCP servers. While the [Debugging Guide](/docs/tools/debugging) covers the Inspector as part of the overall debugging toolkit, this document provides a detailed exploration of the Inspector's features and capabilities.
 3827 | 
 3828 | ## Getting started
 3829 | 
 3830 | ### Installation and basic usage
 3831 | 
 3832 | The Inspector runs directly through `npx` without requiring installation:
 3833 | 
 3834 | ```bash
 3835 | npx @modelcontextprotocol/inspector <command>
 3836 | ```
 3837 | 
 3838 | ```bash
 3839 | npx @modelcontextprotocol/inspector <command> <arg1> <arg2>
 3840 | ```
 3841 | 
 3842 | #### Inspecting servers from NPM or PyPi
 3843 | 
 3844 | A common way to start server packages from [NPM](https://npmjs.com) or [PyPi](https://pypi.com).
 3845 | 
 3846 | <Tabs>
 3847 |   <Tab title="NPM package">
 3848 |     ```bash
 3849 |     npx -y @modelcontextprotocol/inspector npx <package-name> <args>
 3850 |     # For example
 3851 |     npx -y @modelcontextprotocol/inspector npx @modelcontextprotocol/server-filesystem /Users/username/Desktop
 3852 |     ```
 3853 |   </Tab>
 3854 | 
 3855 |   <Tab title="PyPi package">
 3856 |     ```bash
 3857 |     npx @modelcontextprotocol/inspector uvx <package-name> <args>
 3858 |     # For example
 3859 |     npx @modelcontextprotocol/inspector uvx mcp-server-git --repository ~/code/mcp/servers.git
 3860 |     ```
 3861 |   </Tab>
 3862 | </Tabs>
 3863 | 
 3864 | #### Inspecting locally developed servers
 3865 | 
 3866 | To inspect servers locally developed or downloaded as a repository, the most common
 3867 | way is:
 3868 | 
 3869 | <Tabs>
 3870 |   <Tab title="TypeScript">
 3871 |     ```bash
 3872 |     npx @modelcontextprotocol/inspector node path/to/server/index.js args...
 3873 |     ```
 3874 |   </Tab>
 3875 | 
 3876 |   <Tab title="Python">
 3877 |     ```bash
 3878 |     npx @modelcontextprotocol/inspector \
 3879 |       uv \
 3880 |       --directory path/to/server \
 3881 |       run \
 3882 |       package-name \
 3883 |       args...
 3884 |     ```
 3885 |   </Tab>
 3886 | </Tabs>
 3887 | 
 3888 | Please carefully read any attached README for the most accurate instructions.
 3889 | 
 3890 | ## Feature overview
 3891 | 
 3892 | <Frame caption="The MCP Inspector interface">
 3893 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/mcp-inspector.png" />
 3894 | </Frame>
 3895 | 
 3896 | The Inspector provides several features for interacting with your MCP server:
 3897 | 
 3898 | ### Server connection pane
 3899 | 
 3900 | * Allows selecting the [transport](/docs/concepts/transports) for connecting to the server
 3901 | * For local servers, supports customizing the command-line arguments and environment
 3902 | 
 3903 | ### Resources tab
 3904 | 
 3905 | * Lists all available resources
 3906 | * Shows resource metadata (MIME types, descriptions)
 3907 | * Allows resource content inspection
 3908 | * Supports subscription testing
 3909 | 
 3910 | ### Prompts tab
 3911 | 
 3912 | * Displays available prompt templates
 3913 | * Shows prompt arguments and descriptions
 3914 | * Enables prompt testing with custom arguments
 3915 | * Previews generated messages
 3916 | 
 3917 | ### Tools tab
 3918 | 
 3919 | * Lists available tools
 3920 | * Shows tool schemas and descriptions
 3921 | * Enables tool testing with custom inputs
 3922 | * Displays tool execution results
 3923 | 
 3924 | ### Notifications pane
 3925 | 
 3926 | * Presents all logs recorded from the server
 3927 | * Shows notifications received from the server
 3928 | 
 3929 | ## Best practices
 3930 | 
 3931 | ### Development workflow
 3932 | 
 3933 | 1. Start Development
 3934 | 
 3935 |    * Launch Inspector with your server
 3936 |    * Verify basic connectivity
 3937 |    * Check capability negotiation
 3938 | 
 3939 | 2. Iterative testing
 3940 | 
 3941 |    * Make server changes
 3942 |    * Rebuild the server
 3943 |    * Reconnect the Inspector
 3944 |    * Test affected features
 3945 |    * Monitor messages
 3946 | 
 3947 | 3. Test edge cases
 3948 |    * Invalid inputs
 3949 |    * Missing prompt arguments
 3950 |    * Concurrent operations
 3951 |    * Verify error handling and error responses
 3952 | 
 3953 | ## Next steps
 3954 | 
 3955 | <CardGroup cols={2}>
 3956 |   <Card title="Inspector Repository" icon="github" href="https://github.com/modelcontextprotocol/inspector">
 3957 |     Check out the MCP Inspector source code
 3958 |   </Card>
 3959 | 
 3960 |   <Card title="Debugging Guide" icon="bug" href="/docs/tools/debugging">
 3961 |     Learn about broader debugging strategies
 3962 |   </Card>
 3963 | </CardGroup>
 3964 | 
 3965 | 
 3966 | # Example Servers
 3967 | Source: https://modelcontextprotocol.io/examples
 3968 | 
 3969 | A list of example servers and implementations
 3970 | 
 3971 | This page showcases various Model Context Protocol (MCP) servers that demonstrate the protocol's capabilities and versatility. These servers enable Large Language Models (LLMs) to securely access tools and data sources.
 3972 | 
 3973 | ## Reference implementations
 3974 | 
 3975 | These official reference servers demonstrate core MCP features and SDK usage:
 3976 | 
 3977 | ### Current reference servers
 3978 | 
 3979 | * **[Filesystem](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem)** - Secure file operations with configurable access controls
 3980 | * **[Fetch](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch)** - Web content fetching and conversion optimized for LLM usage
 3981 | * **[Memory](https://github.com/modelcontextprotocol/servers/tree/main/src/memory)** - Knowledge graph-based persistent memory system
 3982 | * **[Sequential Thinking](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking)** - Dynamic problem-solving through thought sequences
 3983 | 
 3984 | ### Archived servers (historical reference)
 3985 | 
 3986 | ⚠️ **Note**: The following servers have been moved to the [servers-archived repository](https://github.com/modelcontextprotocol/servers-archived) and are no longer actively maintained. They are provided for historical reference only.
 3987 | 
 3988 | #### Data and file systems
 3989 | 
 3990 | * **[PostgreSQL](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/postgres)** - Read-only database access with schema inspection capabilities
 3991 | * **[SQLite](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/sqlite)** - Database interaction and business intelligence features
 3992 | * **[Google Drive](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/gdrive)** - File access and search capabilities for Google Drive
 3993 | 
 3994 | #### Development tools
 3995 | 
 3996 | * **[Git](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/git)** - Tools to read, search, and manipulate Git repositories
 3997 | * **[GitHub](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/github)** - Repository management, file operations, and GitHub API integration
 3998 | * **[GitLab](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/gitlab)** - GitLab API integration enabling project management
 3999 | * **[Sentry](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/sentry)** - Retrieving and analyzing issues from Sentry.io
 4000 | 
 4001 | #### Web and browser automation
 4002 | 
 4003 | * **[Brave Search](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/brave-search)** - Web and local search using Brave's Search API
 4004 | * **[Puppeteer](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/puppeteer)** - Browser automation and web scraping capabilities
 4005 | 
 4006 | #### Productivity and communication
 4007 | 
 4008 | * **[Slack](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/slack)** - Channel management and messaging capabilities
 4009 | * **[Google Maps](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/google-maps)** - Location services, directions, and place details
 4010 | 
 4011 | #### AI and specialized tools
 4012 | 
 4013 | * **[EverArt](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/everart)** - AI image generation using various models
 4014 | * **[AWS KB Retrieval](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime
 4015 | 
 4016 | ## Official integrations
 4017 | 
 4018 | Visit the [MCP Servers Repository (Official Integrations section)](https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#%EF%B8%8F-official-integrations) for a list of MCP servers maintained by companies for their platforms.
 4019 | 
 4020 | ## Community implementations
 4021 | 
 4022 | Visit the [MCP Servers Repository (Community section)](https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#-community-servers) for a list of MCP servers maintained by community members.
 4023 | 
 4024 | ## Getting started
 4025 | 
 4026 | ### Using reference servers
 4027 | 
 4028 | TypeScript-based servers can be used directly with `npx`:
 4029 | 
 4030 | ```bash
 4031 | npx -y @modelcontextprotocol/server-memory
 4032 | ```
 4033 | 
 4034 | Python-based servers can be used with `uvx` (recommended) or `pip`:
 4035 | 
 4036 | ```bash
 4037 | # Using uvx
 4038 | uvx mcp-server-git
 4039 | 
 4040 | # Using pip
 4041 | pip install mcp-server-git
 4042 | python -m mcp_server_git
 4043 | ```
 4044 | 
 4045 | ### Configuring with Claude
 4046 | 
 4047 | To use an MCP server with Claude, add it to your configuration:
 4048 | 
 4049 | ```json
 4050 | {
 4051 |   "mcpServers": {
 4052 |     "memory": {
 4053 |       "command": "npx",
 4054 |       "args": ["-y", "@modelcontextprotocol/server-memory"]
 4055 |     },
 4056 |     "filesystem": {
 4057 |       "command": "npx",
 4058 |       "args": [
 4059 |         "-y",
 4060 |         "@modelcontextprotocol/server-filesystem",
 4061 |         "/path/to/allowed/files"
 4062 |       ]
 4063 |     },
 4064 |     "github": {
 4065 |       "command": "npx",
 4066 |       "args": ["-y", "@modelcontextprotocol/server-github"],
 4067 |       "env": {
 4068 |         "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
 4069 |       }
 4070 |     }
 4071 |   }
 4072 | }
 4073 | ```
 4074 | 
 4075 | ## Additional resources
 4076 | 
 4077 | Visit the [MCP Servers Repository (Resources section)](https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#-resources) for a collection of other resources and projects related to MCP.
 4078 | 
 4079 | Visit our [GitHub Discussions](https://github.com/orgs/modelcontextprotocol/discussions) to engage with the MCP community.
 4080 | 
 4081 | 
 4082 | # FAQs
 4083 | Source: https://modelcontextprotocol.io/faqs
 4084 | 
 4085 | Explaining MCP and why it matters in simple terms
 4086 | 
 4087 | ## What is MCP?
 4088 | 
 4089 | MCP (Model Context Protocol) is a standard way for AI applications and agents to connect to and work with your data sources (e.g. local files, databases, or content repositories) and tools (e.g. GitHub, Google Maps, or Puppeteer).
 4090 | 
 4091 | Think of MCP as a universal adapter for AI applications, similar to what USB-C is for physical devices. USB-C acts as a universal adapter to connect devices to various peripherals and accessories. Similarly, MCP provides a standardized way to connect AI applications to different data and tools.
 4092 | 
 4093 | Before USB-C, you needed different cables for different connections. Similarly, before MCP, developers had to build custom connections to each data source or tool they wanted their AI application to work with—a time-consuming process that often resulted in limited functionality. Now, with MCP, developers can easily add connections to their AI applications, making their applications much more powerful from day one.
 4094 | 
 4095 | ## Why does MCP matter?
 4096 | 
 4097 | ### For AI application users
 4098 | 
 4099 | MCP means your AI applications can access the information and tools you work with every day, making them much more helpful. Rather than AI being limited to what it already knows about, it can now understand your specific documents, data, and work context.
 4100 | 
 4101 | For example, by using MCP servers, applications can access your personal documents from Google Drive or data about your codebase from GitHub, providing more personalized and contextually relevant assistance.
 4102 | 
 4103 | Imagine asking an AI assistant: "Summarize last week's team meeting notes and schedule follow-ups with everyone."
 4104 | 
 4105 | By using connections to data sources powered by MCP, the AI assistant can:
 4106 | 
 4107 | * Connect to your Google Drive through an MCP server to read meeting notes
 4108 | * Understand who needs follow-ups based on the notes
 4109 | * Connect to your calendar through another MCP server to schedule the meetings automatically
 4110 | 
 4111 | ### For developers
 4112 | 
 4113 | MCP reduces development time and complexity when building AI applications that need to access various data sources. With MCP, developers can focus on building great AI experiences rather than repeatedly creating custom connectors.
 4114 | 
 4115 | Traditionally, connecting applications with data sources required building custom, one-off connections for each data source and each application. This created significant duplicative work—every developer wanting to connect their AI application to Google Drive or Slack needed to build their own connection.
 4116 | 
 4117 | MCP simplifies this by enabling developers to build MCP servers for data sources that are then reusable by various applications. For example, using the open source Google Drive MCP server, many different applications can access data from Google Drive without each developer needing to build a custom connection.
 4118 | 
 4119 | This open source ecosystem of MCP servers means developers can leverage existing work rather than starting from scratch, making it easier to build powerful AI applications that seamlessly integrate with the tools and data sources their users already rely on.
 4120 | 
 4121 | ## How does MCP work?
 4122 | 
 4123 | <Frame>
 4124 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/mcp-simple-diagram.png" />
 4125 | </Frame>
 4126 | 
 4127 | MCP creates a bridge between your AI applications and your data through a straightforward system:
 4128 | 
 4129 | * **MCP servers** connect to your data sources and tools (like Google Drive or Slack)
 4130 | * **MCP clients** are run by AI applications (like Claude Desktop) to connect them to these servers
 4131 | * When you give permission, your AI application discovers available MCP servers
 4132 | * The AI model can then use these connections to read information and take actions
 4133 | 
 4134 | This modular system means new capabilities can be added without changing AI applications themselves—just like adding new accessories to your computer without upgrading your entire system.
 4135 | 
 4136 | ## Who creates and maintains MCP servers?
 4137 | 
 4138 | MCP servers are developed and maintained by:
 4139 | 
 4140 | * Developers at Anthropic who build servers for common tools and data sources
 4141 | * Open source contributors who create servers for tools they use
 4142 | * Enterprise development teams building servers for their internal systems
 4143 | * Software providers making their applications AI-ready
 4144 | 
 4145 | Once an open source MCP server is created for a data source, it can be used by any MCP-compatible AI application, creating a growing ecosystem of connections. See our [list of example servers](https://modelcontextprotocol.io/examples), or [get started building your own server](https://modelcontextprotocol.io/quickstart/server).
 4146 | 
 4147 | 
 4148 | # Introduction
 4149 | Source: https://modelcontextprotocol.io/introduction
 4150 | 
 4151 | Get started with the Model Context Protocol (MCP)
 4152 | 
 4153 | MCP is an open protocol that standardizes how applications provide context to LLMs. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.
 4154 | 
 4155 | ## Why MCP?
 4156 | 
 4157 | MCP helps you build agents and complex workflows on top of LLMs. LLMs frequently need to integrate with data and tools, and MCP provides:
 4158 | 
 4159 | * A growing list of pre-built integrations that your LLM can directly plug into
 4160 | * The flexibility to switch between LLM providers and vendors
 4161 | * Best practices for securing your data within your infrastructure
 4162 | 
 4163 | ### General architecture
 4164 | 
 4165 | At its core, MCP follows a client-server architecture where a host application can connect to multiple servers:
 4166 | 
 4167 | ```mermaid
 4168 | flowchart LR
 4169 |     subgraph "Your Computer"
 4170 |         Host["Host with MCP Client\n(Claude, IDEs, Tools)"]
 4171 |         S1["MCP Server A"]
 4172 |         S2["MCP Server B"]
 4173 |         S3["MCP Server C"]
 4174 |         Host <-->|"MCP Protocol"| S1
 4175 |         Host <-->|"MCP Protocol"| S2
 4176 |         Host <-->|"MCP Protocol"| S3
 4177 |         S1 <--> D1[("Local\nData Source A")]
 4178 |         S2 <--> D2[("Local\nData Source B")]
 4179 |     end
 4180 |     subgraph "Internet"
 4181 |         S3 <-->|"Web APIs"| D3[("Remote\nService C")]
 4182 |     end
 4183 | ```
 4184 | 
 4185 | * **MCP Hosts**: Programs like Claude Desktop, IDEs, or AI tools that want to access data through MCP
 4186 | * **MCP Clients**: Protocol clients that maintain 1:1 connections with servers
 4187 | * **MCP Servers**: Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol
 4188 | * **Local Data Sources**: Your computer's files, databases, and services that MCP servers can securely access
 4189 | * **Remote Services**: External systems available over the internet (e.g., through APIs) that MCP servers can connect to
 4190 | 
 4191 | ## Get started
 4192 | 
 4193 | Choose the path that best fits your needs:
 4194 | 
 4195 | ### Quick Starts
 4196 | 
 4197 | <CardGroup cols={2}>
 4198 |   <Card title="For Server Developers" icon="bolt" href="/quickstart/server">
 4199 |     Get started building your own server to use in Claude for Desktop and other
 4200 |     clients
 4201 |   </Card>
 4202 | 
 4203 |   <Card title="For Client Developers" icon="bolt" href="/quickstart/client">
 4204 |     Get started building your own client that can integrate with all MCP servers
 4205 |   </Card>
 4206 | 
 4207 |   <Card title="For Claude Desktop Users" icon="bolt" href="/quickstart/user">
 4208 |     Get started using pre-built servers in Claude for Desktop
 4209 |   </Card>
 4210 | </CardGroup>
 4211 | 
 4212 | ### Examples
 4213 | 
 4214 | <CardGroup cols={2}>
 4215 |   <Card title="Example Servers" icon="grid" href="/examples">
 4216 |     Check out our gallery of official MCP servers and implementations
 4217 |   </Card>
 4218 | 
 4219 |   <Card title="Example Clients" icon="cubes" href="/clients">
 4220 |     View the list of clients that support MCP integrations
 4221 |   </Card>
 4222 | </CardGroup>
 4223 | 
 4224 | ## Tutorials
 4225 | 
 4226 | <CardGroup cols={2}>
 4227 |   <Card title="Building MCP with LLMs" icon="comments" href="/tutorials/building-mcp-with-llms">
 4228 |     Learn how to use LLMs like Claude to speed up your MCP development
 4229 |   </Card>
 4230 | 
 4231 |   <Card title="Debugging Guide" icon="bug" href="/docs/tools/debugging">
 4232 |     Learn how to effectively debug MCP servers and integrations
 4233 |   </Card>
 4234 | 
 4235 |   <Card title="MCP Inspector" icon="magnifying-glass" href="/docs/tools/inspector">
 4236 |     Test and inspect your MCP servers with our interactive debugging tool
 4237 |   </Card>
 4238 | 
 4239 |   <Card title="MCP Workshop (Video, 2hr)" icon="person-chalkboard" href="https://www.youtube.com/watch?v=kQmXtrmQ5Zg">
 4240 |     <iframe src="https://www.youtube.com/embed/kQmXtrmQ5Zg" />
 4241 |   </Card>
 4242 | </CardGroup>
 4243 | 
 4244 | ## Explore MCP
 4245 | 
 4246 | Dive deeper into MCP's core concepts and capabilities:
 4247 | 
 4248 | <CardGroup cols={2}>
 4249 |   <Card title="Core architecture" icon="sitemap" href="/docs/concepts/architecture">
 4250 |     Understand how MCP connects clients, servers, and LLMs
 4251 |   </Card>
 4252 | 
 4253 |   <Card title="Resources" icon="database" href="/docs/concepts/resources">
 4254 |     Expose data and content from your servers to LLMs
 4255 |   </Card>
 4256 | 
 4257 |   <Card title="Prompts" icon="message" href="/docs/concepts/prompts">
 4258 |     Create reusable prompt templates and workflows
 4259 |   </Card>
 4260 | 
 4261 |   <Card title="Tools" icon="wrench" href="/docs/concepts/tools">
 4262 |     Enable LLMs to perform actions through your server
 4263 |   </Card>
 4264 | 
 4265 |   <Card title="Sampling" icon="robot" href="/docs/concepts/sampling">
 4266 |     Let your servers request completions from LLMs
 4267 |   </Card>
 4268 | 
 4269 |   <Card title="Transports" icon="network-wired" href="/docs/concepts/transports">
 4270 |     Learn about MCP's communication mechanism
 4271 |   </Card>
 4272 | </CardGroup>
 4273 | 
 4274 | ## Contributing
 4275 | 
 4276 | Want to contribute? Check out our [Contributing Guide](/development/contributing) to learn how you can help improve MCP.
 4277 | 
 4278 | ## Support and Feedback
 4279 | 
 4280 | Here's how to get help or provide feedback:
 4281 | 
 4282 | * For bug reports and feature requests related to the MCP specification, SDKs, or documentation (open source), please [create a GitHub issue](https://github.com/modelcontextprotocol)
 4283 | * For discussions or Q\&A about the MCP specification, use the [specification discussions](https://github.com/modelcontextprotocol/specification/discussions)
 4284 | * For discussions or Q\&A about other MCP open source components, use the [organization discussions](https://github.com/orgs/modelcontextprotocol/discussions)
 4285 | * For bug reports, feature requests, and questions related to Claude.app and claude.ai's MCP integration, please see Anthropic's guide on [How to Get Support](https://support.anthropic.com/en/articles/9015913-how-to-get-support)
 4286 | 
 4287 | 
 4288 | # C# SDK
 4289 | Source: https://modelcontextprotocol.io/links/sdks/csharp
 4290 | 
 4291 | 
 4292 | 
 4293 | <Card title="C# SDK" href="https://github.com/modelcontextprotocol/csharp-sdk" />
 4294 | 
 4295 | 
 4296 | # Java SDK
 4297 | Source: https://modelcontextprotocol.io/links/sdks/java
 4298 | 
 4299 | 
 4300 | 
 4301 | <Card title="Java SDK" href="https://github.com/modelcontextprotocol/java-sdk" />
 4302 | 
 4303 | 
 4304 | # Kotlin SDK
 4305 | Source: https://modelcontextprotocol.io/links/sdks/kotlin
 4306 | 
 4307 | 
 4308 | 
 4309 | <Card title="Kotlin SDK" href="https://github.com/modelcontextprotocol/kotlin-sdk" />
 4310 | 
 4311 | 
 4312 | # Python SDK
 4313 | Source: https://modelcontextprotocol.io/links/sdks/python
 4314 | 
 4315 | 
 4316 | 
 4317 | <Card title="Python SDK" href="https://github.com/modelcontextprotocol/python-sdk" />
 4318 | 
 4319 | 
 4320 | # Ruby SDK
 4321 | Source: https://modelcontextprotocol.io/links/sdks/ruby
 4322 | 
 4323 | 
 4324 | 
 4325 | <Card title="Ruby SDK" href="https://github.com/modelcontextprotocol/ruby-sdk" />
 4326 | 
 4327 | 
 4328 | # Swift SDK
 4329 | Source: https://modelcontextprotocol.io/links/sdks/swift
 4330 | 
 4331 | 
 4332 | 
 4333 | <Card title="Swift SDK" href="https://github.com/modelcontextprotocol/swift-sdk" />
 4334 | 
 4335 | 
 4336 | # TypeScript SDK
 4337 | Source: https://modelcontextprotocol.io/links/sdks/typescript
 4338 | 
 4339 | 
 4340 | 
 4341 | <Card title="TypeScript SDK" href="https://github.com/modelcontextprotocol/typescript-sdk" />
 4342 | 
 4343 | 
 4344 | # For Client Developers
 4345 | Source: https://modelcontextprotocol.io/quickstart/client
 4346 | 
 4347 | Get started building your own client that can integrate with all MCP servers.
 4348 | 
 4349 | In this tutorial, you'll learn how to build an LLM-powered chatbot client that connects to MCP servers. It helps to have gone through the [Server quickstart](/quickstart/server) that guides you through the basics of building your first server.
 4350 | 
 4351 | <Tabs>
 4352 |   <Tab title="Python">
 4353 |     [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-python)
 4354 | 
 4355 |     ## System Requirements
 4356 | 
 4357 |     Before starting, ensure your system meets these requirements:
 4358 | 
 4359 |     * Mac or Windows computer
 4360 |     * Latest Python version installed
 4361 |     * Latest version of `uv` installed
 4362 | 
 4363 |     ## Setting Up Your Environment
 4364 | 
 4365 |     First, create a new Python project with `uv`:
 4366 | 
 4367 |     ```bash
 4368 |     # Create project directory
 4369 |     uv init mcp-client
 4370 |     cd mcp-client
 4371 | 
 4372 |     # Create virtual environment
 4373 |     uv venv
 4374 | 
 4375 |     # Activate virtual environment
 4376 |     # On Windows:
 4377 |     .venv\Scripts\activate
 4378 |     # On Unix or MacOS:
 4379 |     source .venv/bin/activate
 4380 | 
 4381 |     # Install required packages
 4382 |     uv add mcp anthropic python-dotenv
 4383 | 
 4384 |     # Remove boilerplate files
 4385 |     # On Windows:
 4386 |     del main.py
 4387 |     # On Unix or MacOS:
 4388 |     rm main.py
 4389 | 
 4390 |     # Create our main file
 4391 |     touch client.py
 4392 |     ```
 4393 | 
 4394 |     ## Setting Up Your API Key
 4395 | 
 4396 |     You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys).
 4397 | 
 4398 |     Create a `.env` file to store it:
 4399 | 
 4400 |     ```bash
 4401 |     # Create .env file
 4402 |     touch .env
 4403 |     ```
 4404 | 
 4405 |     Add your key to the `.env` file:
 4406 | 
 4407 |     ```bash
 4408 |     ANTHROPIC_API_KEY=<your key here>
 4409 |     ```
 4410 | 
 4411 |     Add `.env` to your `.gitignore`:
 4412 | 
 4413 |     ```bash
 4414 |     echo ".env" >> .gitignore
 4415 |     ```
 4416 | 
 4417 |     <Warning>
 4418 |       Make sure you keep your `ANTHROPIC_API_KEY` secure!
 4419 |     </Warning>
 4420 | 
 4421 |     ## Creating the Client
 4422 | 
 4423 |     ### Basic Client Structure
 4424 | 
 4425 |     First, let's set up our imports and create the basic client class:
 4426 | 
 4427 |     ```python
 4428 |     import asyncio
 4429 |     from typing import Optional
 4430 |     from contextlib import AsyncExitStack
 4431 | 
 4432 |     from mcp import ClientSession, StdioServerParameters
 4433 |     from mcp.client.stdio import stdio_client
 4434 | 
 4435 |     from anthropic import Anthropic
 4436 |     from dotenv import load_dotenv
 4437 | 
 4438 |     load_dotenv()  # load environment variables from .env
 4439 | 
 4440 |     class MCPClient:
 4441 |         def __init__(self):
 4442 |             # Initialize session and client objects
 4443 |             self.session: Optional[ClientSession] = None
 4444 |             self.exit_stack = AsyncExitStack()
 4445 |             self.anthropic = Anthropic()
 4446 |         # methods will go here
 4447 |     ```
 4448 | 
 4449 |     ### Server Connection Management
 4450 | 
 4451 |     Next, we'll implement the method to connect to an MCP server:
 4452 | 
 4453 |     ```python
 4454 |     async def connect_to_server(self, server_script_path: str):
 4455 |         """Connect to an MCP server
 4456 | 
 4457 |         Args:
 4458 |             server_script_path: Path to the server script (.py or .js)
 4459 |         """
 4460 |         is_python = server_script_path.endswith('.py')
 4461 |         is_js = server_script_path.endswith('.js')
 4462 |         if not (is_python or is_js):
 4463 |             raise ValueError("Server script must be a .py or .js file")
 4464 | 
 4465 |         command = "python" if is_python else "node"
 4466 |         server_params = StdioServerParameters(
 4467 |             command=command,
 4468 |             args=[server_script_path],
 4469 |             env=None
 4470 |         )
 4471 | 
 4472 |         stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
 4473 |         self.stdio, self.write = stdio_transport
 4474 |         self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
 4475 | 
 4476 |         await self.session.initialize()
 4477 | 
 4478 |         # List available tools
 4479 |         response = await self.session.list_tools()
 4480 |         tools = response.tools
 4481 |         print("\nConnected to server with tools:", [tool.name for tool in tools])
 4482 |     ```
 4483 | 
 4484 |     ### Query Processing Logic
 4485 | 
 4486 |     Now let's add the core functionality for processing queries and handling tool calls:
 4487 | 
 4488 |     ```python
 4489 |     async def process_query(self, query: str) -> str:
 4490 |         """Process a query using Claude and available tools"""
 4491 |         messages = [
 4492 |             {
 4493 |                 "role": "user",
 4494 |                 "content": query
 4495 |             }
 4496 |         ]
 4497 | 
 4498 |         response = await self.session.list_tools()
 4499 |         available_tools = [{
 4500 |             "name": tool.name,
 4501 |             "description": tool.description,
 4502 |             "input_schema": tool.inputSchema
 4503 |         } for tool in response.tools]
 4504 | 
 4505 |         # Initial Claude API call
 4506 |         response = self.anthropic.messages.create(
 4507 |             model="claude-3-5-sonnet-20241022",
 4508 |             max_tokens=1000,
 4509 |             messages=messages,
 4510 |             tools=available_tools
 4511 |         )
 4512 | 
 4513 |         # Process response and handle tool calls
 4514 |         final_text = []
 4515 | 
 4516 |         assistant_message_content = []
 4517 |         for content in response.content:
 4518 |             if content.type == 'text':
 4519 |                 final_text.append(content.text)
 4520 |                 assistant_message_content.append(content)
 4521 |             elif content.type == 'tool_use':
 4522 |                 tool_name = content.name
 4523 |                 tool_args = content.input
 4524 | 
 4525 |                 # Execute tool call
 4526 |                 result = await self.session.call_tool(tool_name, tool_args)
 4527 |                 final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")
 4528 | 
 4529 |                 assistant_message_content.append(content)
 4530 |                 messages.append({
 4531 |                     "role": "assistant",
 4532 |                     "content": assistant_message_content
 4533 |                 })
 4534 |                 messages.append({
 4535 |                     "role": "user",
 4536 |                     "content": [
 4537 |                         {
 4538 |                             "type": "tool_result",
 4539 |                             "tool_use_id": content.id,
 4540 |                             "content": result.content
 4541 |                         }
 4542 |                     ]
 4543 |                 })
 4544 | 
 4545 |                 # Get next response from Claude
 4546 |                 response = self.anthropic.messages.create(
 4547 |                     model="claude-3-5-sonnet-20241022",
 4548 |                     max_tokens=1000,
 4549 |                     messages=messages,
 4550 |                     tools=available_tools
 4551 |                 )
 4552 | 
 4553 |                 final_text.append(response.content[0].text)
 4554 | 
 4555 |         return "\n".join(final_text)
 4556 |     ```
 4557 | 
 4558 |     ### Interactive Chat Interface
 4559 | 
 4560 |     Now we'll add the chat loop and cleanup functionality:
 4561 | 
 4562 |     ```python
 4563 |     async def chat_loop(self):
 4564 |         """Run an interactive chat loop"""
 4565 |         print("\nMCP Client Started!")
 4566 |         print("Type your queries or 'quit' to exit.")
 4567 | 
 4568 |         while True:
 4569 |             try:
 4570 |                 query = input("\nQuery: ").strip()
 4571 | 
 4572 |                 if query.lower() == 'quit':
 4573 |                     break
 4574 | 
 4575 |                 response = await self.process_query(query)
 4576 |                 print("\n" + response)
 4577 | 
 4578 |             except Exception as e:
 4579 |                 print(f"\nError: {str(e)}")
 4580 | 
 4581 |     async def cleanup(self):
 4582 |         """Clean up resources"""
 4583 |         await self.exit_stack.aclose()
 4584 |     ```
 4585 | 
 4586 |     ### Main Entry Point
 4587 | 
 4588 |     Finally, we'll add the main execution logic:
 4589 | 
 4590 |     ```python
 4591 |     async def main():
 4592 |         if len(sys.argv) < 2:
 4593 |             print("Usage: python client.py <path_to_server_script>")
 4594 |             sys.exit(1)
 4595 | 
 4596 |         client = MCPClient()
 4597 |         try:
 4598 |             await client.connect_to_server(sys.argv[1])
 4599 |             await client.chat_loop()
 4600 |         finally:
 4601 |             await client.cleanup()
 4602 | 
 4603 |     if __name__ == "__main__":
 4604 |         import sys
 4605 |         asyncio.run(main())
 4606 |     ```
 4607 | 
 4608 |     You can find the complete `client.py` file [here.](https://gist.github.com/zckly/f3f28ea731e096e53b39b47bf0a2d4b1)
 4609 | 
 4610 |     ## Key Components Explained
 4611 | 
 4612 |     ### 1. Client Initialization
 4613 | 
 4614 |     * The `MCPClient` class initializes with session management and API clients
 4615 |     * Uses `AsyncExitStack` for proper resource management
 4616 |     * Configures the Anthropic client for Claude interactions
 4617 | 
 4618 |     ### 2. Server Connection
 4619 | 
 4620 |     * Supports both Python and Node.js servers
 4621 |     * Validates server script type
 4622 |     * Sets up proper communication channels
 4623 |     * Initializes the session and lists available tools
 4624 | 
 4625 |     ### 3. Query Processing
 4626 | 
 4627 |     * Maintains conversation context
 4628 |     * Handles Claude's responses and tool calls
 4629 |     * Manages the message flow between Claude and tools
 4630 |     * Combines results into a coherent response
 4631 | 
 4632 |     ### 4. Interactive Interface
 4633 | 
 4634 |     * Provides a simple command-line interface
 4635 |     * Handles user input and displays responses
 4636 |     * Includes basic error handling
 4637 |     * Allows graceful exit
 4638 | 
 4639 |     ### 5. Resource Management
 4640 | 
 4641 |     * Proper cleanup of resources
 4642 |     * Error handling for connection issues
 4643 |     * Graceful shutdown procedures
 4644 | 
 4645 |     ## Common Customization Points
 4646 | 
 4647 |     1. **Tool Handling**
 4648 | 
 4649 |        * Modify `process_query()` to handle specific tool types
 4650 |        * Add custom error handling for tool calls
 4651 |        * Implement tool-specific response formatting
 4652 | 
 4653 |     2. **Response Processing**
 4654 | 
 4655 |        * Customize how tool results are formatted
 4656 |        * Add response filtering or transformation
 4657 |        * Implement custom logging
 4658 | 
 4659 |     3. **User Interface**
 4660 |        * Add a GUI or web interface
 4661 |        * Implement rich console output
 4662 |        * Add command history or auto-completion
 4663 | 
 4664 |     ## Running the Client
 4665 | 
 4666 |     To run your client with any MCP server:
 4667 | 
 4668 |     ```bash
 4669 |     uv run client.py path/to/server.py # python server
 4670 |     uv run client.py path/to/build/index.js # node server
 4671 |     ```
 4672 | 
 4673 |     <Note>
 4674 |       If you're continuing the weather tutorial from the server quickstart, your command might look something like this: `python client.py .../quickstart-resources/weather-server-python/weather.py`
 4675 |     </Note>
 4676 | 
 4677 |     The client will:
 4678 | 
 4679 |     1. Connect to the specified server
 4680 |     2. List available tools
 4681 |     3. Start an interactive chat session where you can:
 4682 |        * Enter queries
 4683 |        * See tool executions
 4684 |        * Get responses from Claude
 4685 | 
 4686 |     Here's an example of what it should look like if connected to the weather server from the server quickstart:
 4687 | 
 4688 |     <Frame>
 4689 |       <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/client-claude-cli-python.png" />
 4690 |     </Frame>
 4691 | 
 4692 |     ## How It Works
 4693 | 
 4694 |     When you submit a query:
 4695 | 
 4696 |     1. The client gets the list of available tools from the server
 4697 |     2. Your query is sent to Claude along with tool descriptions
 4698 |     3. Claude decides which tools (if any) to use
 4699 |     4. The client executes any requested tool calls through the server
 4700 |     5. Results are sent back to Claude
 4701 |     6. Claude provides a natural language response
 4702 |     7. The response is displayed to you
 4703 | 
 4704 |     ## Best practices
 4705 | 
 4706 |     1. **Error Handling**
 4707 | 
 4708 |        * Always wrap tool calls in try-catch blocks
 4709 |        * Provide meaningful error messages
 4710 |        * Gracefully handle connection issues
 4711 | 
 4712 |     2. **Resource Management**
 4713 | 
 4714 |        * Use `AsyncExitStack` for proper cleanup
 4715 |        * Close connections when done
 4716 |        * Handle server disconnections
 4717 | 
 4718 |     3. **Security**
 4719 |        * Store API keys securely in `.env`
 4720 |        * Validate server responses
 4721 |        * Be cautious with tool permissions
 4722 | 
 4723 |     ## Troubleshooting
 4724 | 
 4725 |     ### Server Path Issues
 4726 | 
 4727 |     * Double-check the path to your server script is correct
 4728 |     * Use the absolute path if the relative path isn't working
 4729 |     * For Windows users, make sure to use forward slashes (/) or escaped backslashes (\\) in the path
 4730 |     * Verify the server file has the correct extension (.py for Python or .js for Node.js)
 4731 | 
 4732 |     Example of correct path usage:
 4733 | 
 4734 |     ```bash
 4735 |     # Relative path
 4736 |     uv run client.py ./server/weather.py
 4737 | 
 4738 |     # Absolute path
 4739 |     uv run client.py /Users/username/projects/mcp-server/weather.py
 4740 | 
 4741 |     # Windows path (either format works)
 4742 |     uv run client.py C:/projects/mcp-server/weather.py
 4743 |     uv run client.py C:\\projects\\mcp-server\\weather.py
 4744 |     ```
 4745 | 
 4746 |     ### Response Timing
 4747 | 
 4748 |     * The first response might take up to 30 seconds to return
 4749 |     * This is normal and happens while:
 4750 |       * The server initializes
 4751 |       * Claude processes the query
 4752 |       * Tools are being executed
 4753 |     * Subsequent responses are typically faster
 4754 |     * Don't interrupt the process during this initial waiting period
 4755 | 
 4756 |     ### Common Error Messages
 4757 | 
 4758 |     If you see:
 4759 | 
 4760 |     * `FileNotFoundError`: Check your server path
 4761 |     * `Connection refused`: Ensure the server is running and the path is correct
 4762 |     * `Tool execution failed`: Verify the tool's required environment variables are set
 4763 |     * `Timeout error`: Consider increasing the timeout in your client configuration
 4764 |   </Tab>
 4765 | 
 4766 |   <Tab title="Node">
 4767 |     [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-typescript)
 4768 | 
 4769 |     ## System Requirements
 4770 | 
 4771 |     Before starting, ensure your system meets these requirements:
 4772 | 
 4773 |     * Mac or Windows computer
 4774 |     * Node.js 17 or higher installed
 4775 |     * Latest version of `npm` installed
 4776 |     * Anthropic API key (Claude)
 4777 | 
 4778 |     ## Setting Up Your Environment
 4779 | 
 4780 |     First, let's create and set up our project:
 4781 | 
 4782 |     <CodeGroup>
 4783 |       ```bash MacOS/Linux
 4784 |       # Create project directory
 4785 |       mkdir mcp-client-typescript
 4786 |       cd mcp-client-typescript
 4787 | 
 4788 |       # Initialize npm project
 4789 |       npm init -y
 4790 | 
 4791 |       # Install dependencies
 4792 |       npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv
 4793 | 
 4794 |       # Install dev dependencies
 4795 |       npm install -D @types/node typescript
 4796 | 
 4797 |       # Create source file
 4798 |       touch index.ts
 4799 |       ```
 4800 | 
 4801 |       ```powershell Windows
 4802 |       # Create project directory
 4803 |       md mcp-client-typescript
 4804 |       cd mcp-client-typescript
 4805 | 
 4806 |       # Initialize npm project
 4807 |       npm init -y
 4808 | 
 4809 |       # Install dependencies
 4810 |       npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv
 4811 | 
 4812 |       # Install dev dependencies
 4813 |       npm install -D @types/node typescript
 4814 | 
 4815 |       # Create source file
 4816 |       new-item index.ts
 4817 |       ```
 4818 |     </CodeGroup>
 4819 | 
 4820 |     Update your `package.json` to set `type: "module"` and a build script:
 4821 | 
 4822 |     ```json package.json
 4823 |     {
 4824 |       "type": "module",
 4825 |       "scripts": {
 4826 |         "build": "tsc && chmod 755 build/index.js"
 4827 |       }
 4828 |     }
 4829 |     ```
 4830 | 
 4831 |     Create a `tsconfig.json` in the root of your project:
 4832 | 
 4833 |     ```json tsconfig.json
 4834 |     {
 4835 |       "compilerOptions": {
 4836 |         "target": "ES2022",
 4837 |         "module": "Node16",
 4838 |         "moduleResolution": "Node16",
 4839 |         "outDir": "./build",
 4840 |         "rootDir": "./",
 4841 |         "strict": true,
 4842 |         "esModuleInterop": true,
 4843 |         "skipLibCheck": true,
 4844 |         "forceConsistentCasingInFileNames": true
 4845 |       },
 4846 |       "include": ["index.ts"],
 4847 |       "exclude": ["node_modules"]
 4848 |     }
 4849 |     ```
 4850 | 
 4851 |     ## Setting Up Your API Key
 4852 | 
 4853 |     You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys).
 4854 | 
 4855 |     Create a `.env` file to store it:
 4856 | 
 4857 |     ```bash
 4858 |     echo "ANTHROPIC_API_KEY=<your key here>" > .env
 4859 |     ```
 4860 | 
 4861 |     Add `.env` to your `.gitignore`:
 4862 | 
 4863 |     ```bash
 4864 |     echo ".env" >> .gitignore
 4865 |     ```
 4866 | 
 4867 |     <Warning>
 4868 |       Make sure you keep your `ANTHROPIC_API_KEY` secure!
 4869 |     </Warning>
 4870 | 
 4871 |     ## Creating the Client
 4872 | 
 4873 |     ### Basic Client Structure
 4874 | 
 4875 |     First, let's set up our imports and create the basic client class in `index.ts`:
 4876 | 
 4877 |     ```typescript
 4878 |     import { Anthropic } from "@anthropic-ai/sdk";
 4879 |     import {
 4880 |       MessageParam,
 4881 |       Tool,
 4882 |     } from "@anthropic-ai/sdk/resources/messages/messages.mjs";
 4883 |     import { Client } from "@modelcontextprotocol/sdk/client/index.js";
 4884 |     import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
 4885 |     import readline from "readline/promises";
 4886 |     import dotenv from "dotenv";
 4887 | 
 4888 |     dotenv.config();
 4889 | 
 4890 |     const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
 4891 |     if (!ANTHROPIC_API_KEY) {
 4892 |       throw new Error("ANTHROPIC_API_KEY is not set");
 4893 |     }
 4894 | 
 4895 |     class MCPClient {
 4896 |       private mcp: Client;
 4897 |       private anthropic: Anthropic;
 4898 |       private transport: StdioClientTransport | null = null;
 4899 |       private tools: Tool[] = [];
 4900 | 
 4901 |       constructor() {
 4902 |         this.anthropic = new Anthropic({
 4903 |           apiKey: ANTHROPIC_API_KEY,
 4904 |         });
 4905 |         this.mcp = new Client({ name: "mcp-client-cli", version: "1.0.0" });
 4906 |       }
 4907 |       // methods will go here
 4908 |     }
 4909 |     ```
 4910 | 
 4911 |     ### Server Connection Management
 4912 | 
 4913 |     Next, we'll implement the method to connect to an MCP server:
 4914 | 
 4915 |     ```typescript
 4916 |     async connectToServer(serverScriptPath: string) {
 4917 |       try {
 4918 |         const isJs = serverScriptPath.endsWith(".js");
 4919 |         const isPy = serverScriptPath.endsWith(".py");
 4920 |         if (!isJs && !isPy) {
 4921 |           throw new Error("Server script must be a .js or .py file");
 4922 |         }
 4923 |         const command = isPy
 4924 |           ? process.platform === "win32"
 4925 |             ? "python"
 4926 |             : "python3"
 4927 |           : process.execPath;
 4928 | 
 4929 |         this.transport = new StdioClientTransport({
 4930 |           command,
 4931 |           args: [serverScriptPath],
 4932 |         });
 4933 |         await this.mcp.connect(this.transport);
 4934 | 
 4935 |         const toolsResult = await this.mcp.listTools();
 4936 |         this.tools = toolsResult.tools.map((tool) => {
 4937 |           return {
 4938 |             name: tool.name,
 4939 |             description: tool.description,
 4940 |             input_schema: tool.inputSchema,
 4941 |           };
 4942 |         });
 4943 |         console.log(
 4944 |           "Connected to server with tools:",
 4945 |           this.tools.map(({ name }) => name)
 4946 |         );
 4947 |       } catch (e) {
 4948 |         console.log("Failed to connect to MCP server: ", e);
 4949 |         throw e;
 4950 |       }
 4951 |     }
 4952 |     ```
 4953 | 
 4954 |     ### Query Processing Logic
 4955 | 
 4956 |     Now let's add the core functionality for processing queries and handling tool calls:
 4957 | 
 4958 |     ```typescript
 4959 |     async processQuery(query: string) {
 4960 |       const messages: MessageParam[] = [
 4961 |         {
 4962 |           role: "user",
 4963 |           content: query,
 4964 |         },
 4965 |       ];
 4966 | 
 4967 |       const response = await this.anthropic.messages.create({
 4968 |         model: "claude-3-5-sonnet-20241022",
 4969 |         max_tokens: 1000,
 4970 |         messages,
 4971 |         tools: this.tools,
 4972 |       });
 4973 | 
 4974 |       const finalText = [];
 4975 | 
 4976 |       for (const content of response.content) {
 4977 |         if (content.type === "text") {
 4978 |           finalText.push(content.text);
 4979 |         } else if (content.type === "tool_use") {
 4980 |           const toolName = content.name;
 4981 |           const toolArgs = content.input as { [x: string]: unknown } | undefined;
 4982 | 
 4983 |           const result = await this.mcp.callTool({
 4984 |             name: toolName,
 4985 |             arguments: toolArgs,
 4986 |           });
 4987 |           finalText.push(
 4988 |             `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`
 4989 |           );
 4990 | 
 4991 |           messages.push({
 4992 |             role: "user",
 4993 |             content: result.content as string,
 4994 |           });
 4995 | 
 4996 |           const response = await this.anthropic.messages.create({
 4997 |             model: "claude-3-5-sonnet-20241022",
 4998 |             max_tokens: 1000,
 4999 |             messages,
 5000 |           });
 5001 | 
 5002 |           finalText.push(
 5003 |             response.content[0].type === "text" ? response.content[0].text : ""
 5004 |           );
 5005 |         }
 5006 |       }
 5007 | 
 5008 |       return finalText.join("\n");
 5009 |     }
 5010 |     ```
 5011 | 
 5012 |     ### Interactive Chat Interface
 5013 | 
 5014 |     Now we'll add the chat loop and cleanup functionality:
 5015 | 
 5016 |     ```typescript
 5017 |     async chatLoop() {
 5018 |       const rl = readline.createInterface({
 5019 |         input: process.stdin,
 5020 |         output: process.stdout,
 5021 |       });
 5022 | 
 5023 |       try {
 5024 |         console.log("\nMCP Client Started!");
 5025 |         console.log("Type your queries or 'quit' to exit.");
 5026 | 
 5027 |         while (true) {
 5028 |           const message = await rl.question("\nQuery: ");
 5029 |           if (message.toLowerCase() === "quit") {
 5030 |             break;
 5031 |           }
 5032 |           const response = await this.processQuery(message);
 5033 |           console.log("\n" + response);
 5034 |         }
 5035 |       } finally {
 5036 |         rl.close();
 5037 |       }
 5038 |     }
 5039 | 
 5040 |     async cleanup() {
 5041 |       await this.mcp.close();
 5042 |     }
 5043 |     ```
 5044 | 
 5045 |     ### Main Entry Point
 5046 | 
 5047 |     Finally, we'll add the main execution logic:
 5048 | 
 5049 |     ```typescript
 5050 |     async function main() {
 5051 |       if (process.argv.length < 3) {
 5052 |         console.log("Usage: node index.ts <path_to_server_script>");
 5053 |         return;
 5054 |       }
 5055 |       const mcpClient = new MCPClient();
 5056 |       try {
 5057 |         await mcpClient.connectToServer(process.argv[2]);
 5058 |         await mcpClient.chatLoop();
 5059 |       } finally {
 5060 |         await mcpClient.cleanup();
 5061 |         process.exit(0);
 5062 |       }
 5063 |     }
 5064 | 
 5065 |     main();
 5066 |     ```
 5067 | 
 5068 |     ## Running the Client
 5069 | 
 5070 |     To run your client with any MCP server:
 5071 | 
 5072 |     ```bash
 5073 |     # Build TypeScript
 5074 |     npm run build
 5075 | 
 5076 |     # Run the client
 5077 |     node build/index.js path/to/server.py # python server
 5078 |     node build/index.js path/to/build/index.js # node server
 5079 |     ```
 5080 | 
 5081 |     <Note>
 5082 |       If you're continuing the weather tutorial from the server quickstart, your command might look something like this: `node build/index.js .../quickstart-resources/weather-server-typescript/build/index.js`
 5083 |     </Note>
 5084 | 
 5085 |     **The client will:**
 5086 | 
 5087 |     1. Connect to the specified server
 5088 |     2. List available tools
 5089 |     3. Start an interactive chat session where you can:
 5090 |        * Enter queries
 5091 |        * See tool executions
 5092 |        * Get responses from Claude
 5093 | 
 5094 |     ## How It Works
 5095 | 
 5096 |     When you submit a query:
 5097 | 
 5098 |     1. The client gets the list of available tools from the server
 5099 |     2. Your query is sent to Claude along with tool descriptions
 5100 |     3. Claude decides which tools (if any) to use
 5101 |     4. The client executes any requested tool calls through the server
 5102 |     5. Results are sent back to Claude
 5103 |     6. Claude provides a natural language response
 5104 |     7. The response is displayed to you
 5105 | 
 5106 |     ## Best practices
 5107 | 
 5108 |     1. **Error Handling**
 5109 | 
 5110 |        * Use TypeScript's type system for better error detection
 5111 |        * Wrap tool calls in try-catch blocks
 5112 |        * Provide meaningful error messages
 5113 |        * Gracefully handle connection issues
 5114 | 
 5115 |     2. **Security**
 5116 |        * Store API keys securely in `.env`
 5117 |        * Validate server responses
 5118 |        * Be cautious with tool permissions
 5119 | 
 5120 |     ## Troubleshooting
 5121 | 
 5122 |     ### Server Path Issues
 5123 | 
 5124 |     * Double-check the path to your server script is correct
 5125 |     * Use the absolute path if the relative path isn't working
 5126 |     * For Windows users, make sure to use forward slashes (/) or escaped backslashes (\\) in the path
 5127 |     * Verify the server file has the correct extension (.js for Node.js or .py for Python)
 5128 | 
 5129 |     Example of correct path usage:
 5130 | 
 5131 |     ```bash
 5132 |     # Relative path
 5133 |     node build/index.js ./server/build/index.js
 5134 | 
 5135 |     # Absolute path
 5136 |     node build/index.js /Users/username/projects/mcp-server/build/index.js
 5137 | 
 5138 |     # Windows path (either format works)
 5139 |     node build/index.js C:/projects/mcp-server/build/index.js
 5140 |     node build/index.js C:\\projects\\mcp-server\\build\\index.js
 5141 |     ```
 5142 | 
 5143 |     ### Response Timing
 5144 | 
 5145 |     * The first response might take up to 30 seconds to return
 5146 |     * This is normal and happens while:
 5147 |       * The server initializes
 5148 |       * Claude processes the query
 5149 |       * Tools are being executed
 5150 |     * Subsequent responses are typically faster
 5151 |     * Don't interrupt the process during this initial waiting period
 5152 | 
 5153 |     ### Common Error Messages
 5154 | 
 5155 |     If you see:
 5156 | 
 5157 |     * `Error: Cannot find module`: Check your build folder and ensure TypeScript compilation succeeded
 5158 |     * `Connection refused`: Ensure the server is running and the path is correct
 5159 |     * `Tool execution failed`: Verify the tool's required environment variables are set
 5160 |     * `ANTHROPIC_API_KEY is not set`: Check your .env file and environment variables
 5161 |     * `TypeError`: Ensure you're using the correct types for tool arguments
 5162 |   </Tab>
 5163 | 
 5164 |   <Tab title="Java">
 5165 |     <Note>
 5166 |       This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters.
 5167 |       To learn how to create sync and async MCP Clients manually, consult the [Java SDK Client](/sdk/java/mcp-client) documentation
 5168 |     </Note>
 5169 | 
 5170 |     This example demonstrates how to build an interactive chatbot that combines Spring AI's Model Context Protocol (MCP) with the [Brave Search MCP Server](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/brave-search). The application creates a conversational interface powered by Anthropic's Claude AI model that can perform internet searches through Brave Search, enabling natural language interactions with real-time web data.
 5171 |     [You can find the complete code for this tutorial here.](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/web-search/brave-chatbot)
 5172 | 
 5173 |     ## System Requirements
 5174 | 
 5175 |     Before starting, ensure your system meets these requirements:
 5176 | 
 5177 |     * Java 17 or higher
 5178 |     * Maven 3.6+
 5179 |     * npx package manager
 5180 |     * Anthropic API key (Claude)
 5181 |     * Brave Search API key
 5182 | 
 5183 |     ## Setting Up Your Environment
 5184 | 
 5185 |     1. Install npx (Node Package eXecute):
 5186 |        First, make sure to install [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
 5187 |        and then run:
 5188 | 
 5189 |        ```bash
 5190 |        npm install -g npx
 5191 |        ```
 5192 | 
 5193 |     2. Clone the repository:
 5194 | 
 5195 |        ```bash
 5196 |        git clone https://github.com/spring-projects/spring-ai-examples.git
 5197 |        cd model-context-protocol/brave-chatbot
 5198 |        ```
 5199 | 
 5200 |     3. Set up your API keys:
 5201 | 
 5202 |        ```bash
 5203 |        export ANTHROPIC_API_KEY='your-anthropic-api-key-here'
 5204 |        export BRAVE_API_KEY='your-brave-api-key-here'
 5205 |        ```
 5206 | 
 5207 |     4. Build the application:
 5208 | 
 5209 |        ```bash
 5210 |        ./mvnw clean install
 5211 |        ```
 5212 | 
 5213 |     5. Run the application using Maven:
 5214 |        ```bash
 5215 |        ./mvnw spring-boot:run
 5216 |        ```
 5217 | 
 5218 |     <Warning>
 5219 |       Make sure you keep your `ANTHROPIC_API_KEY` and `BRAVE_API_KEY` keys secure!
 5220 |     </Warning>
 5221 | 
 5222 |     ## How it Works
 5223 | 
 5224 |     The application integrates Spring AI with the Brave Search MCP server through several components:
 5225 | 
 5226 |     ### MCP Client Configuration
 5227 | 
 5228 |     1. Required dependencies in pom.xml:
 5229 | 
 5230 |     ```xml
 5231 |     <dependency>
 5232 |         <groupId>org.springframework.ai</groupId>
 5233 |         <artifactId>spring-ai-starter-mcp-client</artifactId>
 5234 |     </dependency>
 5235 |     <dependency>
 5236 |         <groupId>org.springframework.ai</groupId>
 5237 |         <artifactId>spring-ai-starter-model-anthropic</artifactId>
 5238 |     </dependency>
 5239 |     ```
 5240 | 
 5241 |     2. Application properties (application.yml):
 5242 | 
 5243 |     ```yml
 5244 |     spring:
 5245 |       ai:
 5246 |         mcp:
 5247 |           client:
 5248 |             enabled: true
 5249 |             name: brave-search-client
 5250 |             version: 1.0.0
 5251 |             type: SYNC
 5252 |             request-timeout: 20s
 5253 |             stdio:
 5254 |               root-change-notification: true
 5255 |               servers-configuration: classpath:/mcp-servers-config.json
 5256 |             toolcallback:
 5257 |               enabled: true
 5258 |         anthropic:
 5259 |           api-key: ${ANTHROPIC_API_KEY}
 5260 |     ```
 5261 | 
 5262 |     This activates the `spring-ai-starter-mcp-client` to create one or more `McpClient`s based on the provided server configuration.
 5263 |     The `spring.ai.mcp.client.toolcallback.enabled=true` property enables the tool callback mechanism, that automatically registers all MCP tool as spring ai tools.
 5264 |     It is disabled by default.
 5265 | 
 5266 |     3. MCP Server Configuration (`mcp-servers-config.json`):
 5267 | 
 5268 |     ```json
 5269 |     {
 5270 |       "mcpServers": {
 5271 |         "brave-search": {
 5272 |           "command": "npx",
 5273 |           "args": ["-y", "@modelcontextprotocol/server-brave-search"],
 5274 |           "env": {
 5275 |             "BRAVE_API_KEY": "<PUT YOUR BRAVE API KEY>"
 5276 |           }
 5277 |         }
 5278 |       }
 5279 |     }
 5280 |     ```
 5281 | 
 5282 |     ### Chat Implementation
 5283 | 
 5284 |     The chatbot is implemented using Spring AI's ChatClient with MCP tool integration:
 5285 | 
 5286 |     ```java
 5287 |     var chatClient = chatClientBuilder
 5288 |         .defaultSystem("You are useful assistant, expert in AI and Java.")
 5289 |         .defaultToolCallbacks((Object[]) mcpToolAdapter.toolCallbacks())
 5290 |         .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
 5291 |         .build();
 5292 |     ```
 5293 | 
 5294 |     <Warning>
 5295 |       Breaking change: From SpringAI 1.0.0-M8 onwards, use `.defaultToolCallbacks(...)` instead of `.defaultTool(...)` to register MCP tools.
 5296 |     </Warning>
 5297 | 
 5298 |     Key features:
 5299 | 
 5300 |     * Uses Claude AI model for natural language understanding
 5301 |     * Integrates Brave Search through MCP for real-time web search capabilities
 5302 |     * Maintains conversation memory using InMemoryChatMemory
 5303 |     * Runs as an interactive command-line application
 5304 | 
 5305 |     ### Build and run
 5306 | 
 5307 |     ```bash
 5308 |     ./mvnw clean install
 5309 |     java -jar ./target/ai-mcp-brave-chatbot-0.0.1-SNAPSHOT.jar
 5310 |     ```
 5311 | 
 5312 |     or
 5313 | 
 5314 |     ```bash
 5315 |     ./mvnw spring-boot:run
 5316 |     ```
 5317 | 
 5318 |     The application will start an interactive chat session where you can ask questions. The chatbot will use Brave Search when it needs to find information from the internet to answer your queries.
 5319 | 
 5320 |     The chatbot can:
 5321 | 
 5322 |     * Answer questions using its built-in knowledge
 5323 |     * Perform web searches when needed using Brave Search
 5324 |     * Remember context from previous messages in the conversation
 5325 |     * Combine information from multiple sources to provide comprehensive answers
 5326 | 
 5327 |     ### Advanced Configuration
 5328 | 
 5329 |     The MCP client supports additional configuration options:
 5330 | 
 5331 |     * Client customization through `McpSyncClientCustomizer` or `McpAsyncClientCustomizer`
 5332 |     * Multiple clients with multiple transport types: `STDIO` and `SSE` (Server-Sent Events)
 5333 |     * Integration with Spring AI's tool execution framework
 5334 |     * Automatic client initialization and lifecycle management
 5335 | 
 5336 |     For WebFlux-based applications, you can use the WebFlux starter instead:
 5337 | 
 5338 |     ```xml
 5339 |     <dependency>
 5340 |         <groupId>org.springframework.ai</groupId>
 5341 |         <artifactId>spring-ai-mcp-client-webflux-spring-boot-starter</artifactId>
 5342 |     </dependency>
 5343 |     ```
 5344 | 
 5345 |     This provides similar functionality but uses a WebFlux-based SSE transport implementation, recommended for production deployments.
 5346 |   </Tab>
 5347 | 
 5348 |   <Tab title="Kotlin">
 5349 |     [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/kotlin-mcp-client)
 5350 | 
 5351 |     ## System Requirements
 5352 | 
 5353 |     Before starting, ensure your system meets these requirements:
 5354 | 
 5355 |     * Java 17 or higher
 5356 |     * Anthropic API key (Claude)
 5357 | 
 5358 |     ## Setting up your environment
 5359 | 
 5360 |     First, let's install `java` and `gradle` if you haven't already.
 5361 |     You can download `java` from [official Oracle JDK website](https://www.oracle.com/java/technologies/downloads/).
 5362 |     Verify your `java` installation:
 5363 | 
 5364 |     ```bash
 5365 |     java --version
 5366 |     ```
 5367 | 
 5368 |     Now, let's create and set up your project:
 5369 | 
 5370 |     <CodeGroup>
 5371 |       ```bash MacOS/Linux
 5372 |       # Create a new directory for our project
 5373 |       mkdir kotlin-mcp-client
 5374 |       cd kotlin-mcp-client
 5375 | 
 5376 |       # Initialize a new kotlin project
 5377 |       gradle init
 5378 |       ```
 5379 | 
 5380 |       ```powershell Windows
 5381 |       # Create a new directory for our project
 5382 |       md kotlin-mcp-client
 5383 |       cd kotlin-mcp-client
 5384 |       # Initialize a new kotlin project
 5385 |       gradle init
 5386 |       ```
 5387 |     </CodeGroup>
 5388 | 
 5389 |     After running `gradle init`, you will be presented with options for creating your project.
 5390 |     Select **Application** as the project type, **Kotlin** as the programming language, and **Java 17** as the Java version.
 5391 | 
 5392 |     Alternatively, you can create a Kotlin application using the [IntelliJ IDEA project wizard](https://kotlinlang.org/docs/jvm-get-started.html).
 5393 | 
 5394 |     After creating the project, add the following dependencies:
 5395 | 
 5396 |     <CodeGroup>
 5397 |       ```kotlin build.gradle.kts
 5398 |       val mcpVersion = "0.4.0"
 5399 |       val slf4jVersion = "2.0.9"
 5400 |       val anthropicVersion = "0.8.0"
 5401 | 
 5402 |       dependencies {
 5403 |           implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
 5404 |           implementation("org.slf4j:slf4j-nop:$slf4jVersion")
 5405 |           implementation("com.anthropic:anthropic-java:$anthropicVersion")
 5406 |       }
 5407 |       ```
 5408 | 
 5409 |       ```groovy build.gradle
 5410 |       def mcpVersion = '0.3.0'
 5411 |       def slf4jVersion = '2.0.9'
 5412 |       def anthropicVersion = '0.8.0'
 5413 |       dependencies {
 5414 |           implementation "io.modelcontextprotocol:kotlin-sdk:$mcpVersion"
 5415 |           implementation "org.slf4j:slf4j-nop:$slf4jVersion"
 5416 |           implementation "com.anthropic:anthropic-java:$anthropicVersion"
 5417 |       }
 5418 |       ```
 5419 |     </CodeGroup>
 5420 | 
 5421 |     Also, add the following plugins to your build script:
 5422 | 
 5423 |     <CodeGroup>
 5424 |       ```kotlin build.gradle.kts
 5425 |       plugins {
 5426 |           id("com.github.johnrengelman.shadow") version "8.1.1"
 5427 |       }
 5428 |       ```
 5429 | 
 5430 |       ```groovy build.gradle
 5431 |       plugins {
 5432 |           id 'com.github.johnrengelman.shadow' version '8.1.1'
 5433 |       }
 5434 |       ```
 5435 |     </CodeGroup>
 5436 | 
 5437 |     ## Setting up your API key
 5438 | 
 5439 |     You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys).
 5440 | 
 5441 |     Set up your API key:
 5442 | 
 5443 |     ```bash
 5444 |     export ANTHROPIC_API_KEY='your-anthropic-api-key-here'
 5445 |     ```
 5446 | 
 5447 |     <Warning>
 5448 |       Make sure your keep your `ANTHROPIC_API_KEY` secure!
 5449 |     </Warning>
 5450 | 
 5451 |     ## Creating the Client
 5452 | 
 5453 |     ### Basic Client Structure
 5454 | 
 5455 |     First, let's create the basic client class:
 5456 | 
 5457 |     ```kotlin
 5458 |     class MCPClient : AutoCloseable {
 5459 |         private val anthropic = AnthropicOkHttpClient.fromEnv()
 5460 |         private val mcp: Client = Client(clientInfo = Implementation(name = "mcp-client-cli", version = "1.0.0"))
 5461 |         private lateinit var tools: List<ToolUnion>
 5462 | 
 5463 |         // methods will go here
 5464 | 
 5465 |         override fun close() {
 5466 |             runBlocking {
 5467 |                 mcp.close()
 5468 |                 anthropic.close()
 5469 |             }
 5470 |         }
 5471 |     ```
 5472 | 
 5473 |     ### Server connection management
 5474 | 
 5475 |     Next, we'll implement the method to connect to an MCP server:
 5476 | 
 5477 |     ```kotlin
 5478 |     suspend fun connectToServer(serverScriptPath: String) {
 5479 |         try {
 5480 |             val command = buildList {
 5481 |                 when (serverScriptPath.substringAfterLast(".")) {
 5482 |                     "js" -> add("node")
 5483 |                     "py" -> add(if (System.getProperty("os.name").lowercase().contains("win")) "python" else "python3")
 5484 |                     "jar" -> addAll(listOf("java", "-jar"))
 5485 |                     else -> throw IllegalArgumentException("Server script must be a .js, .py or .jar file")
 5486 |                 }
 5487 |                 add(serverScriptPath)
 5488 |             }
 5489 | 
 5490 |             val process = ProcessBuilder(command).start()
 5491 |             val transport = StdioClientTransport(
 5492 |                 input = process.inputStream.asSource().buffered(),
 5493 |                 output = process.outputStream.asSink().buffered()
 5494 |             )
 5495 | 
 5496 |             mcp.connect(transport)
 5497 | 
 5498 |             val toolsResult = mcp.listTools()
 5499 |             tools = toolsResult?.tools?.map { tool ->
 5500 |                 ToolUnion.ofTool(
 5501 |                     Tool.builder()
 5502 |                         .name(tool.name)
 5503 |                         .description(tool.description ?: "")
 5504 |                         .inputSchema(
 5505 |                             Tool.InputSchema.builder()
 5506 |                                 .type(JsonValue.from(tool.inputSchema.type))
 5507 |                                 .properties(tool.inputSchema.properties.toJsonValue())
 5508 |                                 .putAdditionalProperty("required", JsonValue.from(tool.inputSchema.required))
 5509 |                                 .build()
 5510 |                         )
 5511 |                         .build()
 5512 |                 )
 5513 |             } ?: emptyList()
 5514 |             println("Connected to server with tools: ${tools.joinToString(", ") { it.tool().get().name() }}")
 5515 |         } catch (e: Exception) {
 5516 |             println("Failed to connect to MCP server: $e")
 5517 |             throw e
 5518 |         }
 5519 |     }
 5520 |     ```
 5521 | 
 5522 |     Also create a helper function to convert from `JsonObject` to `JsonValue` for Anthropic:
 5523 | 
 5524 |     ```kotlin
 5525 |     private fun JsonObject.toJsonValue(): JsonValue {
 5526 |         val mapper = ObjectMapper()
 5527 |         val node = mapper.readTree(this.toString())
 5528 |         return JsonValue.fromJsonNode(node)
 5529 |     }
 5530 |     ```
 5531 | 
 5532 |     ### Query processing logic
 5533 | 
 5534 |     Now let's add the core functionality for processing queries and handling tool calls:
 5535 | 
 5536 |     ```kotlin
 5537 |     private val messageParamsBuilder: MessageCreateParams.Builder = MessageCreateParams.builder()
 5538 |         .model(Model.CLAUDE_3_5_SONNET_20241022)
 5539 |         .maxTokens(1024)
 5540 | 
 5541 |     suspend fun processQuery(query: String): String {
 5542 |         val messages = mutableListOf(
 5543 |             MessageParam.builder()
 5544 |                 .role(MessageParam.Role.USER)
 5545 |                 .content(query)
 5546 |                 .build()
 5547 |         )
 5548 | 
 5549 |         val response = anthropic.messages().create(
 5550 |             messageParamsBuilder
 5551 |                 .messages(messages)
 5552 |                 .tools(tools)
 5553 |                 .build()
 5554 |         )
 5555 | 
 5556 |         val finalText = mutableListOf<String>()
 5557 |         response.content().forEach { content ->
 5558 |             when {
 5559 |                 content.isText() -> finalText.add(content.text().getOrNull()?.text() ?: "")
 5560 | 
 5561 |                 content.isToolUse() -> {
 5562 |                     val toolName = content.toolUse().get().name()
 5563 |                     val toolArgs =
 5564 |                         content.toolUse().get()._input().convert(object : TypeReference<Map<String, JsonValue>>() {})
 5565 | 
 5566 |                     val result = mcp.callTool(
 5567 |                         name = toolName,
 5568 |                         arguments = toolArgs ?: emptyMap()
 5569 |                     )
 5570 |                     finalText.add("[Calling tool $toolName with args $toolArgs]")
 5571 | 
 5572 |                     messages.add(
 5573 |                         MessageParam.builder()
 5574 |                             .role(MessageParam.Role.USER)
 5575 |                             .content(
 5576 |                                 """
 5577 |                                     "type": "tool_result",
 5578 |                                     "tool_name": $toolName,
 5579 |                                     "result": ${result?.content?.joinToString("\n") { (it as TextContent).text ?: "" }}
 5580 |                                 """.trimIndent()
 5581 |                             )
 5582 |                             .build()
 5583 |                     )
 5584 | 
 5585 |                     val aiResponse = anthropic.messages().create(
 5586 |                         messageParamsBuilder
 5587 |                             .messages(messages)
 5588 |                             .build()
 5589 |                     )
 5590 | 
 5591 |                     finalText.add(aiResponse.content().first().text().getOrNull()?.text() ?: "")
 5592 |                 }
 5593 |             }
 5594 |         }
 5595 | 
 5596 |         return finalText.joinToString("\n", prefix = "", postfix = "")
 5597 |     }
 5598 |     ```
 5599 | 
 5600 |     ### Interactive chat
 5601 | 
 5602 |     We'll add the chat loop:
 5603 | 
 5604 |     ```kotlin
 5605 |     suspend fun chatLoop() {
 5606 |         println("\nMCP Client Started!")
 5607 |         println("Type your queries or 'quit' to exit.")
 5608 | 
 5609 |         while (true) {
 5610 |             print("\nQuery: ")
 5611 |             val message = readLine() ?: break
 5612 |             if (message.lowercase() == "quit") break
 5613 |             val response = processQuery(message)
 5614 |             println("\n$response")
 5615 |         }
 5616 |     }
 5617 |     ```
 5618 | 
 5619 |     ### Main entry point
 5620 | 
 5621 |     Finally, we'll add the main execution function:
 5622 | 
 5623 |     ```kotlin
 5624 |     fun main(args: Array<String>) = runBlocking {
 5625 |         if (args.isEmpty()) throw IllegalArgumentException("Usage: java -jar <your_path>/build/libs/kotlin-mcp-client-0.1.0-all.jar <path_to_server_script>")
 5626 |         val serverPath = args.first()
 5627 |         val client = MCPClient()
 5628 |         client.use {
 5629 |             client.connectToServer(serverPath)
 5630 |             client.chatLoop()
 5631 |         }
 5632 |     }
 5633 |     ```
 5634 | 
 5635 |     ## Running the client
 5636 | 
 5637 |     To run your client with any MCP server:
 5638 | 
 5639 |     ```bash
 5640 |     ./gradlew build
 5641 | 
 5642 |     # Run the client
 5643 |     java -jar build/libs/<your-jar-name>.jar path/to/server.jar # jvm server
 5644 |     java -jar build/libs/<your-jar-name>.jar path/to/server.py # python server
 5645 |     java -jar build/libs/<your-jar-name>.jar path/to/build/index.js # node server
 5646 |     ```
 5647 | 
 5648 |     <Note>
 5649 |       If you're continuing the weather tutorial from the server quickstart, your command might look something like this: `java -jar build/libs/kotlin-mcp-client-0.1.0-all.jar .../samples/weather-stdio-server/build/libs/weather-stdio-server-0.1.0-all.jar`
 5650 |     </Note>
 5651 | 
 5652 |     **The client will:**
 5653 | 
 5654 |     1. Connect to the specified server
 5655 |     2. List available tools
 5656 |     3. Start an interactive chat session where you can:
 5657 |        * Enter queries
 5658 |        * See tool executions
 5659 |        * Get responses from Claude
 5660 | 
 5661 |     ## How it works
 5662 | 
 5663 |     Here's a high-level workflow schema:
 5664 | 
 5665 |     ```mermaid
 5666 |     ---
 5667 |     config:
 5668 |         theme: neutral
 5669 |     ---
 5670 |     sequenceDiagram
 5671 |         actor User
 5672 |         participant Client
 5673 |         participant Claude
 5674 |         participant MCP_Server as MCP Server
 5675 |         participant Tools
 5676 | 
 5677 |         User->>Client: Send query
 5678 |         Client<<->>MCP_Server: Get available tools
 5679 |         Client->>Claude: Send query with tool descriptions
 5680 |         Claude-->>Client: Decide tool execution
 5681 |         Client->>MCP_Server: Request tool execution
 5682 |         MCP_Server->>Tools: Execute chosen tools
 5683 |         Tools-->>MCP_Server: Return results
 5684 |         MCP_Server-->>Client: Send results
 5685 |         Client->>Claude: Send tool results
 5686 |         Claude-->>Client: Provide final response
 5687 |         Client-->>User: Display response
 5688 |     ```
 5689 | 
 5690 |     When you submit a query:
 5691 | 
 5692 |     1. The client gets the list of available tools from the server
 5693 |     2. Your query is sent to Claude along with tool descriptions
 5694 |     3. Claude decides which tools (if any) to use
 5695 |     4. The client executes any requested tool calls through the server
 5696 |     5. Results are sent back to Claude
 5697 |     6. Claude provides a natural language response
 5698 |     7. The response is displayed to you
 5699 | 
 5700 |     ## Best practices
 5701 | 
 5702 |     1. **Error Handling**
 5703 | 
 5704 |        * Leverage Kotlin's type system to model errors explicitly
 5705 |        * Wrap external tool and API calls in `try-catch` blocks when exceptions are possible
 5706 |        * Provide clear and meaningful error messages
 5707 |        * Handle network timeouts and connection issues gracefully
 5708 | 
 5709 |     2. **Security**
 5710 |        * Store API keys and secrets securely in `local.properties`, environment variables, or secret managers
 5711 |        * Validate all external responses to avoid unexpected or unsafe data usage
 5712 |        * Be cautious with permissions and trust boundaries when using tools
 5713 | 
 5714 |     ## Troubleshooting
 5715 | 
 5716 |     ### Server Path Issues
 5717 | 
 5718 |     * Double-check the path to your server script is correct
 5719 |     * Use the absolute path if the relative path isn't working
 5720 |     * For Windows users, make sure to use forward slashes (/) or escaped backslashes (\\) in the path
 5721 |     * Make sure that the required runtime is installed (java for Java, npm for Node.js, or uv for Python)
 5722 |     * Verify the server file has the correct extension (.jar for Java, .js for Node.js or .py for Python)
 5723 | 
 5724 |     Example of correct path usage:
 5725 | 
 5726 |     ```bash
 5727 |     # Relative path
 5728 |     java -jar build/libs/client.jar ./server/build/libs/server.jar
 5729 | 
 5730 |     # Absolute path
 5731 |     java -jar build/libs/client.jar /Users/username/projects/mcp-server/build/libs/server.jar
 5732 | 
 5733 |     # Windows path (either format works)
 5734 |     java -jar build/libs/client.jar C:/projects/mcp-server/build/libs/server.jar
 5735 |     java -jar build/libs/client.jar C:\\projects\\mcp-server\\build\\libs\\server.jar
 5736 |     ```
 5737 | 
 5738 |     ### Response Timing
 5739 | 
 5740 |     * The first response might take up to 30 seconds to return
 5741 |     * This is normal and happens while:
 5742 |       * The server initializes
 5743 |       * Claude processes the query
 5744 |       * Tools are being executed
 5745 |     * Subsequent responses are typically faster
 5746 |     * Don't interrupt the process during this initial waiting period
 5747 | 
 5748 |     ### Common Error Messages
 5749 | 
 5750 |     If you see:
 5751 | 
 5752 |     * `Connection refused`: Ensure the server is running and the path is correct
 5753 |     * `Tool execution failed`: Verify the tool's required environment variables are set
 5754 |     * `ANTHROPIC_API_KEY is not set`: Check your environment variables
 5755 |   </Tab>
 5756 | 
 5757 |   <Tab title="C#">
 5758 |     [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/QuickstartClient)
 5759 | 
 5760 |     ## System Requirements
 5761 | 
 5762 |     Before starting, ensure your system meets these requirements:
 5763 | 
 5764 |     * .NET 8.0 or higher
 5765 |     * Anthropic API key (Claude)
 5766 |     * Windows, Linux, or MacOS
 5767 | 
 5768 |     ## Setting up your environment
 5769 | 
 5770 |     First, create a new .NET project:
 5771 | 
 5772 |     ```bash
 5773 |     dotnet new console -n QuickstartClient
 5774 |     cd QuickstartClient
 5775 |     ```
 5776 | 
 5777 |     Then, add the required dependencies to your project:
 5778 | 
 5779 |     ```bash
 5780 |     dotnet add package ModelContextProtocol --prerelease
 5781 |     dotnet add package Anthropic.SDK
 5782 |     dotnet add package Microsoft.Extensions.Hosting
 5783 |     dotnet add package Microsoft.Extensions.AI
 5784 |     ```
 5785 | 
 5786 |     ## Setting up your API key
 5787 | 
 5788 |     You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys).
 5789 | 
 5790 |     ```bash
 5791 |     dotnet user-secrets init
 5792 |     dotnet user-secrets set "ANTHROPIC_API_KEY" "<your key here>"
 5793 |     ```
 5794 | 
 5795 |     ## Creating the Client
 5796 | 
 5797 |     ### Basic Client Structure
 5798 | 
 5799 |     First, let's setup the basic client class in the file `Program.cs`:
 5800 | 
 5801 |     ```csharp
 5802 |     using Anthropic.SDK;
 5803 |     using Microsoft.Extensions.AI;
 5804 |     using Microsoft.Extensions.Configuration;
 5805 |     using Microsoft.Extensions.Hosting;
 5806 |     using ModelContextProtocol.Client;
 5807 |     using ModelContextProtocol.Protocol.Transport;
 5808 | 
 5809 |     var builder = Host.CreateApplicationBuilder(args);
 5810 | 
 5811 |     builder.Configuration
 5812 |         .AddEnvironmentVariables()
 5813 |         .AddUserSecrets<Program>();
 5814 |     ```
 5815 | 
 5816 |     This creates the beginnings of a .NET console application that can read the API key from user secrets.
 5817 | 
 5818 |     Next, we'll setup the MCP Client:
 5819 | 
 5820 |     ```csharp
 5821 |     var (command, arguments) = GetCommandAndArguments(args);
 5822 | 
 5823 |     var clientTransport = new StdioClientTransport(new()
 5824 |     {
 5825 |         Name = "Demo Server",
 5826 |         Command = command,
 5827 |         Arguments = arguments,
 5828 |     });
 5829 | 
 5830 |     await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
 5831 | 
 5832 |     var tools = await mcpClient.ListToolsAsync();
 5833 |     foreach (var tool in tools)
 5834 |     {
 5835 |         Console.WriteLine($"Connected to server with tools: {tool.Name}");
 5836 |     }
 5837 |     ```
 5838 | 
 5839 |     Add this function at the end of the `Program.cs` file:
 5840 | 
 5841 |     ```csharp
 5842 |     static (string command, string[] arguments) GetCommandAndArguments(string[] args)
 5843 |     {
 5844 |         return args switch
 5845 |         {
 5846 |             [var script] when script.EndsWith(".py") => ("python", args),
 5847 |             [var script] when script.EndsWith(".js") => ("node", args),
 5848 |             [var script] when Directory.Exists(script) || (File.Exists(script) && script.EndsWith(".csproj")) => ("dotnet", ["run", "--project", script, "--no-build"]),
 5849 |             _ => throw new NotSupportedException("An unsupported server script was provided. Supported scripts are .py, .js, or .csproj")
 5850 |         };
 5851 |     }
 5852 |     ```
 5853 | 
 5854 |     This creates a MCP client that will connect to a server that is provided as a command line argument. It then lists the available tools from the connected server.
 5855 | 
 5856 |     ### Query processing logic
 5857 | 
 5858 |     Now let's add the core functionality for processing queries and handling tool calls:
 5859 | 
 5860 |     ```csharp
 5861 |     using var anthropicClient = new AnthropicClient(new APIAuthentication(builder.Configuration["ANTHROPIC_API_KEY"]))
 5862 |         .Messages
 5863 |         .AsBuilder()
 5864 |         .UseFunctionInvocation()
 5865 |         .Build();
 5866 | 
 5867 |     var options = new ChatOptions
 5868 |     {
 5869 |         MaxOutputTokens = 1000,
 5870 |         ModelId = "claude-3-5-sonnet-20241022",
 5871 |         Tools = [.. tools]
 5872 |     };
 5873 | 
 5874 |     Console.ForegroundColor = ConsoleColor.Green;
 5875 |     Console.WriteLine("MCP Client Started!");
 5876 |     Console.ResetColor();
 5877 | 
 5878 |     PromptForInput();
 5879 |     while(Console.ReadLine() is string query && !"exit".Equals(query, StringComparison.OrdinalIgnoreCase))
 5880 |     {
 5881 |         if (string.IsNullOrWhiteSpace(query))
 5882 |         {
 5883 |             PromptForInput();
 5884 |             continue;
 5885 |         }
 5886 | 
 5887 |         await foreach (var message in anthropicClient.GetStreamingResponseAsync(query, options))
 5888 |         {
 5889 |             Console.Write(message);
 5890 |         }
 5891 |         Console.WriteLine();
 5892 | 
 5893 |         PromptForInput();
 5894 |     }
 5895 | 
 5896 |     static void PromptForInput()
 5897 |     {
 5898 |         Console.WriteLine("Enter a command (or 'exit' to quit):");
 5899 |         Console.ForegroundColor = ConsoleColor.Cyan;
 5900 |         Console.Write("> ");
 5901 |         Console.ResetColor();
 5902 |     }
 5903 |     ```
 5904 | 
 5905 |     ## Key Components Explained
 5906 | 
 5907 |     ### 1. Client Initialization
 5908 | 
 5909 |     * The client is initialized using `McpClientFactory.CreateAsync()`, which sets up the transport type and command to run the server.
 5910 | 
 5911 |     ### 2. Server Connection
 5912 | 
 5913 |     * Supports Python, Node.js, and .NET servers.
 5914 |     * The server is started using the command specified in the arguments.
 5915 |     * Configures to use stdio for communication with the server.
 5916 |     * Initializes the session and available tools.
 5917 | 
 5918 |     ### 3. Query Processing
 5919 | 
 5920 |     * Leverages [Microsoft.Extensions.AI](https://learn.microsoft.com/dotnet/ai/ai-extensions) for the chat client.
 5921 |     * Configures the `IChatClient` to use automatic tool (function) invocation.
 5922 |     * The client reads user input and sends it to the server.
 5923 |     * The server processes the query and returns a response.
 5924 |     * The response is displayed to the user.
 5925 | 
 5926 |     ## Running the Client
 5927 | 
 5928 |     To run your client with any MCP server:
 5929 | 
 5930 |     ```bash
 5931 |     dotnet run -- path/to/server.csproj # dotnet server
 5932 |     dotnet run -- path/to/server.py # python server
 5933 |     dotnet run -- path/to/server.js # node server
 5934 |     ```
 5935 | 
 5936 |     <Note>
 5937 |       If you're continuing the weather tutorial from the server quickstart, your command might look something like this: `dotnet run -- path/to/QuickstartWeatherServer`.
 5938 |     </Note>
 5939 | 
 5940 |     The client will:
 5941 | 
 5942 |     1. Connect to the specified server
 5943 |     2. List available tools
 5944 |     3. Start an interactive chat session where you can:
 5945 |        * Enter queries
 5946 |        * See tool executions
 5947 |        * Get responses from Claude
 5948 |     4. Exit the session when done
 5949 | 
 5950 |     Here's an example of what it should look like it connected to a weather server quickstart:
 5951 | 
 5952 |     <Frame>
 5953 |       <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-dotnet-client.png" />
 5954 |     </Frame>
 5955 |   </Tab>
 5956 | </Tabs>
 5957 | 
 5958 | ## Next steps
 5959 | 
 5960 | <CardGroup cols={2}>
 5961 |   <Card title="Example servers" icon="grid" href="/examples">
 5962 |     Check out our gallery of official MCP servers and implementations
 5963 |   </Card>
 5964 | 
 5965 |   <Card title="Clients" icon="cubes" href="/clients">
 5966 |     View the list of clients that support MCP integrations
 5967 |   </Card>
 5968 | 
 5969 |   <Card title="Building MCP with LLMs" icon="comments" href="/tutorials/building-mcp-with-llms">
 5970 |     Learn how to use LLMs like Claude to speed up your MCP development
 5971 |   </Card>
 5972 | 
 5973 |   <Card title="Core architecture" icon="sitemap" href="/docs/concepts/architecture">
 5974 |     Understand how MCP connects clients, servers, and LLMs
 5975 |   </Card>
 5976 | </CardGroup>
 5977 | 
 5978 | 
 5979 | # For Server Developers
 5980 | Source: https://modelcontextprotocol.io/quickstart/server
 5981 | 
 5982 | Get started building your own server to use in Claude for Desktop and other clients.
 5983 | 
 5984 | In this tutorial, we'll build a simple MCP weather server and connect it to a host, Claude for Desktop. We'll start with a basic setup, and then progress to more complex use cases.
 5985 | 
 5986 | ### What we'll be building
 5987 | 
 5988 | Many LLMs do not currently have the ability to fetch the forecast and severe weather alerts. Let's use MCP to solve that!
 5989 | 
 5990 | We'll build a server that exposes two tools: `get-alerts` and `get-forecast`. Then we'll connect the server to an MCP host (in this case, Claude for Desktop):
 5991 | 
 5992 | <Frame>
 5993 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/weather-alerts.png" />
 5994 | </Frame>
 5995 | 
 5996 | <Frame>
 5997 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/current-weather.png" />
 5998 | </Frame>
 5999 | 
 6000 | <Note>
 6001 |   Servers can connect to any client. We've chosen Claude for Desktop here for simplicity, but we also have guides on [building your own client](/quickstart/client) as well as a [list of other clients here](/clients).
 6002 | </Note>
 6003 | 
 6004 | ### Core MCP Concepts
 6005 | 
 6006 | MCP servers can provide three main types of capabilities:
 6007 | 
 6008 | 1. **Resources**: File-like data that can be read by clients (like API responses or file contents)
 6009 | 2. **Tools**: Functions that can be called by the LLM (with user approval)
 6010 | 3. **Prompts**: Pre-written templates that help users accomplish specific tasks
 6011 | 
 6012 | This tutorial will primarily focus on tools.
 6013 | 
 6014 | <Tabs>
 6015 |   <Tab title="Python">
 6016 |     Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-python)
 6017 | 
 6018 |     ### Prerequisite knowledge
 6019 | 
 6020 |     This quickstart assumes you have familiarity with:
 6021 | 
 6022 |     * Python
 6023 |     * LLMs like Claude
 6024 | 
 6025 |     ### System requirements
 6026 | 
 6027 |     * Python 3.10 or higher installed.
 6028 |     * You must use the Python MCP SDK 1.2.0 or higher.
 6029 | 
 6030 |     ### Set up your environment
 6031 | 
 6032 |     First, let's install `uv` and set up our Python project and environment:
 6033 | 
 6034 |     <CodeGroup>
 6035 |       ```bash MacOS/Linux
 6036 |       curl -LsSf https://astral.sh/uv/install.sh | sh
 6037 |       ```
 6038 | 
 6039 |       ```powershell Windows
 6040 |       powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
 6041 |       ```
 6042 |     </CodeGroup>
 6043 | 
 6044 |     Make sure to restart your terminal afterwards to ensure that the `uv` command gets picked up.
 6045 | 
 6046 |     Now, let's create and set up our project:
 6047 | 
 6048 |     <CodeGroup>
 6049 |       ```bash MacOS/Linux
 6050 |       # Create a new directory for our project
 6051 |       uv init weather
 6052 |       cd weather
 6053 | 
 6054 |       # Create virtual environment and activate it
 6055 |       uv venv
 6056 |       source .venv/bin/activate
 6057 | 
 6058 |       # Install dependencies
 6059 |       uv add "mcp[cli]" httpx
 6060 | 
 6061 |       # Create our server file
 6062 |       touch weather.py
 6063 |       ```
 6064 | 
 6065 |       ```powershell Windows
 6066 |       # Create a new directory for our project
 6067 |       uv init weather
 6068 |       cd weather
 6069 | 
 6070 |       # Create virtual environment and activate it
 6071 |       uv venv
 6072 |       .venv\Scripts\activate
 6073 | 
 6074 |       # Install dependencies
 6075 |       uv add mcp[cli] httpx
 6076 | 
 6077 |       # Create our server file
 6078 |       new-item weather.py
 6079 |       ```
 6080 |     </CodeGroup>
 6081 | 
 6082 |     Now let's dive into building your server.
 6083 | 
 6084 |     ## Building your server
 6085 | 
 6086 |     ### Importing packages and setting up the instance
 6087 | 
 6088 |     Add these to the top of your `weather.py`:
 6089 | 
 6090 |     ```python
 6091 |     from typing import Any
 6092 |     import httpx
 6093 |     from mcp.server.fastmcp import FastMCP
 6094 | 
 6095 |     # Initialize FastMCP server
 6096 |     mcp = FastMCP("weather")
 6097 | 
 6098 |     # Constants
 6099 |     NWS_API_BASE = "https://api.weather.gov"
 6100 |     USER_AGENT = "weather-app/1.0"
 6101 |     ```
 6102 | 
 6103 |     The FastMCP class uses Python type hints and docstrings to automatically generate tool definitions, making it easy to create and maintain MCP tools.
 6104 | 
 6105 |     ### Helper functions
 6106 | 
 6107 |     Next, let's add our helper functions for querying and formatting the data from the National Weather Service API:
 6108 | 
 6109 |     ```python
 6110 |     async def make_nws_request(url: str) -> dict[str, Any] | None:
 6111 |         """Make a request to the NWS API with proper error handling."""
 6112 |         headers = {
 6113 |             "User-Agent": USER_AGENT,
 6114 |             "Accept": "application/geo+json"
 6115 |         }
 6116 |         async with httpx.AsyncClient() as client:
 6117 |             try:
 6118 |                 response = await client.get(url, headers=headers, timeout=30.0)
 6119 |                 response.raise_for_status()
 6120 |                 return response.json()
 6121 |             except Exception:
 6122 |                 return None
 6123 | 
 6124 |     def format_alert(feature: dict) -> str:
 6125 |         """Format an alert feature into a readable string."""
 6126 |         props = feature["properties"]
 6127 |         return f"""
 6128 |     Event: {props.get('event', 'Unknown')}
 6129 |     Area: {props.get('areaDesc', 'Unknown')}
 6130 |     Severity: {props.get('severity', 'Unknown')}
 6131 |     Description: {props.get('description', 'No description available')}
 6132 |     Instructions: {props.get('instruction', 'No specific instructions provided')}
 6133 |     """
 6134 |     ```
 6135 | 
 6136 |     ### Implementing tool execution
 6137 | 
 6138 |     The tool execution handler is responsible for actually executing the logic of each tool. Let's add it:
 6139 | 
 6140 |     ```python
 6141 |     @mcp.tool()
 6142 |     async def get_alerts(state: str) -> str:
 6143 |         """Get weather alerts for a US state.
 6144 | 
 6145 |         Args:
 6146 |             state: Two-letter US state code (e.g. CA, NY)
 6147 |         """
 6148 |         url = f"{NWS_API_BASE}/alerts/active/area/{state}"
 6149 |         data = await make_nws_request(url)
 6150 | 
 6151 |         if not data or "features" not in data:
 6152 |             return "Unable to fetch alerts or no alerts found."
 6153 | 
 6154 |         if not data["features"]:
 6155 |             return "No active alerts for this state."
 6156 | 
 6157 |         alerts = [format_alert(feature) for feature in data["features"]]
 6158 |         return "\n---\n".join(alerts)
 6159 | 
 6160 |     @mcp.tool()
 6161 |     async def get_forecast(latitude: float, longitude: float) -> str:
 6162 |         """Get weather forecast for a location.
 6163 | 
 6164 |         Args:
 6165 |             latitude: Latitude of the location
 6166 |             longitude: Longitude of the location
 6167 |         """
 6168 |         # First get the forecast grid endpoint
 6169 |         points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
 6170 |         points_data = await make_nws_request(points_url)
 6171 | 
 6172 |         if not points_data:
 6173 |             return "Unable to fetch forecast data for this location."
 6174 | 
 6175 |         # Get the forecast URL from the points response
 6176 |         forecast_url = points_data["properties"]["forecast"]
 6177 |         forecast_data = await make_nws_request(forecast_url)
 6178 | 
 6179 |         if not forecast_data:
 6180 |             return "Unable to fetch detailed forecast."
 6181 | 
 6182 |         # Format the periods into a readable forecast
 6183 |         periods = forecast_data["properties"]["periods"]
 6184 |         forecasts = []
 6185 |         for period in periods[:5]:  # Only show next 5 periods
 6186 |             forecast = f"""
 6187 |     {period['name']}:
 6188 |     Temperature: {period['temperature']}°{period['temperatureUnit']}
 6189 |     Wind: {period['windSpeed']} {period['windDirection']}
 6190 |     Forecast: {period['detailedForecast']}
 6191 |     """
 6192 |             forecasts.append(forecast)
 6193 | 
 6194 |         return "\n---\n".join(forecasts)
 6195 |     ```
 6196 | 
 6197 |     ### Running the server
 6198 | 
 6199 |     Finally, let's initialize and run the server:
 6200 | 
 6201 |     ```python
 6202 |     if __name__ == "__main__":
 6203 |         # Initialize and run the server
 6204 |         mcp.run(transport='stdio')
 6205 |     ```
 6206 | 
 6207 |     Your server is complete! Run `uv run weather.py` to confirm that everything's working.
 6208 | 
 6209 |     Let's now test your server from an existing MCP host, Claude for Desktop.
 6210 | 
 6211 |     ## Testing your server with Claude for Desktop
 6212 | 
 6213 |     <Note>
 6214 |       Claude for Desktop is not yet available on Linux. Linux users can proceed to the [Building a client](/quickstart/client) tutorial to build an MCP client that connects to the server we just built.
 6215 |     </Note>
 6216 | 
 6217 |     First, make sure you have Claude for Desktop installed. [You can install the latest version
 6218 |     here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
 6219 | 
 6220 |     We'll need to configure Claude for Desktop for whichever MCP servers you want to use. To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor. Make sure to create the file if it doesn't exist.
 6221 | 
 6222 |     For example, if you have [VS Code](https://code.visualstudio.com/) installed:
 6223 | 
 6224 |     <Tabs>
 6225 |       <Tab title="MacOS/Linux">
 6226 |         ```bash
 6227 |         code ~/Library/Application\ Support/Claude/claude_desktop_config.json
 6228 |         ```
 6229 |       </Tab>
 6230 | 
 6231 |       <Tab title="Windows">
 6232 |         ```powershell
 6233 |         code $env:AppData\Claude\claude_desktop_config.json
 6234 |         ```
 6235 |       </Tab>
 6236 |     </Tabs>
 6237 | 
 6238 |     You'll then add your servers in the `mcpServers` key. The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
 6239 | 
 6240 |     In this case, we'll add our single weather server like so:
 6241 | 
 6242 |     <Tabs>
 6243 |       <Tab title="MacOS/Linux">
 6244 |         ```json Python
 6245 |         {
 6246 |           "mcpServers": {
 6247 |             "weather": {
 6248 |               "command": "uv",
 6249 |               "args": [
 6250 |                 "--directory",
 6251 |                 "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather",
 6252 |                 "run",
 6253 |                 "weather.py"
 6254 |               ]
 6255 |             }
 6256 |           }
 6257 |         }
 6258 |         ```
 6259 |       </Tab>
 6260 | 
 6261 |       <Tab title="Windows">
 6262 |         ```json Python
 6263 |         {
 6264 |           "mcpServers": {
 6265 |             "weather": {
 6266 |               "command": "uv",
 6267 |               "args": [
 6268 |                 "--directory",
 6269 |                 "C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather",
 6270 |                 "run",
 6271 |                 "weather.py"
 6272 |               ]
 6273 |             }
 6274 |           }
 6275 |         }
 6276 |         ```
 6277 |       </Tab>
 6278 |     </Tabs>
 6279 | 
 6280 |     <Warning>
 6281 |       You may need to put the full path to the `uv` executable in the `command` field. You can get this by running `which uv` on MacOS/Linux or `where uv` on Windows.
 6282 |     </Warning>
 6283 | 
 6284 |     <Note>
 6285 |       Make sure you pass in the absolute path to your server.
 6286 |     </Note>
 6287 | 
 6288 |     This tells Claude for Desktop:
 6289 | 
 6290 |     1. There's an MCP server named "weather"
 6291 |     2. To launch it by running `uv --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather run weather.py`
 6292 | 
 6293 |     Save the file, and restart **Claude for Desktop**.
 6294 |   </Tab>
 6295 | 
 6296 |   <Tab title="Node">
 6297 |     Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-typescript)
 6298 | 
 6299 |     ### Prerequisite knowledge
 6300 | 
 6301 |     This quickstart assumes you have familiarity with:
 6302 | 
 6303 |     * TypeScript
 6304 |     * LLMs like Claude
 6305 | 
 6306 |     ### System requirements
 6307 | 
 6308 |     For TypeScript, make sure you have the latest version of Node installed.
 6309 | 
 6310 |     ### Set up your environment
 6311 | 
 6312 |     First, let's install Node.js and npm if you haven't already. You can download them from [nodejs.org](https://nodejs.org/).
 6313 |     Verify your Node.js installation:
 6314 | 
 6315 |     ```bash
 6316 |     node --version
 6317 |     npm --version
 6318 |     ```
 6319 | 
 6320 |     For this tutorial, you'll need Node.js version 16 or higher.
 6321 | 
 6322 |     Now, let's create and set up our project:
 6323 | 
 6324 |     <CodeGroup>
 6325 |       ```bash MacOS/Linux
 6326 |       # Create a new directory for our project
 6327 |       mkdir weather
 6328 |       cd weather
 6329 | 
 6330 |       # Initialize a new npm project
 6331 |       npm init -y
 6332 | 
 6333 |       # Install dependencies
 6334 |       npm install @modelcontextprotocol/sdk zod
 6335 |       npm install -D @types/node typescript
 6336 | 
 6337 |       # Create our files
 6338 |       mkdir src
 6339 |       touch src/index.ts
 6340 |       ```
 6341 | 
 6342 |       ```powershell Windows
 6343 |       # Create a new directory for our project
 6344 |       md weather
 6345 |       cd weather
 6346 | 
 6347 |       # Initialize a new npm project
 6348 |       npm init -y
 6349 | 
 6350 |       # Install dependencies
 6351 |       npm install @modelcontextprotocol/sdk zod
 6352 |       npm install -D @types/node typescript
 6353 | 
 6354 |       # Create our files
 6355 |       md src
 6356 |       new-item src\index.ts
 6357 |       ```
 6358 |     </CodeGroup>
 6359 | 
 6360 |     Update your package.json to add type: "module" and a build script:
 6361 | 
 6362 |     ```json package.json
 6363 |     {
 6364 |       "type": "module",
 6365 |       "bin": {
 6366 |         "weather": "./build/index.js"
 6367 |       },
 6368 |       "scripts": {
 6369 |         "build": "tsc && chmod 755 build/index.js"
 6370 |       },
 6371 |       "files": ["build"]
 6372 |     }
 6373 |     ```
 6374 | 
 6375 |     Create a `tsconfig.json` in the root of your project:
 6376 | 
 6377 |     ```json tsconfig.json
 6378 |     {
 6379 |       "compilerOptions": {
 6380 |         "target": "ES2022",
 6381 |         "module": "Node16",
 6382 |         "moduleResolution": "Node16",
 6383 |         "outDir": "./build",
 6384 |         "rootDir": "./src",
 6385 |         "strict": true,
 6386 |         "esModuleInterop": true,
 6387 |         "skipLibCheck": true,
 6388 |         "forceConsistentCasingInFileNames": true
 6389 |       },
 6390 |       "include": ["src/**/*"],
 6391 |       "exclude": ["node_modules"]
 6392 |     }
 6393 |     ```
 6394 | 
 6395 |     Now let's dive into building your server.
 6396 | 
 6397 |     ## Building your server
 6398 | 
 6399 |     ### Importing packages and setting up the instance
 6400 | 
 6401 |     Add these to the top of your `src/index.ts`:
 6402 | 
 6403 |     ```typescript
 6404 |     import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
 6405 |     import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 6406 |     import { z } from "zod";
 6407 | 
 6408 |     const NWS_API_BASE = "https://api.weather.gov";
 6409 |     const USER_AGENT = "weather-app/1.0";
 6410 | 
 6411 |     // Create server instance
 6412 |     const server = new McpServer({
 6413 |       name: "weather",
 6414 |       version: "1.0.0",
 6415 |       capabilities: {
 6416 |         resources: {},
 6417 |         tools: {},
 6418 |       },
 6419 |     });
 6420 |     ```
 6421 | 
 6422 |     ### Helper functions
 6423 | 
 6424 |     Next, let's add our helper functions for querying and formatting the data from the National Weather Service API:
 6425 | 
 6426 |     ```typescript
 6427 |     // Helper function for making NWS API requests
 6428 |     async function makeNWSRequest<T>(url: string): Promise<T | null> {
 6429 |       const headers = {
 6430 |         "User-Agent": USER_AGENT,
 6431 |         Accept: "application/geo+json",
 6432 |       };
 6433 | 
 6434 |       try {
 6435 |         const response = await fetch(url, { headers });
 6436 |         if (!response.ok) {
 6437 |           throw new Error(`HTTP error! status: ${response.status}`);
 6438 |         }
 6439 |         return (await response.json()) as T;
 6440 |       } catch (error) {
 6441 |         console.error("Error making NWS request:", error);
 6442 |         return null;
 6443 |       }
 6444 |     }
 6445 | 
 6446 |     interface AlertFeature {
 6447 |       properties: {
 6448 |         event?: string;
 6449 |         areaDesc?: string;
 6450 |         severity?: string;
 6451 |         status?: string;
 6452 |         headline?: string;
 6453 |       };
 6454 |     }
 6455 | 
 6456 |     // Format alert data
 6457 |     function formatAlert(feature: AlertFeature): string {
 6458 |       const props = feature.properties;
 6459 |       return [
 6460 |         `Event: ${props.event || "Unknown"}`,
 6461 |         `Area: ${props.areaDesc || "Unknown"}`,
 6462 |         `Severity: ${props.severity || "Unknown"}`,
 6463 |         `Status: ${props.status || "Unknown"}`,
 6464 |         `Headline: ${props.headline || "No headline"}`,
 6465 |         "---",
 6466 |       ].join("\n");
 6467 |     }
 6468 | 
 6469 |     interface ForecastPeriod {
 6470 |       name?: string;
 6471 |       temperature?: number;
 6472 |       temperatureUnit?: string;
 6473 |       windSpeed?: string;
 6474 |       windDirection?: string;
 6475 |       shortForecast?: string;
 6476 |     }
 6477 | 
 6478 |     interface AlertsResponse {
 6479 |       features: AlertFeature[];
 6480 |     }
 6481 | 
 6482 |     interface PointsResponse {
 6483 |       properties: {
 6484 |         forecast?: string;
 6485 |       };
 6486 |     }
 6487 | 
 6488 |     interface ForecastResponse {
 6489 |       properties: {
 6490 |         periods: ForecastPeriod[];
 6491 |       };
 6492 |     }
 6493 |     ```
 6494 | 
 6495 |     ### Implementing tool execution
 6496 | 
 6497 |     The tool execution handler is responsible for actually executing the logic of each tool. Let's add it:
 6498 | 
 6499 |     ```typescript
 6500 |     // Register weather tools
 6501 |     server.tool(
 6502 |       "get-alerts",
 6503 |       "Get weather alerts for a state",
 6504 |       {
 6505 |         state: z.string().length(2).describe("Two-letter state code (e.g. CA, NY)"),
 6506 |       },
 6507 |       async ({ state }) => {
 6508 |         const stateCode = state.toUpperCase();
 6509 |         const alertsUrl = `${NWS_API_BASE}/alerts?area=${stateCode}`;
 6510 |         const alertsData = await makeNWSRequest<AlertsResponse>(alertsUrl);
 6511 | 
 6512 |         if (!alertsData) {
 6513 |           return {
 6514 |             content: [
 6515 |               {
 6516 |                 type: "text",
 6517 |                 text: "Failed to retrieve alerts data",
 6518 |               },
 6519 |             ],
 6520 |           };
 6521 |         }
 6522 | 
 6523 |         const features = alertsData.features || [];
 6524 |         if (features.length === 0) {
 6525 |           return {
 6526 |             content: [
 6527 |               {
 6528 |                 type: "text",
 6529 |                 text: `No active alerts for ${stateCode}`,
 6530 |               },
 6531 |             ],
 6532 |           };
 6533 |         }
 6534 | 
 6535 |         const formattedAlerts = features.map(formatAlert);
 6536 |         const alertsText = `Active alerts for ${stateCode}:\n\n${formattedAlerts.join("\n")}`;
 6537 | 
 6538 |         return {
 6539 |           content: [
 6540 |             {
 6541 |               type: "text",
 6542 |               text: alertsText,
 6543 |             },
 6544 |           ],
 6545 |         };
 6546 |       },
 6547 |     );
 6548 | 
 6549 |     server.tool(
 6550 |       "get-forecast",
 6551 |       "Get weather forecast for a location",
 6552 |       {
 6553 |         latitude: z.number().min(-90).max(90).describe("Latitude of the location"),
 6554 |         longitude: z
 6555 |           .number()
 6556 |           .min(-180)
 6557 |           .max(180)
 6558 |           .describe("Longitude of the location"),
 6559 |       },
 6560 |       async ({ latitude, longitude }) => {
 6561 |         // Get grid point data
 6562 |         const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(4)},${longitude.toFixed(4)}`;
 6563 |         const pointsData = await makeNWSRequest<PointsResponse>(pointsUrl);
 6564 | 
 6565 |         if (!pointsData) {
 6566 |           return {
 6567 |             content: [
 6568 |               {
 6569 |                 type: "text",
 6570 |                 text: `Failed to retrieve grid point data for coordinates: ${latitude}, ${longitude}. This location may not be supported by the NWS API (only US locations are supported).`,
 6571 |               },
 6572 |             ],
 6573 |           };
 6574 |         }
 6575 | 
 6576 |         const forecastUrl = pointsData.properties?.forecast;
 6577 |         if (!forecastUrl) {
 6578 |           return {
 6579 |             content: [
 6580 |               {
 6581 |                 type: "text",
 6582 |                 text: "Failed to get forecast URL from grid point data",
 6583 |               },
 6584 |             ],
 6585 |           };
 6586 |         }
 6587 | 
 6588 |         // Get forecast data
 6589 |         const forecastData = await makeNWSRequest<ForecastResponse>(forecastUrl);
 6590 |         if (!forecastData) {
 6591 |           return {
 6592 |             content: [
 6593 |               {
 6594 |                 type: "text",
 6595 |                 text: "Failed to retrieve forecast data",
 6596 |               },
 6597 |             ],
 6598 |           };
 6599 |         }
 6600 | 
 6601 |         const periods = forecastData.properties?.periods || [];
 6602 |         if (periods.length === 0) {
 6603 |           return {
 6604 |             content: [
 6605 |               {
 6606 |                 type: "text",
 6607 |                 text: "No forecast periods available",
 6608 |               },
 6609 |             ],
 6610 |           };
 6611 |         }
 6612 | 
 6613 |         // Format forecast periods
 6614 |         const formattedForecast = periods.map((period: ForecastPeriod) =>
 6615 |           [
 6616 |             `${period.name || "Unknown"}:`,
 6617 |             `Temperature: ${period.temperature || "Unknown"}°${period.temperatureUnit || "F"}`,
 6618 |             `Wind: ${period.windSpeed || "Unknown"} ${period.windDirection || ""}`,
 6619 |             `${period.shortForecast || "No forecast available"}`,
 6620 |             "---",
 6621 |           ].join("\n"),
 6622 |         );
 6623 | 
 6624 |         const forecastText = `Forecast for ${latitude}, ${longitude}:\n\n${formattedForecast.join("\n")}`;
 6625 | 
 6626 |         return {
 6627 |           content: [
 6628 |             {
 6629 |               type: "text",
 6630 |               text: forecastText,
 6631 |             },
 6632 |           ],
 6633 |         };
 6634 |       },
 6635 |     );
 6636 |     ```
 6637 | 
 6638 |     ### Running the server
 6639 | 
 6640 |     Finally, implement the main function to run the server:
 6641 | 
 6642 |     ```typescript
 6643 |     async function main() {
 6644 |       const transport = new StdioServerTransport();
 6645 |       await server.connect(transport);
 6646 |       console.error("Weather MCP Server running on stdio");
 6647 |     }
 6648 | 
 6649 |     main().catch((error) => {
 6650 |       console.error("Fatal error in main():", error);
 6651 |       process.exit(1);
 6652 |     });
 6653 |     ```
 6654 | 
 6655 |     Make sure to run `npm run build` to build your server! This is a very important step in getting your server to connect.
 6656 | 
 6657 |     Let's now test your server from an existing MCP host, Claude for Desktop.
 6658 | 
 6659 |     ## Testing your server with Claude for Desktop
 6660 | 
 6661 |     <Note>
 6662 |       Claude for Desktop is not yet available on Linux. Linux users can proceed to the [Building a client](/quickstart/client) tutorial to build an MCP client that connects to the server we just built.
 6663 |     </Note>
 6664 | 
 6665 |     First, make sure you have Claude for Desktop installed. [You can install the latest version
 6666 |     here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
 6667 | 
 6668 |     We'll need to configure Claude for Desktop for whichever MCP servers you want to use. To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor. Make sure to create the file if it doesn't exist.
 6669 | 
 6670 |     For example, if you have [VS Code](https://code.visualstudio.com/) installed:
 6671 | 
 6672 |     <Tabs>
 6673 |       <Tab title="MacOS/Linux">
 6674 |         ```bash
 6675 |         code ~/Library/Application\ Support/Claude/claude_desktop_config.json
 6676 |         ```
 6677 |       </Tab>
 6678 | 
 6679 |       <Tab title="Windows">
 6680 |         ```powershell
 6681 |         code $env:AppData\Claude\claude_desktop_config.json
 6682 |         ```
 6683 |       </Tab>
 6684 |     </Tabs>
 6685 | 
 6686 |     You'll then add your servers in the `mcpServers` key. The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
 6687 | 
 6688 |     In this case, we'll add our single weather server like so:
 6689 | 
 6690 |     <Tabs>
 6691 |       <Tab title="MacOS/Linux">
 6692 |         <CodeGroup>
 6693 |           ```json Node
 6694 |           {
 6695 |             "mcpServers": {
 6696 |               "weather": {
 6697 |                 "command": "node",
 6698 |                 "args": ["/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/index.js"]
 6699 |               }
 6700 |             }
 6701 |           }
 6702 |           ```
 6703 |         </CodeGroup>
 6704 |       </Tab>
 6705 | 
 6706 |       <Tab title="Windows">
 6707 |         <CodeGroup>
 6708 |           ```json Node
 6709 |           {
 6710 |             "mcpServers": {
 6711 |               "weather": {
 6712 |                 "command": "node",
 6713 |                 "args": ["C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\index.js"]
 6714 |               }
 6715 |             }
 6716 |           }
 6717 |           ```
 6718 |         </CodeGroup>
 6719 |       </Tab>
 6720 |     </Tabs>
 6721 | 
 6722 |     This tells Claude for Desktop:
 6723 | 
 6724 |     1. There's an MCP server named "weather"
 6725 |     2. Launch it by running `node /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/index.js`
 6726 | 
 6727 |     Save the file, and restart **Claude for Desktop**.
 6728 |   </Tab>
 6729 | 
 6730 |   <Tab title="Java">
 6731 |     <Note>
 6732 |       This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters.
 6733 |       To learn how to create sync and async MCP Servers, manually, consult the [Java SDK Server](/sdk/java/mcp-server) documentation.
 6734 |     </Note>
 6735 | 
 6736 |     Let's get started with building our weather server!
 6737 |     [You can find the complete code for what we'll be building here.](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-stdio-server)
 6738 | 
 6739 |     For more information, see the [MCP Server Boot Starter](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html) reference documentation.
 6740 |     For manual MCP Server implementation, refer to the [MCP Server Java SDK documentation](/sdk/java/mcp-server).
 6741 | 
 6742 |     ### System requirements
 6743 | 
 6744 |     * Java 17 or higher installed.
 6745 |     * [Spring Boot 3.3.x](https://docs.spring.io/spring-boot/installing.html) or higher
 6746 | 
 6747 |     ### Set up your environment
 6748 | 
 6749 |     Use the [Spring Initializer](https://start.spring.io/) to bootstrap the project.
 6750 | 
 6751 |     You will need to add the following dependencies:
 6752 | 
 6753 |     <Tabs>
 6754 |       <Tab title="Maven">
 6755 |         ```xml
 6756 |         <dependencies>
 6757 |               <dependency>
 6758 |                   <groupId>org.springframework.ai</groupId>
 6759 |                   <artifactId>spring-ai-starter-mcp-server</artifactId>
 6760 |               </dependency>
 6761 | 
 6762 |               <dependency>
 6763 |                   <groupId>org.springframework</groupId>
 6764 |                   <artifactId>spring-web</artifactId>
 6765 |               </dependency>
 6766 |         </dependencies>
 6767 |         ```
 6768 |       </Tab>
 6769 | 
 6770 |       <Tab title="Gradle">
 6771 |         ```groovy
 6772 |         dependencies {
 6773 |           implementation platform("org.springframework.ai:spring-ai-starter-mcp-server")
 6774 |           implementation platform("org.springframework:spring-web")
 6775 |         }
 6776 |         ```
 6777 |       </Tab>
 6778 |     </Tabs>
 6779 | 
 6780 |     Then configure your application by setting the application properties:
 6781 | 
 6782 |     <CodeGroup>
 6783 |       ```bash application.properties
 6784 |       spring.main.bannerMode=off
 6785 |       logging.pattern.console=
 6786 |       ```
 6787 | 
 6788 |       ```yaml application.yml
 6789 |       logging:
 6790 |         pattern:
 6791 |           console:
 6792 |       spring:
 6793 |         main:
 6794 |           banner-mode: off
 6795 |       ```
 6796 |     </CodeGroup>
 6797 | 
 6798 |     The [Server Configuration Properties](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html#_configuration_properties) documents all available properties.
 6799 | 
 6800 |     Now let's dive into building your server.
 6801 | 
 6802 |     ## Building your server
 6803 | 
 6804 |     ### Weather Service
 6805 | 
 6806 |     Let's implement a [WeatherService.java](https://github.com/spring-projects/spring-ai-examples/blob/main/model-context-protocol/weather/starter-stdio-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java) that uses a REST client to query the data from the National Weather Service API:
 6807 | 
 6808 |     ```java
 6809 |     @Service
 6810 |     public class WeatherService {
 6811 | 
 6812 |     	private final RestClient restClient;
 6813 | 
 6814 |     	public WeatherService() {
 6815 |     		this.restClient = RestClient.builder()
 6816 |     			.baseUrl("https://api.weather.gov")
 6817 |     			.defaultHeader("Accept", "application/geo+json")
 6818 |     			.defaultHeader("User-Agent", "WeatherApiClient/1.0 ([email protected])")
 6819 |     			.build();
 6820 |     	}
 6821 | 
 6822 |       @Tool(description = "Get weather forecast for a specific latitude/longitude")
 6823 |       public String getWeatherForecastByLocation(
 6824 |           double latitude,   // Latitude coordinate
 6825 |           double longitude   // Longitude coordinate
 6826 |       ) {
 6827 |           // Returns detailed forecast including:
 6828 |           // - Temperature and unit
 6829 |           // - Wind speed and direction
 6830 |           // - Detailed forecast description
 6831 |       }
 6832 | 
 6833 |       @Tool(description = "Get weather alerts for a US state")
 6834 |       public String getAlerts(
 6835 |           @ToolParam(description = "Two-letter US state code (e.g. CA, NY)") String state
 6836 |       ) {
 6837 |           // Returns active alerts including:
 6838 |           // - Event type
 6839 |           // - Affected area
 6840 |           // - Severity
 6841 |           // - Description
 6842 |           // - Safety instructions
 6843 |       }
 6844 | 
 6845 |       // ......
 6846 |     }
 6847 |     ```
 6848 | 
 6849 |     The `@Service` annotation with auto-register the service in your application context.
 6850 |     The Spring AI `@Tool` annotation, making it easy to create and maintain MCP tools.
 6851 | 
 6852 |     The auto-configuration will automatically register these tools with the MCP server.
 6853 | 
 6854 |     ### Create your Boot Application
 6855 | 
 6856 |     ```java
 6857 |     @SpringBootApplication
 6858 |     public class McpServerApplication {
 6859 | 
 6860 |     	public static void main(String[] args) {
 6861 |     		SpringApplication.run(McpServerApplication.class, args);
 6862 |     	}
 6863 | 
 6864 |     	@Bean
 6865 |     	public ToolCallbackProvider weatherTools(WeatherService weatherService) {
 6866 |     		return  MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
 6867 |     	}
 6868 |     }
 6869 |     ```
 6870 | 
 6871 |     Uses the the `MethodToolCallbackProvider` utils to convert the `@Tools` into actionable callbacks used by the MCP server.
 6872 | 
 6873 |     ### Running the server
 6874 | 
 6875 |     Finally, let's build the server:
 6876 | 
 6877 |     ```bash
 6878 |     ./mvnw clean install
 6879 |     ```
 6880 | 
 6881 |     This will generate a `mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar` file within the `target` folder.
 6882 | 
 6883 |     Let's now test your server from an existing MCP host, Claude for Desktop.
 6884 | 
 6885 |     ## Testing your server with Claude for Desktop
 6886 | 
 6887 |     <Note>
 6888 |       Claude for Desktop is not yet available on Linux.
 6889 |     </Note>
 6890 | 
 6891 |     First, make sure you have Claude for Desktop installed.
 6892 |     [You can install the latest version here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
 6893 | 
 6894 |     We'll need to configure Claude for Desktop for whichever MCP servers you want to use.
 6895 |     To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor.
 6896 |     Make sure to create the file if it doesn't exist.
 6897 | 
 6898 |     For example, if you have [VS Code](https://code.visualstudio.com/) installed:
 6899 | 
 6900 |     <Tabs>
 6901 |       <Tab title="MacOS/Linux">
 6902 |         ```bash
 6903 |         code ~/Library/Application\ Support/Claude/claude_desktop_config.json
 6904 |         ```
 6905 |       </Tab>
 6906 | 
 6907 |       <Tab title="Windows">
 6908 |         ```powershell
 6909 |         code $env:AppData\Claude\claude_desktop_config.json
 6910 |         ```
 6911 |       </Tab>
 6912 |     </Tabs>
 6913 | 
 6914 |     You'll then add your servers in the `mcpServers` key.
 6915 |     The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
 6916 | 
 6917 |     In this case, we'll add our single weather server like so:
 6918 | 
 6919 |     <Tabs>
 6920 |       <Tab title="MacOS/Linux">
 6921 |         ```json java
 6922 |         {
 6923 |           "mcpServers": {
 6924 |             "spring-ai-mcp-weather": {
 6925 |               "command": "java",
 6926 |               "args": [
 6927 |                 "-Dspring.ai.mcp.server.stdio=true",
 6928 |                 "-jar",
 6929 |                 "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar"
 6930 |               ]
 6931 |             }
 6932 |           }
 6933 |         }
 6934 |         ```
 6935 |       </Tab>
 6936 | 
 6937 |       <Tab title="Windows">
 6938 |         ```json java
 6939 |         {
 6940 |           "mcpServers": {
 6941 |             "spring-ai-mcp-weather": {
 6942 |               "command": "java",
 6943 |               "args": [
 6944 |                 "-Dspring.ai.mcp.server.transport=STDIO",
 6945 |                 "-jar",
 6946 |                 "C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather\\mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar"
 6947 |               ]
 6948 |             }
 6949 |           }
 6950 |         }
 6951 |         ```
 6952 |       </Tab>
 6953 |     </Tabs>
 6954 | 
 6955 |     <Note>
 6956 |       Make sure you pass in the absolute path to your server.
 6957 |     </Note>
 6958 | 
 6959 |     This tells Claude for Desktop:
 6960 | 
 6961 |     1. There's an MCP server named "my-weather-server"
 6962 |     2. To launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar`
 6963 | 
 6964 |     Save the file, and restart **Claude for Desktop**.
 6965 | 
 6966 |     ## Testing your server with Java client
 6967 | 
 6968 |     ### Create a MCP Client manually
 6969 | 
 6970 |     Use the `McpClient` to connect to the server:
 6971 | 
 6972 |     ```java
 6973 |     var stdioParams = ServerParameters.builder("java")
 6974 |       .args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar")
 6975 |       .build();
 6976 | 
 6977 |     var stdioTransport = new StdioClientTransport(stdioParams);
 6978 | 
 6979 |     var mcpClient = McpClient.sync(stdioTransport).build();
 6980 | 
 6981 |     mcpClient.initialize();
 6982 | 
 6983 |     ListToolsResult toolsList = mcpClient.listTools();
 6984 | 
 6985 |     CallToolResult weather = mcpClient.callTool(
 6986 |       new CallToolRequest("getWeatherForecastByLocation",
 6987 |           Map.of("latitude", "47.6062", "longitude", "-122.3321")));
 6988 | 
 6989 |     CallToolResult alert = mcpClient.callTool(
 6990 |       new CallToolRequest("getAlerts", Map.of("state", "NY")));
 6991 | 
 6992 |     mcpClient.closeGracefully();
 6993 |     ```
 6994 | 
 6995 |     ### Use MCP Client Boot Starter
 6996 | 
 6997 |     Create a new boot starter application using the `spring-ai-starter-mcp-client` dependency:
 6998 | 
 6999 |     ```xml
 7000 |     <dependency>
 7001 |         <groupId>org.springframework.ai</groupId>
 7002 |         <artifactId>spring-ai-starter-mcp-client</artifactId>
 7003 |     </dependency>
 7004 |     ```
 7005 | 
 7006 |     and set the `spring.ai.mcp.client.stdio.servers-configuration` property to point to your `claude_desktop_config.json`.
 7007 |     You can reuse the existing Anthropic Desktop configuration:
 7008 | 
 7009 |     ```properties
 7010 |     spring.ai.mcp.client.stdio.servers-configuration=file:PATH/TO/claude_desktop_config.json
 7011 |     ```
 7012 | 
 7013 |     When you start your client application, the auto-configuration will create, automatically MCP clients from the claude\_desktop\_config.json.
 7014 | 
 7015 |     For more information, see the [MCP Client Boot Starters](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-client-docs.html) reference documentation.
 7016 | 
 7017 |     ## More Java MCP Server examples
 7018 | 
 7019 |     The [starter-webflux-server](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-webflux-server) demonstrates how to create a MCP server using SSE transport.
 7020 |     It showcases how to define and register MCP Tools, Resources, and Prompts, using the Spring Boot's auto-configuration capabilities.
 7021 |   </Tab>
 7022 | 
 7023 |   <Tab title="Kotlin">
 7024 |     Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/weather-stdio-server)
 7025 | 
 7026 |     ### Prerequisite knowledge
 7027 | 
 7028 |     This quickstart assumes you have familiarity with:
 7029 | 
 7030 |     * Kotlin
 7031 |     * LLMs like Claude
 7032 | 
 7033 |     ### System requirements
 7034 | 
 7035 |     * Java 17 or higher installed.
 7036 | 
 7037 |     ### Set up your environment
 7038 | 
 7039 |     First, let's install `java` and `gradle` if you haven't already.
 7040 |     You can download `java` from [official Oracle JDK website](https://www.oracle.com/java/technologies/downloads/).
 7041 |     Verify your `java` installation:
 7042 | 
 7043 |     ```bash
 7044 |     java --version
 7045 |     ```
 7046 | 
 7047 |     Now, let's create and set up your project:
 7048 | 
 7049 |     <CodeGroup>
 7050 |       ```bash MacOS/Linux
 7051 |       # Create a new directory for our project
 7052 |       mkdir weather
 7053 |       cd weather
 7054 | 
 7055 |       # Initialize a new kotlin project
 7056 |       gradle init
 7057 |       ```
 7058 | 
 7059 |       ```powershell Windows
 7060 |       # Create a new directory for our project
 7061 |       md weather
 7062 |       cd weather
 7063 | 
 7064 |       # Initialize a new kotlin project
 7065 |       gradle init
 7066 |       ```
 7067 |     </CodeGroup>
 7068 | 
 7069 |     After running `gradle init`, you will be presented with options for creating your project.
 7070 |     Select **Application** as the project type, **Kotlin** as the programming language, and **Java 17** as the Java version.
 7071 | 
 7072 |     Alternatively, you can create a Kotlin application using the [IntelliJ IDEA project wizard](https://kotlinlang.org/docs/jvm-get-started.html).
 7073 | 
 7074 |     After creating the project, add the following dependencies:
 7075 | 
 7076 |     <CodeGroup>
 7077 |       ```kotlin build.gradle.kts
 7078 |       val mcpVersion = "0.4.0"
 7079 |       val slf4jVersion = "2.0.9"
 7080 |       val ktorVersion = "3.1.1"
 7081 | 
 7082 |       dependencies {
 7083 |           implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
 7084 |           implementation("org.slf4j:slf4j-nop:$slf4jVersion")
 7085 |           implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
 7086 |           implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
 7087 |       }
 7088 |       ```
 7089 | 
 7090 |       ```groovy build.gradle
 7091 |       def mcpVersion = '0.3.0'
 7092 |       def slf4jVersion = '2.0.9'
 7093 |       def ktorVersion = '3.1.1'
 7094 | 
 7095 |       dependencies {
 7096 |           implementation "io.modelcontextprotocol:kotlin-sdk:$mcpVersion"
 7097 |           implementation "org.slf4j:slf4j-nop:$slf4jVersion"
 7098 |           implementation "io.ktor:ktor-client-content-negotiation:$ktorVersion"
 7099 |           implementation "io.ktor:ktor-serialization-kotlinx-json:$ktorVersion"
 7100 |       }
 7101 |       ```
 7102 |     </CodeGroup>
 7103 | 
 7104 |     Also, add the following plugins to your build script:
 7105 | 
 7106 |     <CodeGroup>
 7107 |       ```kotlin build.gradle.kts
 7108 |       plugins {
 7109 |           kotlin("plugin.serialization") version "your_version_of_kotlin"
 7110 |           id("com.github.johnrengelman.shadow") version "8.1.1"
 7111 |       }
 7112 |       ```
 7113 | 
 7114 |       ```groovy build.gradle
 7115 |       plugins {
 7116 |           id 'org.jetbrains.kotlin.plugin.serialization' version 'your_version_of_kotlin'
 7117 |           id 'com.github.johnrengelman.shadow' version '8.1.1'
 7118 |       }
 7119 |       ```
 7120 |     </CodeGroup>
 7121 | 
 7122 |     Now let’s dive into building your server.
 7123 | 
 7124 |     ## Building your server
 7125 | 
 7126 |     ### Setting up the instance
 7127 | 
 7128 |     Add a server initialization function:
 7129 | 
 7130 |     ```kotlin
 7131 |     // Main function to run the MCP server
 7132 |     fun `run mcp server`() {
 7133 |         // Create the MCP Server instance with a basic implementation
 7134 |         val server = Server(
 7135 |             Implementation(
 7136 |                 name = "weather", // Tool name is "weather"
 7137 |                 version = "1.0.0" // Version of the implementation
 7138 |             ),
 7139 |             ServerOptions(
 7140 |                 capabilities = ServerCapabilities(tools = ServerCapabilities.Tools(listChanged = true))
 7141 |             )
 7142 |         )
 7143 | 
 7144 |         // Create a transport using standard IO for server communication
 7145 |         val transport = StdioServerTransport(
 7146 |             System.`in`.asInput(),
 7147 |             System.out.asSink().buffered()
 7148 |         )
 7149 | 
 7150 |         runBlocking {
 7151 |             server.connect(transport)
 7152 |             val done = Job()
 7153 |             server.onClose {
 7154 |                 done.complete()
 7155 |             }
 7156 |             done.join()
 7157 |         }
 7158 |     }
 7159 |     ```
 7160 | 
 7161 |     ### Weather API helper functions
 7162 | 
 7163 |     Next, let's add functions and data classes for querying and converting responses from the National Weather Service API:
 7164 | 
 7165 |     ```kotlin
 7166 |     // Extension function to fetch forecast information for given latitude and longitude
 7167 |     suspend fun HttpClient.getForecast(latitude: Double, longitude: Double): List<String> {
 7168 |         val points = this.get("/points/$latitude,$longitude").body<Points>()
 7169 |         val forecast = this.get(points.properties.forecast).body<Forecast>()
 7170 |         return forecast.properties.periods.map { period ->
 7171 |             """
 7172 |                 ${period.name}:
 7173 |                 Temperature: ${period.temperature} ${period.temperatureUnit}
 7174 |                 Wind: ${period.windSpeed} ${period.windDirection}
 7175 |                 Forecast: ${period.detailedForecast}
 7176 |             """.trimIndent()
 7177 |         }
 7178 |     }
 7179 | 
 7180 |     // Extension function to fetch weather alerts for a given state
 7181 |     suspend fun HttpClient.getAlerts(state: String): List<String> {
 7182 |         val alerts = this.get("/alerts/active/area/$state").body<Alert>()
 7183 |         return alerts.features.map { feature ->
 7184 |             """
 7185 |                 Event: ${feature.properties.event}
 7186 |                 Area: ${feature.properties.areaDesc}
 7187 |                 Severity: ${feature.properties.severity}
 7188 |                 Description: ${feature.properties.description}
 7189 |                 Instruction: ${feature.properties.instruction}
 7190 |             """.trimIndent()
 7191 |         }
 7192 |     }
 7193 | 
 7194 |     @Serializable
 7195 |     data class Points(
 7196 |         val properties: Properties
 7197 |     ) {
 7198 |         @Serializable
 7199 |         data class Properties(val forecast: String)
 7200 |     }
 7201 | 
 7202 |     @Serializable
 7203 |     data class Forecast(
 7204 |         val properties: Properties
 7205 |     ) {
 7206 |         @Serializable
 7207 |         data class Properties(val periods: List<Period>)
 7208 | 
 7209 |         @Serializable
 7210 |         data class Period(
 7211 |             val number: Int, val name: String, val startTime: String, val endTime: String,
 7212 |             val isDaytime: Boolean, val temperature: Int, val temperatureUnit: String,
 7213 |             val temperatureTrend: String, val probabilityOfPrecipitation: JsonObject,
 7214 |             val windSpeed: String, val windDirection: String,
 7215 |             val shortForecast: String, val detailedForecast: String,
 7216 |         )
 7217 |     }
 7218 | 
 7219 |     @Serializable
 7220 |     data class Alert(
 7221 |         val features: List<Feature>
 7222 |     ) {
 7223 |         @Serializable
 7224 |         data class Feature(
 7225 |             val properties: Properties
 7226 |         )
 7227 | 
 7228 |         @Serializable
 7229 |         data class Properties(
 7230 |             val event: String, val areaDesc: String, val severity: String,
 7231 |             val description: String, val instruction: String?,
 7232 |         )
 7233 |     }
 7234 |     ```
 7235 | 
 7236 |     ### Implementing tool execution
 7237 | 
 7238 |     The tool execution handler is responsible for actually executing the logic of each tool. Let's add it:
 7239 | 
 7240 |     ```kotlin
 7241 |     // Create an HTTP client with a default request configuration and JSON content negotiation
 7242 |     val httpClient = HttpClient {
 7243 |         defaultRequest {
 7244 |             url("https://api.weather.gov")
 7245 |             headers {
 7246 |                 append("Accept", "application/geo+json")
 7247 |                 append("User-Agent", "WeatherApiClient/1.0")
 7248 |             }
 7249 |             contentType(ContentType.Application.Json)
 7250 |         }
 7251 |         // Install content negotiation plugin for JSON serialization/deserialization
 7252 |         install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
 7253 |     }
 7254 | 
 7255 |     // Register a tool to fetch weather alerts by state
 7256 |     server.addTool(
 7257 |         name = "get_alerts",
 7258 |         description = """
 7259 |             Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)
 7260 |         """.trimIndent(),
 7261 |         inputSchema = Tool.Input(
 7262 |             properties = buildJsonObject {
 7263 |                 putJsonObject("state") {
 7264 |                     put("type", "string")
 7265 |                     put("description", "Two-letter US state code (e.g. CA, NY)")
 7266 |                 }
 7267 |             },
 7268 |             required = listOf("state")
 7269 |         )
 7270 |     ) { request ->
 7271 |         val state = request.arguments["state"]?.jsonPrimitive?.content
 7272 |         if (state == null) {
 7273 |             return@addTool CallToolResult(
 7274 |                 content = listOf(TextContent("The 'state' parameter is required."))
 7275 |             )
 7276 |         }
 7277 | 
 7278 |         val alerts = httpClient.getAlerts(state)
 7279 | 
 7280 |         CallToolResult(content = alerts.map { TextContent(it) })
 7281 |     }
 7282 | 
 7283 |     // Register a tool to fetch weather forecast by latitude and longitude
 7284 |     server.addTool(
 7285 |         name = "get_forecast",
 7286 |         description = """
 7287 |             Get weather forecast for a specific latitude/longitude
 7288 |         """.trimIndent(),
 7289 |         inputSchema = Tool.Input(
 7290 |             properties = buildJsonObject {
 7291 |                 putJsonObject("latitude") { put("type", "number") }
 7292 |                 putJsonObject("longitude") { put("type", "number") }
 7293 |             },
 7294 |             required = listOf("latitude", "longitude")
 7295 |         )
 7296 |     ) { request ->
 7297 |         val latitude = request.arguments["latitude"]?.jsonPrimitive?.doubleOrNull
 7298 |         val longitude = request.arguments["longitude"]?.jsonPrimitive?.doubleOrNull
 7299 |         if (latitude == null || longitude == null) {
 7300 |             return@addTool CallToolResult(
 7301 |                 content = listOf(TextContent("The 'latitude' and 'longitude' parameters are required."))
 7302 |             )
 7303 |         }
 7304 | 
 7305 |         val forecast = httpClient.getForecast(latitude, longitude)
 7306 | 
 7307 |         CallToolResult(content = forecast.map { TextContent(it) })
 7308 |     }
 7309 |     ```
 7310 | 
 7311 |     ### Running the server
 7312 | 
 7313 |     Finally, implement the main function to run the server:
 7314 | 
 7315 |     ```kotlin
 7316 |     fun main() = `run mcp server`()
 7317 |     ```
 7318 | 
 7319 |     Make sure to run `./gradlew build` to build your server. This is a very important step in getting your server to connect.
 7320 | 
 7321 |     Let's now test your server from an existing MCP host, Claude for Desktop.
 7322 | 
 7323 |     ## Testing your server with Claude for Desktop
 7324 | 
 7325 |     <Note>
 7326 |       Claude for Desktop is not yet available on Linux. Linux users can proceed to the [Building a client](/quickstart/client) tutorial to build an MCP client that connects to the server we just built.
 7327 |     </Note>
 7328 | 
 7329 |     First, make sure you have Claude for Desktop installed. [You can install the latest version
 7330 |     here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
 7331 | 
 7332 |     We'll need to configure Claude for Desktop for whichever MCP servers you want to use.
 7333 |     To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor.
 7334 |     Make sure to create the file if it doesn't exist.
 7335 | 
 7336 |     For example, if you have [VS Code](https://code.visualstudio.com/) installed:
 7337 | 
 7338 |     <CodeGroup>
 7339 |       ```bash MacOS/Linux
 7340 |       code ~/Library/Application\ Support/Claude/claude_desktop_config.json
 7341 |       ```
 7342 | 
 7343 |       ```powershell Windows
 7344 |       code $env:AppData\Claude\claude_desktop_config.json
 7345 |       ```
 7346 |     </CodeGroup>
 7347 | 
 7348 |     You'll then add your servers in the `mcpServers` key.
 7349 |     The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
 7350 | 
 7351 |     In this case, we'll add our single weather server like so:
 7352 | 
 7353 |     <CodeGroup>
 7354 |       ```json MacOS/Linux
 7355 |       {
 7356 |         "mcpServers": {
 7357 |           "weather": {
 7358 |             "command": "java",
 7359 |             "args": [
 7360 |               "-jar",
 7361 |               "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar"
 7362 |             ]
 7363 |           }
 7364 |         }
 7365 |       }
 7366 |       ```
 7367 | 
 7368 |       ```json Windows
 7369 |       {
 7370 |         "mcpServers": {
 7371 |           "weather": {
 7372 |             "command": "java",
 7373 |             "args": [
 7374 |               "-jar",
 7375 |               "C:\\PATH\\TO\\PARENT\\FOLDER\\weather\\build\\libs\\weather-0.1.0-all.jar"
 7376 |             ]
 7377 |           }
 7378 |         }
 7379 |       }
 7380 |       ```
 7381 |     </CodeGroup>
 7382 | 
 7383 |     This tells Claude for Desktop:
 7384 | 
 7385 |     1. There's an MCP server named "weather"
 7386 |     2. Launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar`
 7387 | 
 7388 |     Save the file, and restart **Claude for Desktop**.
 7389 |   </Tab>
 7390 | 
 7391 |   <Tab title="C#">
 7392 |     Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/QuickstartWeatherServer)
 7393 | 
 7394 |     ### Prerequisite knowledge
 7395 | 
 7396 |     This quickstart assumes you have familiarity with:
 7397 | 
 7398 |     * C#
 7399 |     * LLMs like Claude
 7400 |     * .NET 8 or higher
 7401 | 
 7402 |     ### System requirements
 7403 | 
 7404 |     * [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or higher installed.
 7405 | 
 7406 |     ### Set up your environment
 7407 | 
 7408 |     First, let's install `dotnet` if you haven't already. You can download `dotnet` from [official Microsoft .NET website](https://dotnet.microsoft.com/download/). Verify your `dotnet` installation:
 7409 | 
 7410 |     ```bash
 7411 |     dotnet --version
 7412 |     ```
 7413 | 
 7414 |     Now, let's create and set up your project:
 7415 | 
 7416 |     <CodeGroup>
 7417 |       ```bash MacOS/Linux
 7418 |       # Create a new directory for our project
 7419 |       mkdir weather
 7420 |       cd weather
 7421 |       # Initialize a new C# project
 7422 |       dotnet new console
 7423 |       ```
 7424 | 
 7425 |       ```powershell Windows
 7426 |       # Create a new directory for our project
 7427 |       mkdir weather
 7428 |       cd weather
 7429 |       # Initialize a new C# project
 7430 |       dotnet new console
 7431 |       ```
 7432 |     </CodeGroup>
 7433 | 
 7434 |     After running `dotnet new console`, you will be presented with a new C# project.
 7435 |     You can open the project in your favorite IDE, such as [Visual Studio](https://visualstudio.microsoft.com/) or [Rider](https://www.jetbrains.com/rider/).
 7436 |     Alternatively, you can create a C# application using the [Visual Studio project wizard](https://learn.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-console?view=vs-2022).
 7437 |     After creating the project, add NuGet package for the Model Context Protocol SDK and hosting:
 7438 | 
 7439 |     ```bash
 7440 |     # Add the Model Context Protocol SDK NuGet package
 7441 |     dotnet add package ModelContextProtocol --prerelease
 7442 |     # Add the .NET Hosting NuGet package
 7443 |     dotnet add package Microsoft.Extensions.Hosting
 7444 |     ```
 7445 | 
 7446 |     Now let’s dive into building your server.
 7447 | 
 7448 |     ## Building your server
 7449 | 
 7450 |     Open the `Program.cs` file in your project and replace its contents with the following code:
 7451 | 
 7452 |     ```csharp
 7453 |     using Microsoft.Extensions.DependencyInjection;
 7454 |     using Microsoft.Extensions.Hosting;
 7455 |     using ModelContextProtocol;
 7456 |     using System.Net.Http.Headers;
 7457 | 
 7458 |     var builder = Host.CreateEmptyApplicationBuilder(settings: null);
 7459 | 
 7460 |     builder.Services.AddMcpServer()
 7461 |         .WithStdioServerTransport()
 7462 |         .WithToolsFromAssembly();
 7463 | 
 7464 |     builder.Services.AddSingleton(_ =>
 7465 |     {
 7466 |         var client = new HttpClient() { BaseAddress = new Uri("https://api.weather.gov") };
 7467 |         client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
 7468 |         return client;
 7469 |     });
 7470 | 
 7471 |     var app = builder.Build();
 7472 | 
 7473 |     await app.RunAsync();
 7474 |     ```
 7475 | 
 7476 |     <Note>
 7477 |       When creating the `ApplicationHostBuilder`, ensure you use `CreateEmptyApplicationBuilder` instead of `CreateDefaultBuilder`. This ensures that the server does not write any additional messages to the console. This is only necessary for servers using STDIO transport.
 7478 |     </Note>
 7479 | 
 7480 |     This code sets up a basic console application that uses the Model Context Protocol SDK to create an MCP server with standard I/O transport.
 7481 | 
 7482 |     ### Weather API helper functions
 7483 | 
 7484 |     Create an extension class for `HttpClient` which helps simplify JSON request handling:
 7485 | 
 7486 |     ```csharp
 7487 |     using System.Text.Json;
 7488 | 
 7489 |     internal static class HttpClientExt
 7490 |     {
 7491 |         public static async Task<JsonDocument> ReadJsonDocumentAsync(this HttpClient client, string requestUri)
 7492 |         {
 7493 |             using var response = await client.GetAsync(requestUri);
 7494 |             response.EnsureSuccessStatusCode();
 7495 |             return await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
 7496 |         }
 7497 |     }
 7498 |     ```
 7499 | 
 7500 |     Next, define a class with the tool execution handlers for querying and converting responses from the National Weather Service API:
 7501 | 
 7502 |     ```csharp
 7503 |     using ModelContextProtocol.Server;
 7504 |     using System.ComponentModel;
 7505 |     using System.Globalization;
 7506 |     using System.Text.Json;
 7507 | 
 7508 |     namespace QuickstartWeatherServer.Tools;
 7509 | 
 7510 |     [McpServerToolType]
 7511 |     public static class WeatherTools
 7512 |     {
 7513 |         [McpServerTool, Description("Get weather alerts for a US state.")]
 7514 |         public static async Task<string> GetAlerts(
 7515 |             HttpClient client,
 7516 |             [Description("The US state to get alerts for.")] string state)
 7517 |         {
 7518 |             using var jsonDocument = await client.ReadJsonDocumentAsync($"/alerts/active/area/{state}");
 7519 |             var jsonElement = jsonDocument.RootElement;
 7520 |             var alerts = jsonElement.GetProperty("features").EnumerateArray();
 7521 | 
 7522 |             if (!alerts.Any())
 7523 |             {
 7524 |                 return "No active alerts for this state.";
 7525 |             }
 7526 | 
 7527 |             return string.Join("\n--\n", alerts.Select(alert =>
 7528 |             {
 7529 |                 JsonElement properties = alert.GetProperty("properties");
 7530 |                 return $"""
 7531 |                         Event: {properties.GetProperty("event").GetString()}
 7532 |                         Area: {properties.GetProperty("areaDesc").GetString()}
 7533 |                         Severity: {properties.GetProperty("severity").GetString()}
 7534 |                         Description: {properties.GetProperty("description").GetString()}
 7535 |                         Instruction: {properties.GetProperty("instruction").GetString()}
 7536 |                         """;
 7537 |             }));
 7538 |         }
 7539 | 
 7540 |         [McpServerTool, Description("Get weather forecast for a location.")]
 7541 |         public static async Task<string> GetForecast(
 7542 |             HttpClient client,
 7543 |             [Description("Latitude of the location.")] double latitude,
 7544 |             [Description("Longitude of the location.")] double longitude)
 7545 |         {
 7546 |             var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}");
 7547 |             using var jsonDocument = await client.ReadJsonDocumentAsync(pointUrl);
 7548 |             var forecastUrl = jsonDocument.RootElement.GetProperty("properties").GetProperty("forecast").GetString()
 7549 |                 ?? throw new Exception($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}");
 7550 | 
 7551 |             using var forecastDocument = await client.ReadJsonDocumentAsync(forecastUrl);
 7552 |             var periods = forecastDocument.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray();
 7553 | 
 7554 |             return string.Join("\n---\n", periods.Select(period => $"""
 7555 |                     {period.GetProperty("name").GetString()}
 7556 |                     Temperature: {period.GetProperty("temperature").GetInt32()}°F
 7557 |                     Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
 7558 |                     Forecast: {period.GetProperty("detailedForecast").GetString()}
 7559 |                     """));
 7560 |         }
 7561 |     }
 7562 |     ```
 7563 | 
 7564 |     ### Running the server
 7565 | 
 7566 |     Finally, run the server using the following command:
 7567 | 
 7568 |     ```bash
 7569 |     dotnet run
 7570 |     ```
 7571 | 
 7572 |     This will start the server and listen for incoming requests on standard input/output.
 7573 | 
 7574 |     ## Testing your server with Claude for Desktop
 7575 | 
 7576 |     <Note>
 7577 |       Claude for Desktop is not yet available on Linux. Linux users can proceed to the [Building a client](/quickstart/client) tutorial to build an MCP client that connects to the server we just built.
 7578 |     </Note>
 7579 | 
 7580 |     First, make sure you have Claude for Desktop installed. [You can install the latest version
 7581 |     here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
 7582 |     We'll need to configure Claude for Desktop for whichever MCP servers you want to use. To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor. Make sure to create the file if it doesn't exist.
 7583 |     For example, if you have [VS Code](https://code.visualstudio.com/) installed:
 7584 | 
 7585 |     <Tabs>
 7586 |       <Tab title="MacOS/Linux">
 7587 |         ```bash
 7588 |         code ~/Library/Application\ Support/Claude/claude_desktop_config.json
 7589 |         ```
 7590 |       </Tab>
 7591 | 
 7592 |       <Tab title="Windows">
 7593 |         ```powershell
 7594 |         code $env:AppData\Claude\claude_desktop_config.json
 7595 |         ```
 7596 |       </Tab>
 7597 |     </Tabs>
 7598 | 
 7599 |     You'll then add your servers in the `mcpServers` key. The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
 7600 |     In this case, we'll add our single weather server like so:
 7601 | 
 7602 |     <Tabs>
 7603 |       <Tab title="MacOS/Linux">
 7604 |         ```json
 7605 |         {
 7606 |           "mcpServers": {
 7607 |             "weather": {
 7608 |               "command": "dotnet",
 7609 |               "args": ["run", "--project", "/ABSOLUTE/PATH/TO/PROJECT", "--no-build"]
 7610 |             }
 7611 |           }
 7612 |         }
 7613 |         ```
 7614 |       </Tab>
 7615 | 
 7616 |       <Tab title="Windows">
 7617 |         ```json
 7618 |         {
 7619 |           "mcpServers": {
 7620 |             "weather": {
 7621 |               "command": "dotnet",
 7622 |               "args": [
 7623 |                 "run",
 7624 |                 "--project",
 7625 |                 "C:\\ABSOLUTE\\PATH\\TO\\PROJECT",
 7626 |                 "--no-build"
 7627 |               ]
 7628 |             }
 7629 |           }
 7630 |         }
 7631 |         ```
 7632 |       </Tab>
 7633 |     </Tabs>
 7634 | 
 7635 |     This tells Claude for Desktop:
 7636 | 
 7637 |     1. There's an MCP server named "weather"
 7638 |     2. Launch it by running `dotnet run /ABSOLUTE/PATH/TO/PROJECT`
 7639 |        Save the file, and restart **Claude for Desktop**.
 7640 |   </Tab>
 7641 | </Tabs>
 7642 | 
 7643 | ### Test with commands
 7644 | 
 7645 | Let's make sure Claude for Desktop is picking up the two tools we've exposed in our `weather` server. You can do this by looking for the "Search and tools" <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/claude-desktop-mcp-slider.svg" style={{display: 'inline', margin: 0, height: '1.3em'}} /> icon:
 7646 | 
 7647 | <Frame>
 7648 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/visual-indicator-mcp-tools.png" />
 7649 | </Frame>
 7650 | 
 7651 | After clicking on the slider icon, you should see two tools listed:
 7652 | 
 7653 | <Frame>
 7654 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/available-mcp-tools.png" />
 7655 | </Frame>
 7656 | 
 7657 | If your server isn't being picked up by Claude for Desktop, proceed to the [Troubleshooting](#troubleshooting) section for debugging tips.
 7658 | 
 7659 | If the tool settings icon has shown up, you can now test your server by running the following commands in Claude for Desktop:
 7660 | 
 7661 | * What's the weather in Sacramento?
 7662 | * What are the active weather alerts in Texas?
 7663 | 
 7664 | <Frame>
 7665 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/current-weather.png" />
 7666 | </Frame>
 7667 | 
 7668 | <Frame>
 7669 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/weather-alerts.png" />
 7670 | </Frame>
 7671 | 
 7672 | <Note>
 7673 |   Since this is the US National Weather service, the queries will only work for US locations.
 7674 | </Note>
 7675 | 
 7676 | ## What's happening under the hood
 7677 | 
 7678 | When you ask a question:
 7679 | 
 7680 | 1. The client sends your question to Claude
 7681 | 2. Claude analyzes the available tools and decides which one(s) to use
 7682 | 3. The client executes the chosen tool(s) through the MCP server
 7683 | 4. The results are sent back to Claude
 7684 | 5. Claude formulates a natural language response
 7685 | 6. The response is displayed to you!
 7686 | 
 7687 | ## Troubleshooting
 7688 | 
 7689 | <AccordionGroup>
 7690 |   <Accordion title="Claude for Desktop Integration Issues">
 7691 |     **Getting logs from Claude for Desktop**
 7692 | 
 7693 |     Claude.app logging related to MCP is written to log files in `~/Library/Logs/Claude`:
 7694 | 
 7695 |     * `mcp.log` will contain general logging about MCP connections and connection failures.
 7696 |     * Files named `mcp-server-SERVERNAME.log` will contain error (stderr) logging from the named server.
 7697 | 
 7698 |     You can run the following command to list recent logs and follow along with any new ones:
 7699 | 
 7700 |     ```bash
 7701 |     # Check Claude's logs for errors
 7702 |     tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
 7703 |     ```
 7704 | 
 7705 |     **Server not showing up in Claude**
 7706 | 
 7707 |     1. Check your `claude_desktop_config.json` file syntax
 7708 |     2. Make sure the path to your project is absolute and not relative
 7709 |     3. Restart Claude for Desktop completely
 7710 | 
 7711 |     **Tool calls failing silently**
 7712 | 
 7713 |     If Claude attempts to use the tools but they fail:
 7714 | 
 7715 |     1. Check Claude's logs for errors
 7716 |     2. Verify your server builds and runs without errors
 7717 |     3. Try restarting Claude for Desktop
 7718 | 
 7719 |     **None of this is working. What do I do?**
 7720 | 
 7721 |     Please refer to our [debugging guide](/docs/tools/debugging) for better debugging tools and more detailed guidance.
 7722 |   </Accordion>
 7723 | 
 7724 |   <Accordion title="Weather API Issues">
 7725 |     **Error: Failed to retrieve grid point data**
 7726 | 
 7727 |     This usually means either:
 7728 | 
 7729 |     1. The coordinates are outside the US
 7730 |     2. The NWS API is having issues
 7731 |     3. You're being rate limited
 7732 | 
 7733 |     Fix:
 7734 | 
 7735 |     * Verify you're using US coordinates
 7736 |     * Add a small delay between requests
 7737 |     * Check the NWS API status page
 7738 | 
 7739 |     **Error: No active alerts for \[STATE]**
 7740 | 
 7741 |     This isn't an error - it just means there are no current weather alerts for that state. Try a different state or check during severe weather.
 7742 |   </Accordion>
 7743 | </AccordionGroup>
 7744 | 
 7745 | <Note>
 7746 |   For more advanced troubleshooting, check out our guide on [Debugging MCP](/docs/tools/debugging)
 7747 | </Note>
 7748 | 
 7749 | ## Next steps
 7750 | 
 7751 | <CardGroup cols={2}>
 7752 |   <Card title="Building a client" icon="outlet" href="/quickstart/client">
 7753 |     Learn how to build your own MCP client that can connect to your server
 7754 |   </Card>
 7755 | 
 7756 |   <Card title="Example servers" icon="grid" href="/examples">
 7757 |     Check out our gallery of official MCP servers and implementations
 7758 |   </Card>
 7759 | 
 7760 |   <Card title="Debugging Guide" icon="bug" href="/docs/tools/debugging">
 7761 |     Learn how to effectively debug MCP servers and integrations
 7762 |   </Card>
 7763 | 
 7764 |   <Card title="Building MCP with LLMs" icon="comments" href="/tutorials/building-mcp-with-llms">
 7765 |     Learn how to use LLMs like Claude to speed up your MCP development
 7766 |   </Card>
 7767 | </CardGroup>
 7768 | 
 7769 | 
 7770 | # For Claude Desktop Users
 7771 | Source: https://modelcontextprotocol.io/quickstart/user
 7772 | 
 7773 | Get started using pre-built servers in Claude for Desktop.
 7774 | 
 7775 | In this tutorial, you will extend [Claude for Desktop](https://claude.ai/download) so that it can read from your computer's file system, write new files, move files, and even search files.
 7776 | 
 7777 | <Frame>
 7778 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-filesystem.png" />
 7779 | </Frame>
 7780 | 
 7781 | Don't worry — it will ask you for your permission before executing these actions!
 7782 | 
 7783 | ## 1. Download Claude for Desktop
 7784 | 
 7785 | Start by downloading [Claude for Desktop](https://claude.ai/download), choosing either macOS or Windows. (Linux is not yet supported for Claude for Desktop.)
 7786 | 
 7787 | Follow the installation instructions.
 7788 | 
 7789 | If you already have Claude for Desktop, make sure it's on the latest version by clicking on the Claude menu on your computer and selecting "Check for Updates..."
 7790 | 
 7791 | ## 2. Add the Filesystem MCP Server
 7792 | 
 7793 | To add this filesystem functionality, we will be installing a pre-built [Filesystem MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) to Claude for Desktop. This is one of several current [reference servers](https://github.com/modelcontextprotocol/servers/tree/main) and many community-created servers.
 7794 | 
 7795 | Get started by opening up the Claude menu on your computer and select "Settings..." Please note that these are not the Claude Account Settings found in the app window itself.
 7796 | 
 7797 | This is what it should look like on a Mac:
 7798 | 
 7799 | <Frame style={{ textAlign: "center" }}>
 7800 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-menu.png" width="400" />
 7801 | </Frame>
 7802 | 
 7803 | Click on "Developer" in the left-hand bar of the Settings pane, and then click on "Edit Config":
 7804 | 
 7805 | <Frame>
 7806 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-developer.png" />
 7807 | </Frame>
 7808 | 
 7809 | This will create a configuration file at:
 7810 | 
 7811 | * macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
 7812 | * Windows: `%APPDATA%\Claude\claude_desktop_config.json`
 7813 | 
 7814 | if you don't already have one, and will display the file in your file system.
 7815 | 
 7816 | Open up the configuration file in any text editor. Replace the file contents with this:
 7817 | 
 7818 | <Tabs>
 7819 |   <Tab title="MacOS/Linux">
 7820 |     ```json
 7821 |     {
 7822 |       "mcpServers": {
 7823 |         "filesystem": {
 7824 |           "command": "npx",
 7825 |           "args": [
 7826 |             "-y",
 7827 |             "@modelcontextprotocol/server-filesystem",
 7828 |             "/Users/username/Desktop",
 7829 |             "/Users/username/Downloads"
 7830 |           ]
 7831 |         }
 7832 |       }
 7833 |     }
 7834 |     ```
 7835 |   </Tab>
 7836 | 
 7837 |   <Tab title="Windows">
 7838 |     ```json
 7839 |     {
 7840 |       "mcpServers": {
 7841 |         "filesystem": {
 7842 |           "command": "npx",
 7843 |           "args": [
 7844 |             "-y",
 7845 |             "@modelcontextprotocol/server-filesystem",
 7846 |             "C:\\Users\\username\\Desktop",
 7847 |             "C:\\Users\\username\\Downloads"
 7848 |           ]
 7849 |         }
 7850 |       }
 7851 |     }
 7852 |     ```
 7853 |   </Tab>
 7854 | </Tabs>
 7855 | 
 7856 | 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. It's set up to work for Desktop and Downloads, but you can add more paths as well.
 7857 | 
 7858 | You will also need [Node.js](https://nodejs.org) on your computer for this to run properly. To verify you have Node installed, open the command line on your computer.
 7859 | 
 7860 | * On macOS, open the Terminal from your Applications folder
 7861 | * On Windows, press Windows + R, type "cmd", and press Enter
 7862 | 
 7863 | Once in the command line, verify you have Node installed by entering in the following command:
 7864 | 
 7865 | ```bash
 7866 | node --version
 7867 | ```
 7868 | 
 7869 | If you get an error saying "command not found" or "node is not recognized", download Node from [nodejs.org](https://nodejs.org/).
 7870 | 
 7871 | <Tip>
 7872 |   **How does the configuration file work?**
 7873 | 
 7874 |   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](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem), will let you access your file system in Claude for Desktop.
 7875 | </Tip>
 7876 | 
 7877 | <Warning>
 7878 |   **Command Privileges**
 7879 | 
 7880 |   Claude for Desktop will run the commands in the configuration file with the permissions of your user account, and access to your local files. Only add commands if you understand and trust the source.
 7881 | </Warning>
 7882 | 
 7883 | ## 3. Restart Claude
 7884 | 
 7885 | After updating your configuration file, you need to restart Claude for Desktop.
 7886 | 
 7887 | Upon restarting, you should see a slider <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/claude-desktop-mcp-slider.svg" style={{display: 'inline', margin: 0, height: '1.3em'}} /> icon in the bottom left corner of the input box:
 7888 | 
 7889 | <Frame>
 7890 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-slider.png" />
 7891 | </Frame>
 7892 | 
 7893 | After clicking on the slider icon, you should see the tools that come with the Filesystem MCP Server:
 7894 | 
 7895 | <Frame style={{ textAlign: "center" }}>
 7896 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-tools.png" width="400" />
 7897 | </Frame>
 7898 | 
 7899 | If your server isn't being picked up by Claude for Desktop, proceed to the [Troubleshooting](#troubleshooting) section for debugging tips.
 7900 | 
 7901 | ## 4. Try it out!
 7902 | 
 7903 | You can now talk to Claude and ask it about your filesystem. It should know when to call the relevant tools.
 7904 | 
 7905 | Things you might try asking Claude:
 7906 | 
 7907 | * Can you write a poem and save it to my desktop?
 7908 | * What are some work-related files in my downloads folder?
 7909 | * Can you take all the images on my desktop and move them to a new folder called "Images"?
 7910 | 
 7911 | As needed, Claude will call the relevant tools and seek your approval before taking an action:
 7912 | 
 7913 | <Frame style={{ textAlign: "center" }}>
 7914 |   <img src="https://mintlify.s3.us-west-1.amazonaws.com/mcp/images/quickstart-approve.png" width="500" />
 7915 | </Frame>
 7916 | 
 7917 | ## Troubleshooting
 7918 | 
 7919 | <AccordionGroup>
 7920 |   <Accordion title="Server not showing up in Claude / hammer icon missing">
 7921 |     1. Restart Claude for Desktop completely
 7922 |     2. Check your `claude_desktop_config.json` file syntax
 7923 |     3. Make sure the file paths included in `claude_desktop_config.json` are valid and that they are absolute and not relative
 7924 |     4. Look at [logs](#getting-logs-from-claude-for-desktop) to see why the server is not connecting
 7925 |     5. In your command line, try manually running the server (replacing `username` as you did in `claude_desktop_config.json`) to see if you get any errors:
 7926 | 
 7927 |     <Tabs>
 7928 |       <Tab title="MacOS/Linux">
 7929 |         ```bash
 7930 |         npx -y @modelcontextprotocol/server-filesystem /Users/username/Desktop /Users/username/Downloads
 7931 |         ```
 7932 |       </Tab>
 7933 | 
 7934 |       <Tab title="Windows">
 7935 |         ```bash
 7936 |         npx -y @modelcontextprotocol/server-filesystem C:\Users\username\Desktop C:\Users\username\Downloads
 7937 |         ```
 7938 |       </Tab>
 7939 |     </Tabs>
 7940 |   </Accordion>
 7941 | 
 7942 |   <Accordion title="Getting logs from Claude for Desktop">
 7943 |     Claude.app logging related to MCP is written to log files in:
 7944 | 
 7945 |     * macOS: `~/Library/Logs/Claude`
 7946 | 
 7947 |     * Windows: `%APPDATA%\Claude\logs`
 7948 | 
 7949 |     * `mcp.log` will contain general logging about MCP connections and connection failures.
 7950 | 
 7951 |     * Files named `mcp-server-SERVERNAME.log` will contain error (stderr) logging from the named server.
 7952 | 
 7953 |     You can run the following command to list recent logs and follow along with any new ones (on Windows, it will only show recent logs):
 7954 | 
 7955 |     <Tabs>
 7956 |       <Tab title="MacOS/Linux">
 7957 |         ```bash
 7958 |         # Check Claude's logs for errors
 7959 |         tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
 7960 |         ```
 7961 |       </Tab>
 7962 | 
 7963 |       <Tab title="Windows">
 7964 |         ```bash
 7965 |         type "%APPDATA%\Claude\logs\mcp*.log"
 7966 |         ```
 7967 |       </Tab>
 7968 |     </Tabs>
 7969 |   </Accordion>
 7970 | 
 7971 |   <Accordion title="Tool calls failing silently">
 7972 |     If Claude attempts to use the tools but they fail:
 7973 | 
 7974 |     1. Check Claude's logs for errors
 7975 |     2. Verify your server builds and runs without errors
 7976 |     3. Try restarting Claude for Desktop
 7977 |   </Accordion>
 7978 | 
 7979 |   <Accordion title="None of this is working. What do I do?">
 7980 |     Please refer to our [debugging guide](/docs/tools/debugging) for better debugging tools and more detailed guidance.
 7981 |   </Accordion>
 7982 | 
 7983 |   <Accordion title="ENOENT error and `${APPDATA}` in paths on Windows">
 7984 |     If your configured server fails to load, and you see within its logs an error referring to `${APPDATA}` within a path, you may need to add the expanded value of `%APPDATA%` to your `env` key in `claude_desktop_config.json`:
 7985 | 
 7986 |     ```json
 7987 |     {
 7988 |       "brave-search": {
 7989 |         "command": "npx",
 7990 |         "args": ["-y", "@modelcontextprotocol/server-brave-search"],
 7991 |         "env": {
 7992 |           "APPDATA": "C:\\Users\\user\\AppData\\Roaming\\",
 7993 |           "BRAVE_API_KEY": "..."
 7994 |         }
 7995 |       }
 7996 |     }
 7997 |     ```
 7998 | 
 7999 |     With this change in place, launch Claude Desktop once again.
 8000 | 
 8001 |     <Warning>
 8002 |       **NPM should be installed globally**
 8003 | 
 8004 |       The `npx` command may continue to fail if you have not installed NPM globally. If NPM is already installed globally, you will find `%APPDATA%\npm` exists on your system. If not, you can install NPM globally by running the following command:
 8005 | 
 8006 |       ```bash
 8007 |       npm install -g npm
 8008 |       ```
 8009 |     </Warning>
 8010 |   </Accordion>
 8011 | </AccordionGroup>
 8012 | 
 8013 | ## Next steps
 8014 | 
 8015 | <CardGroup cols={2}>
 8016 |   <Card title="Explore other servers" icon="grid" href="/examples">
 8017 |     Check out our gallery of official MCP servers and implementations
 8018 |   </Card>
 8019 | 
 8020 |   <Card title="Build your own server" icon="code" href="/quickstart/server">
 8021 |     Now build your own custom server to use in Claude for Desktop and other
 8022 |     clients
 8023 |   </Card>
 8024 | </CardGroup>
 8025 | 
 8026 | 
 8027 | # Architecture
 8028 | Source: https://modelcontextprotocol.io/specification/2025-06-18/architecture/index
 8029 | 
 8030 | 
 8031 | 
 8032 | <div id="enable-section-numbers" />
 8033 | 
 8034 | The Model Context Protocol (MCP) follows a client-host-server architecture where each
 8035 | host can run multiple client instances. This architecture enables users to integrate AI
 8036 | capabilities across applications while maintaining clear security boundaries and
 8037 | isolating concerns. Built on JSON-RPC, MCP provides a stateful session protocol focused
 8038 | on context exchange and sampling coordination between clients and servers.
 8039 | 
 8040 | ## Core Components
 8041 | 
 8042 | ```mermaid
 8043 | graph LR
 8044 |     subgraph "Application Host Process"
 8045 |         H[Host]
 8046 |         C1[Client 1]
 8047 |         C2[Client 2]
 8048 |         C3[Client 3]
 8049 |         H --> C1
 8050 |         H --> C2
 8051 |         H --> C3
 8052 |     end
 8053 | 
 8054 |     subgraph "Local machine"
 8055 |         S1[Server 1<br>Files & Git]
 8056 |         S2[Server 2<br>Database]
 8057 |         R1[("Local<br>Resource A")]
 8058 |         R2[("Local<br>Resource B")]
 8059 | 
 8060 |         C1 --> S1
 8061 |         C2 --> S2
 8062 |         S1 <--> R1
 8063 |         S2 <--> R2
 8064 |     end
 8065 | 
 8066 |     subgraph "Internet"
 8067 |         S3[Server 3<br>External APIs]
 8068 |         R3[("Remote<br>Resource C")]
 8069 | 
 8070 |         C3 --> S3
 8071 |         S3 <--> R3
 8072 |     end
 8073 | ```
 8074 | 
 8075 | ### Host
 8076 | 
 8077 | The host process acts as the container and coordinator:
 8078 | 
 8079 | * Creates and manages multiple client instances
 8080 | * Controls client connection permissions and lifecycle
 8081 | * Enforces security policies and consent requirements
 8082 | * Handles user authorization decisions
 8083 | * Coordinates AI/LLM integration and sampling
 8084 | * Manages context aggregation across clients
 8085 | 
 8086 | ### Clients
 8087 | 
 8088 | Each client is created by the host and maintains an isolated server connection:
 8089 | 
 8090 | * Establishes one stateful session per server
 8091 | * Handles protocol negotiation and capability exchange
 8092 | * Routes protocol messages bidirectionally
 8093 | * Manages subscriptions and notifications
 8094 | * Maintains security boundaries between servers
 8095 | 
 8096 | A host application creates and manages multiple clients, with each client having a 1:1
 8097 | relationship with a particular server.
 8098 | 
 8099 | ### Servers
 8100 | 
 8101 | Servers provide specialized context and capabilities:
 8102 | 
 8103 | * Expose resources, tools and prompts via MCP primitives
 8104 | * Operate independently with focused responsibilities
 8105 | * Request sampling through client interfaces
 8106 | * Must respect security constraints
 8107 | * Can be local processes or remote services
 8108 | 
 8109 | ## Design Principles
 8110 | 
 8111 | MCP is built on several key design principles that inform its architecture and
 8112 | implementation:
 8113 | 
 8114 | 1. **Servers should be extremely easy to build**
 8115 | 
 8116 |    * Host applications handle complex orchestration responsibilities
 8117 |    * Servers focus on specific, well-defined capabilities
 8118 |    * Simple interfaces minimize implementation overhead
 8119 |    * Clear separation enables maintainable code
 8120 | 
 8121 | 2. **Servers should be highly composable**
 8122 | 
 8123 |    * Each server provides focused functionality in isolation
 8124 |    * Multiple servers can be combined seamlessly
 8125 |    * Shared protocol enables interoperability
 8126 |    * Modular design supports extensibility
 8127 | 
 8128 | 3. **Servers should not be able to read the whole conversation, nor "see into" other
 8129 |    servers**
 8130 | 
 8131 |    * Servers receive only necessary contextual information
 8132 |    * Full conversation history stays with the host
 8133 |    * Each server connection maintains isolation
 8134 |    * Cross-server interactions are controlled by the host
 8135 |    * Host process enforces security boundaries
 8136 | 
 8137 | 4. **Features can be added to servers and clients progressively**
 8138 |    * Core protocol provides minimal required functionality
 8139 |    * Additional capabilities can be negotiated as needed
 8140 |    * Servers and clients evolve independently
 8141 |    * Protocol designed for future extensibility
 8142 |    * Backwards compatibility is maintained
 8143 | 
 8144 | ## Capability Negotiation
 8145 | 
 8146 | The Model Context Protocol uses a capability-based negotiation system where clients and
 8147 | servers explicitly declare their supported features during initialization. Capabilities
 8148 | determine which protocol features and primitives are available during a session.
 8149 | 
 8150 | * Servers declare capabilities like resource subscriptions, tool support, and prompt
 8151 |   templates
 8152 | * Clients declare capabilities like sampling support and notification handling
 8153 | * Both parties must respect declared capabilities throughout the session
 8154 | * Additional capabilities can be negotiated through extensions to the protocol
 8155 | 
 8156 | ```mermaid
 8157 | sequenceDiagram
 8158 |     participant Host
 8159 |     participant Client
 8160 |     participant Server
 8161 | 
 8162 |     Host->>+Client: Initialize client
 8163 |     Client->>+Server: Initialize session with capabilities
 8164 |     Server-->>Client: Respond with supported capabilities
 8165 | 
 8166 |     Note over Host,Server: Active Session with Negotiated Features
 8167 | 
 8168 |     loop Client Requests
 8169 |         Host->>Client: User- or model-initiated action
 8170 |         Client->>Server: Request (tools/resources)
 8171 |         Server-->>Client: Response
 8172 |         Client-->>Host: Update UI or respond to model
 8173 |     end
 8174 | 
 8175 |     loop Server Requests
 8176 |         Server->>Client: Request (sampling)
 8177 |         Client->>Host: Forward to AI
 8178 |         Host-->>Client: AI response
 8179 |         Client-->>Server: Response
 8180 |     end
 8181 | 
 8182 |     loop Notifications
 8183 |         Server--)Client: Resource updates
 8184 |         Client--)Server: Status changes
 8185 |     end
 8186 | 
 8187 |     Host->>Client: Terminate
 8188 |     Client->>-Server: End session
 8189 |     deactivate Server
 8190 | ```
 8191 | 
 8192 | Each capability unlocks specific protocol features for use during the session. For
 8193 | example:
 8194 | 
 8195 | * Implemented [server features](/specification/2025-06-18/server) must be advertised in the
 8196 |   server's capabilities
 8197 | * Emitting resource subscription notifications requires the server to declare
 8198 |   subscription support
 8199 | * Tool invocation requires the server to declare tool capabilities
 8200 | * [Sampling](/specification/2025-06-18/client) requires the client to declare support in its
 8201 |   capabilities
 8202 | 
 8203 | This capability negotiation ensures clients and servers have a clear understanding of
 8204 | supported functionality while maintaining protocol extensibility.
 8205 | 
 8206 | 
 8207 | # Authorization
 8208 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization
 8209 | 
 8210 | 
 8211 | 
 8212 | <div id="enable-section-numbers" />
 8213 | 
 8214 | <Info>**Protocol Revision**: 2025-06-18</Info>
 8215 | 
 8216 | ## Introduction
 8217 | 
 8218 | ### Purpose and Scope
 8219 | 
 8220 | The Model Context Protocol provides authorization capabilities at the transport level,
 8221 | enabling MCP clients to make requests to restricted MCP servers on behalf of resource
 8222 | owners. This specification defines the authorization flow for HTTP-based transports.
 8223 | 
 8224 | ### Protocol Requirements
 8225 | 
 8226 | Authorization is **OPTIONAL** for MCP implementations. When supported:
 8227 | 
 8228 | * Implementations using an HTTP-based transport **SHOULD** conform to this specification.
 8229 | * Implementations using an STDIO transport **SHOULD NOT** follow this specification, and
 8230 |   instead retrieve credentials from the environment.
 8231 | * Implementations using alternative transports **MUST** follow established security best
 8232 |   practices for their protocol.
 8233 | 
 8234 | ### Standards Compliance
 8235 | 
 8236 | This authorization mechanism is based on established specifications listed below, but
 8237 | implements a selected subset of their features to ensure security and interoperability
 8238 | while maintaining simplicity:
 8239 | 
 8240 | * OAuth 2.1 IETF DRAFT ([draft-ietf-oauth-v2-1-12](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12))
 8241 | * OAuth 2.0 Authorization Server Metadata
 8242 |   ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
 8243 | * OAuth 2.0 Dynamic Client Registration Protocol
 8244 |   ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))
 8245 | * OAuth 2.0 Protected Resource Metadata ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728))
 8246 | 
 8247 | ## Authorization Flow
 8248 | 
 8249 | ### Roles
 8250 | 
 8251 | A protected *MCP server* acts as an [OAuth 2.1 resource server](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-12.html#name-roles),
 8252 | capable of accepting and responding to protected resource requests using access tokens.
 8253 | 
 8254 | An *MCP client* acts as an [OAuth 2.1 client](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-12.html#name-roles),
 8255 | making protected resource requests on behalf of a resource owner.
 8256 | 
 8257 | The *authorization server* is responsible for interacting with the user (if necessary) and issuing access tokens for use at the MCP server.
 8258 | The implementation details of the authorization server are beyond the scope of this specification. It may be hosted with the
 8259 | resource server or a separate entity. The [Authorization Server Discovery section](#authorization-server-discovery)
 8260 | specifies how an MCP server indicates the location of its corresponding authorization server to a client.
 8261 | 
 8262 | ### Overview
 8263 | 
 8264 | 1. Authorization servers **MUST** implement OAuth 2.1 with appropriate security
 8265 |    measures for both confidential and public clients.
 8266 | 
 8267 | 2. Authorization servers and MCP clients **SHOULD** support the OAuth 2.0 Dynamic Client Registration
 8268 |    Protocol ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591)).
 8269 | 
 8270 | 3. MCP servers **MUST** implement OAuth 2.0 Protected Resource Metadata ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728)).
 8271 |    MCP clients **MUST** use OAuth 2.0 Protected Resource Metadata for authorization server discovery.
 8272 | 
 8273 | 4. Authorization servers **MUST** provide OAuth 2.0 Authorization
 8274 |    Server Metadata ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414)).
 8275 |    MCP clients **MUST** use the OAuth 2.0 Authorization Server Metadata.
 8276 | 
 8277 | ### Authorization Server Discovery
 8278 | 
 8279 | This section describes the mechanisms by which MCP servers advertise their associated
 8280 | authorization servers to MCP clients, as well as the discovery process through which MCP
 8281 | clients can determine authorization server endpoints and supported capabilities.
 8282 | 
 8283 | #### Authorization Server Location
 8284 | 
 8285 | MCP servers **MUST** implement the OAuth 2.0 Protected Resource Metadata ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728))
 8286 | specification to indicate the locations of authorization servers. The Protected Resource Metadata document returned by the MCP server **MUST** include
 8287 | the `authorization_servers` field containing at least one authorization server.
 8288 | 
 8289 | The specific use of `authorization_servers` is beyond the scope of this specification; implementers should consult
 8290 | OAuth 2.0 Protected Resource Metadata ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728)) for
 8291 | guidance on implementation details.
 8292 | 
 8293 | Implementors should note that Protected Resource Metadata documents can define multiple authorization servers. The responsibility for selecting which authorization server to use lies with the MCP client, following the guidelines specified in
 8294 | [RFC9728 Section 7.6 "Authorization Servers"](https://datatracker.ietf.org/doc/html/rfc9728#name-authorization-servers).
 8295 | 
 8296 | MCP servers **MUST** use the HTTP header `WWW-Authenticate` when returning a *401 Unauthorized* to indicate the location of the resource server metadata URL
 8297 | as described in [RFC9728 Section 5.1 "WWW-Authenticate Response"](https://datatracker.ietf.org/doc/html/rfc9728#name-www-authenticate-response).
 8298 | 
 8299 | MCP clients **MUST** be able to parse `WWW-Authenticate` headers and respond appropriately to `HTTP 401 Unauthorized` responses from the MCP server.
 8300 | 
 8301 | #### Server Metadata Discovery
 8302 | 
 8303 | MCP clients **MUST** follow the OAuth 2.0 Authorization Server Metadata [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414)
 8304 | specification to obtain the information required to interact with the authorization server.
 8305 | 
 8306 | #### Sequence Diagram
 8307 | 
 8308 | The following diagram outlines an example flow:
 8309 | 
 8310 | ```mermaid
 8311 | sequenceDiagram
 8312 |     participant C as Client
 8313 |     participant M as MCP Server (Resource Server)
 8314 |     participant A as Authorization Server
 8315 | 
 8316 |     C->>M: MCP request without token
 8317 |     M-->>C: HTTP 401 Unauthorized with WWW-Authenticate header
 8318 |     Note over C: Extract resource_metadata<br />from WWW-Authenticate
 8319 | 
 8320 |     C->>M: GET /.well-known/oauth-protected-resource
 8321 |     M-->>C: Resource metadata with authorization server URL
 8322 |     Note over C: Validate RS metadata,<br />build AS metadata URL
 8323 | 
 8324 |     C->>A: GET /.well-known/oauth-authorization-server
 8325 |     A-->>C: Authorization server metadata
 8326 | 
 8327 |     Note over C,A: OAuth 2.1 authorization flow happens here
 8328 | 
 8329 |     C->>A: Token request
 8330 |     A-->>C: Access token
 8331 | 
 8332 |     C->>M: MCP request with access token
 8333 |     M-->>C: MCP response
 8334 |     Note over C,M: MCP communication continues with valid token
 8335 | ```
 8336 | 
 8337 | ### Dynamic Client Registration
 8338 | 
 8339 | MCP clients and authorization servers **SHOULD** support the
 8340 | OAuth 2.0 Dynamic Client Registration Protocol [RFC7591](https://datatracker.ietf.org/doc/html/rfc7591)
 8341 | to allow MCP clients to obtain OAuth client IDs without user interaction. This provides a
 8342 | standardized way for clients to automatically register with new authorization servers, which is crucial
 8343 | for MCP because:
 8344 | 
 8345 | * Clients may not know all possible MCP servers and their authorization servers in advance.
 8346 | * Manual registration would create friction for users.
 8347 | * It enables seamless connection to new MCP servers and their authorization servers.
 8348 | * Authorization servers can implement their own registration policies.
 8349 | 
 8350 | Any authorization servers that *do not* support Dynamic Client Registration need to provide
 8351 | alternative ways to obtain a client ID (and, if applicable, client credentials). For one of
 8352 | these authorization servers, MCP clients will have to either:
 8353 | 
 8354 | 1. Hardcode a client ID (and, if applicable, client credentials) specifically for the MCP client to use when
 8355 |    interacting with that authorization server, or
 8356 | 2. Present a UI to users that allows them to enter these details, after registering an
 8357 |    OAuth client themselves (e.g., through a configuration interface hosted by the
 8358 |    server).
 8359 | 
 8360 | ### Authorization Flow Steps
 8361 | 
 8362 | The complete Authorization flow proceeds as follows:
 8363 | 
 8364 | ```mermaid
 8365 | sequenceDiagram
 8366 |     participant B as User-Agent (Browser)
 8367 |     participant C as Client
 8368 |     participant M as MCP Server (Resource Server)
 8369 |     participant A as Authorization Server
 8370 | 
 8371 |     C->>M: MCP request without token
 8372 |     M->>C: HTTP 401 Unauthorized with WWW-Authenticate header
 8373 |     Note over C: Extract resource_metadata URL from WWW-Authenticate
 8374 | 
 8375 |     C->>M: Request Protected Resource Metadata
 8376 |     M->>C: Return metadata
 8377 | 
 8378 |     Note over C: Parse metadata and extract authorization server(s)<br/>Client determines AS to use
 8379 | 
 8380 |     C->>A: GET /.well-known/oauth-authorization-server
 8381 |     A->>C: Authorization server metadata response
 8382 | 
 8383 |     alt Dynamic client registration
 8384 |         C->>A: POST /register
 8385 |         A->>C: Client Credentials
 8386 |     end
 8387 | 
 8388 |     Note over C: Generate PKCE parameters<br/>Include resource parameter
 8389 |     C->>B: Open browser with authorization URL + code_challenge + resource
 8390 |     B->>A: Authorization request with resource parameter
 8391 |     Note over A: User authorizes
 8392 |     A->>B: Redirect to callback with authorization code
 8393 |     B->>C: Authorization code callback
 8394 |     C->>A: Token request + code_verifier + resource
 8395 |     A->>C: Access token (+ refresh token)
 8396 |     C->>M: MCP request with access token
 8397 |     M-->>C: MCP response
 8398 |     Note over C,M: MCP communication continues with valid token
 8399 | ```
 8400 | 
 8401 | #### Resource Parameter Implementation
 8402 | 
 8403 | MCP clients **MUST** implement Resource Indicators for OAuth 2.0 as defined in [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html)
 8404 | to explicitly specify the target resource for which the token is being requested. The `resource` parameter:
 8405 | 
 8406 | 1. **MUST** be included in both authorization requests and token requests.
 8407 | 2. **MUST** identify the MCP server that the client intends to use the token with.
 8408 | 3. **MUST** use the canonical URI of the MCP server as defined in [RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#name-access-token-request).
 8409 | 
 8410 | ##### Canonical Server URI
 8411 | 
 8412 | For the purposes of this specification, the canonical URI of an MCP server is defined as the resource identifier as specified in
 8413 | [RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#section-2) and aligns with the `resource` parameter in
 8414 | [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728).
 8415 | 
 8416 | MCP clients **SHOULD** provide the most specific URI that they can for the MCP server they intend to access, following the guidance in [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707). While the canonical form uses lowercase scheme and host components, implementations **SHOULD** accept uppercase scheme and host components for robustness and interoperability.
 8417 | 
 8418 | Examples of valid canonical URIs:
 8419 | 
 8420 | * `https://mcp.example.com/mcp`
 8421 | * `https://mcp.example.com`
 8422 | * `https://mcp.example.com:8443`
 8423 | * `https://mcp.example.com/server/mcp` (when path component is necessary to identify individual MCP server)
 8424 | 
 8425 | Examples of invalid canonical URIs:
 8426 | 
 8427 | * `mcp.example.com` (missing scheme)
 8428 | * `https://mcp.example.com#fragment` (contains fragment)
 8429 | 
 8430 | > **Note:** While both `https://mcp.example.com/` (with trailing slash) and `https://mcp.example.com` (without trailing slash) are technically valid absolute URIs according to [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986), implementations **SHOULD** consistently use the form without the trailing slash for better interoperability unless the trailing slash is semantically significant for the specific resource.
 8431 | 
 8432 | For example, if accessing an MCP server at `https://mcp.example.com`, the authorization request would include:
 8433 | 
 8434 | ```
 8435 | &resource=https%3A%2F%2Fmcp.example.com
 8436 | ```
 8437 | 
 8438 | MCP clients **MUST** send this parameter regardless of whether authorization servers support it.
 8439 | 
 8440 | ### Access Token Usage
 8441 | 
 8442 | #### Token Requirements
 8443 | 
 8444 | Access token handling when making requests to MCP servers **MUST** conform to the requirements defined in
 8445 | [OAuth 2.1 Section 5 "Resource Requests"](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5).
 8446 | Specifically:
 8447 | 
 8448 | 1. MCP client **MUST** use the Authorization request header field defined in
 8449 |    [OAuth 2.1 Section 5.1.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.1.1):
 8450 | 
 8451 | ```
 8452 | Authorization: Bearer <access-token>
 8453 | ```
 8454 | 
 8455 | Note that authorization **MUST** be included in every HTTP request from client to server,
 8456 | even if they are part of the same logical session.
 8457 | 
 8458 | 2. Access tokens **MUST NOT** be included in the URI query string
 8459 | 
 8460 | Example request:
 8461 | 
 8462 | ```http
 8463 | GET /mcp HTTP/1.1
 8464 | Host: mcp.example.com
 8465 | Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
 8466 | ```
 8467 | 
 8468 | #### Token Handling
 8469 | 
 8470 | MCP servers, acting in their role as an OAuth 2.1 resource server, **MUST** validate access tokens as described in
 8471 | [OAuth 2.1 Section 5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.2).
 8472 | MCP servers **MUST** validate that access tokens were issued specifically for them as the intended audience,
 8473 | according to [RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#section-2).
 8474 | If validation fails, servers **MUST** respond according to
 8475 | [OAuth 2.1 Section 5.3](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.3)
 8476 | error handling requirements. Invalid or expired tokens **MUST** receive a HTTP 401
 8477 | response.
 8478 | 
 8479 | MCP clients **MUST NOT** send tokens to the MCP server other than ones issued by the MCP server's authorization server.
 8480 | 
 8481 | Authorization servers **MUST** only accept tokens that are valid for use with their
 8482 | own resources.
 8483 | 
 8484 | MCP servers **MUST NOT** accept or transit any other tokens.
 8485 | 
 8486 | ### Error Handling
 8487 | 
 8488 | Servers **MUST** return appropriate HTTP status codes for authorization errors:
 8489 | 
 8490 | | Status Code | Description  | Usage                                      |
 8491 | | ----------- | ------------ | ------------------------------------------ |
 8492 | | 401         | Unauthorized | Authorization required or token invalid    |
 8493 | | 403         | Forbidden    | Invalid scopes or insufficient permissions |
 8494 | | 400         | Bad Request  | Malformed authorization request            |
 8495 | 
 8496 | ## Security Considerations
 8497 | 
 8498 | Implementations **MUST** follow OAuth 2.1 security best practices as laid out in [OAuth 2.1 Section 7. "Security Considerations"](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#name-security-considerations).
 8499 | 
 8500 | ### Token Audience Binding and Validation
 8501 | 
 8502 | [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) Resource Indicators provide critical security benefits by binding tokens to their intended
 8503 | audiences **when the Authorization Server supports the capability**. To enable current and future adoption:
 8504 | 
 8505 | * MCP clients **MUST** include the `resource` parameter in authorization and token requests as specified in the [Resource Parameter Implementation](#resource-parameter-implementation) section
 8506 | * MCP servers **MUST** validate that tokens presented to them were specifically issued for their use
 8507 | 
 8508 | The [Security Best Practices document](/specification/draft/basic/security_best_practices#token-passthrough)
 8509 | outlines why token audience validation is crucial and why token passthrough is explicitly forbidden.
 8510 | 
 8511 | ### Token Theft
 8512 | 
 8513 | Attackers who obtain tokens stored by the client, or tokens cached or logged on the server can access protected resources with
 8514 | requests that appear legitimate to resource servers.
 8515 | 
 8516 | Clients and servers **MUST** implement secure token storage and follow OAuth best practices,
 8517 | as outlined in [OAuth 2.1, Section 7.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.1).
 8518 | 
 8519 | Authorization servers **SHOULD** issue short-lived access tokens to reduce the impact of leaked tokens.
 8520 | For public clients, authorization servers **MUST** rotate refresh tokens as described in [OAuth 2.1 Section 4.3.1 "Refresh Token Grant"](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-4.3.1).
 8521 | 
 8522 | ### Communication Security
 8523 | 
 8524 | Implementations **MUST** follow [OAuth 2.1 Section 1.5 "Communication Security"](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-1.5).
 8525 | 
 8526 | Specifically:
 8527 | 
 8528 | 1. All authorization server endpoints **MUST** be served over HTTPS.
 8529 | 2. All redirect URIs **MUST** be either `localhost` or use HTTPS.
 8530 | 
 8531 | ### Authorization Code Protection
 8532 | 
 8533 | An attacker who has gained access to an authorization code contained in an authorization response can try to redeem the authorization code for an access token or otherwise make use of the authorization code.
 8534 | (Further described in [OAuth 2.1 Section 7.5](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.5))
 8535 | 
 8536 | To mitigate this, MCP clients **MUST** implement PKCE according to [OAuth 2.1 Section 7.5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.5.2).
 8537 | PKCE helps prevent authorization code interception and injection attacks by requiring clients to create a secret verifier-challenge pair, ensuring that only the original requestor can exchange an authorization code for tokens.
 8538 | 
 8539 | ### Open Redirection
 8540 | 
 8541 | An attacker may craft malicious redirect URIs to direct users to phishing sites.
 8542 | 
 8543 | MCP clients **MUST** have redirect URIs registered with the authorization server.
 8544 | 
 8545 | Authorization servers **MUST** validate exact redirect URIs against pre-registered values to prevent redirection attacks.
 8546 | 
 8547 | MCP clients **SHOULD** use and verify state parameters in the authorization code flow
 8548 | and discard any results that do not include or have a mismatch with the original state.
 8549 | 
 8550 | Authorization servers **MUST** take precautions to prevent redirecting user agents to untrusted URI's, following suggestions laid out in [OAuth 2.1 Section 7.12.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.12.2)
 8551 | 
 8552 | Authorization servers **SHOULD** only automatically redirect the user agent if it trusts the redirection URI. If the URI is not trusted, the authorization server MAY inform the user and rely on the user to make the correct decision.
 8553 | 
 8554 | ### Confused Deputy Problem
 8555 | 
 8556 | Attackers can exploit MCP servers acting as intermediaries to third-party APIs, leading to [confused deputy vulnerabilities](/specification/2025-06-18/basic/security_best_practices#confused-deputy-problem).
 8557 | By using stolen authorization codes, they can obtain access tokens without user consent.
 8558 | 
 8559 | MCP proxy servers using static client IDs **MUST** obtain user consent for each dynamically
 8560 | registered client before forwarding to third-party authorization servers (which may require additional consent).
 8561 | 
 8562 | ### Access Token Privilege Restriction
 8563 | 
 8564 | An attacker can gain unauthorized access or otherwise compromise a MCP server if the server accepts tokens issued for other resources.
 8565 | 
 8566 | This vulnerability has two critical dimensions:
 8567 | 
 8568 | 1. **Audience validation failures.** When an MCP server doesn't verify that tokens were specifically intended for it (for example, via the audience claim, as mentioned in [RFC9068](https://www.rfc-editor.org/rfc/rfc9068.html)), it may accept tokens originally issued for other services. This breaks a fundamental OAuth security boundary, allowing attackers to reuse legitimate tokens across different services than intended.
 8569 | 2. **Token passthrough.** If the MCP server not only accepts tokens with incorrect audiences but also forwards these unmodified tokens to downstream services, it can potentially cause the ["confused deputy" problem](#confused-deputy-problem), where the downstream API may incorrectly trust the token as if it came from the MCP server or assume the token was validated by the upstream API. See the [Token Passthrough section](/specification/2025-06-18/basic/security_best_practices#token-passthrough) of the Security Best Practices guide for additional details.
 8570 | 
 8571 | MCP servers **MUST** validate access tokens before processing the request, ensuring the access token is issued specifically for the MCP server, and take all necessary steps to ensure no data is returned to unauthorized parties.
 8572 | 
 8573 | A MCP server **MUST** follow the guidelines in [OAuth 2.1 - Section 5.2](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-12.html#section-5.2) to validate inbound tokens.
 8574 | 
 8575 | MCP servers **MUST** only accept tokens specifically intended for themselves and **MUST** reject tokens that do not include them in the audience claim or otherwise verify that they are the intended recipient of the token. See the [Security Best Practices Token Passthrough section](/specification/2025-06-18/basic/security_best_practices#token-passthrough) for details.
 8576 | 
 8577 | If the MCP server makes requests to upstream APIs, it may act as an OAuth client to them. The access token used at the upstream API is a seperate token, issued by the upstream authorization server. The MCP server **MUST NOT** pass through the token it received from the MCP client.
 8578 | 
 8579 | MCP clients **MUST** implement and use the `resource` parameter as defined in [RFC 8707 - Resource Indicators for OAuth 2.0](https://www.rfc-editor.org/rfc/rfc8707.html)
 8580 | to explicitly specify the target resource for which the token is being requested. This requirement aligns with the recommendation in
 8581 | [RFC 9728 Section 7.4](https://datatracker.ietf.org/doc/html/rfc9728#section-7.4). This ensures that access tokens are bound to their intended resources and
 8582 | cannot be misused across different services.
 8583 | 
 8584 | 
 8585 | # Overview
 8586 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/index
 8587 | 
 8588 | 
 8589 | 
 8590 | <div id="enable-section-numbers" />
 8591 | 
 8592 | <Info>**Protocol Revision**: 2025-06-18</Info>
 8593 | 
 8594 | The Model Context Protocol consists of several key components that work together:
 8595 | 
 8596 | * **Base Protocol**: Core JSON-RPC message types
 8597 | * **Lifecycle Management**: Connection initialization, capability negotiation, and
 8598 |   session control
 8599 | * **Authorization**: Authentication and authorization framework for HTTP-based transports
 8600 | * **Server Features**: Resources, prompts, and tools exposed by servers
 8601 | * **Client Features**: Sampling and root directory lists provided by clients
 8602 | * **Utilities**: Cross-cutting concerns like logging and argument completion
 8603 | 
 8604 | All implementations **MUST** support the base protocol and lifecycle management
 8605 | components. Other components **MAY** be implemented based on the specific needs of the
 8606 | application.
 8607 | 
 8608 | These protocol layers establish clear separation of concerns while enabling rich
 8609 | interactions between clients and servers. The modular design allows implementations to
 8610 | support exactly the features they need.
 8611 | 
 8612 | ## Messages
 8613 | 
 8614 | All messages between MCP clients and servers **MUST** follow the
 8615 | [JSON-RPC 2.0](https://www.jsonrpc.org/specification) specification. The protocol defines
 8616 | these types of messages:
 8617 | 
 8618 | ### Requests
 8619 | 
 8620 | Requests are sent from the client to the server or vice versa, to initiate an operation.
 8621 | 
 8622 | ```typescript
 8623 | {
 8624 |   jsonrpc: "2.0";
 8625 |   id: string | number;
 8626 |   method: string;
 8627 |   params?: {
 8628 |     [key: string]: unknown;
 8629 |   };
 8630 | }
 8631 | ```
 8632 | 
 8633 | * Requests **MUST** include a string or integer ID.
 8634 | * Unlike base JSON-RPC, the ID **MUST NOT** be `null`.
 8635 | * The request ID **MUST NOT** have been previously used by the requestor within the same
 8636 |   session.
 8637 | 
 8638 | ### Responses
 8639 | 
 8640 | Responses are sent in reply to requests, containing the result or error of the operation.
 8641 | 
 8642 | ```typescript
 8643 | {
 8644 |   jsonrpc: "2.0";
 8645 |   id: string | number;
 8646 |   result?: {
 8647 |     [key: string]: unknown;
 8648 |   }
 8649 |   error?: {
 8650 |     code: number;
 8651 |     message: string;
 8652 |     data?: unknown;
 8653 |   }
 8654 | }
 8655 | ```
 8656 | 
 8657 | * Responses **MUST** include the same ID as the request they correspond to.
 8658 | * **Responses** are further sub-categorized as either **successful results** or
 8659 |   **errors**. Either a `result` or an `error` **MUST** be set. A response **MUST NOT**
 8660 |   set both.
 8661 | * Results **MAY** follow any JSON object structure, while errors **MUST** include an
 8662 |   error code and message at minimum.
 8663 | * Error codes **MUST** be integers.
 8664 | 
 8665 | ### Notifications
 8666 | 
 8667 | Notifications are sent from the client to the server or vice versa, as a one-way message.
 8668 | The receiver **MUST NOT** send a response.
 8669 | 
 8670 | ```typescript
 8671 | {
 8672 |   jsonrpc: "2.0";
 8673 |   method: string;
 8674 |   params?: {
 8675 |     [key: string]: unknown;
 8676 |   };
 8677 | }
 8678 | ```
 8679 | 
 8680 | * Notifications **MUST NOT** include an ID.
 8681 | 
 8682 | ## Auth
 8683 | 
 8684 | MCP provides an [Authorization](/specification/2025-06-18/basic/authorization) framework for use with HTTP.
 8685 | Implementations using an HTTP-based transport **SHOULD** conform to this specification,
 8686 | whereas implementations using STDIO transport **SHOULD NOT** follow this specification,
 8687 | and instead retrieve credentials from the environment.
 8688 | 
 8689 | Additionally, clients and servers **MAY** negotiate their own custom authentication and
 8690 | authorization strategies.
 8691 | 
 8692 | For further discussions and contributions to the evolution of MCP’s auth mechanisms, join
 8693 | us in
 8694 | [GitHub Discussions](https://github.com/modelcontextprotocol/specification/discussions)
 8695 | to help shape the future of the protocol!
 8696 | 
 8697 | ## Schema
 8698 | 
 8699 | The full specification of the protocol is defined as a
 8700 | [TypeScript schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.ts).
 8701 | This is the source of truth for all protocol messages and structures.
 8702 | 
 8703 | There is also a
 8704 | [JSON Schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.json),
 8705 | which is automatically generated from the TypeScript source of truth, for use with
 8706 | various automated tooling.
 8707 | 
 8708 | ### General fields
 8709 | 
 8710 | #### `_meta`
 8711 | 
 8712 | The `_meta` property/parameter is reserved by MCP to allow clients and servers
 8713 | to attach additional metadata to their interactions.
 8714 | 
 8715 | Certain key names are reserved by MCP for protocol-level metadata, as specified below;
 8716 | implementations MUST NOT make assumptions about values at these keys.
 8717 | 
 8718 | Additionally, definitions in the [schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.ts)
 8719 | may reserve particular names for purpose-specific metadata, as declared in those definitions.
 8720 | 
 8721 | **Key name format:** valid `_meta` key names have two segments: an optional **prefix**, and a **name**.
 8722 | 
 8723 | **Prefix:**
 8724 | 
 8725 | * If specified, MUST be a series of labels separated by dots (`.`), followed by a slash (`/`).
 8726 |   * Labels MUST start with a letter and end with a letter or digit; interior characters can be letters, digits, or hyphens (`-`).
 8727 | * Any prefix beginning with zero or more valid labels, followed by `modelcontextprotocol` or `mcp`, followed by any valid label,
 8728 |   is **reserved** for MCP use.
 8729 |   * For example: `modelcontextprotocol.io/`, `mcp.dev/`, `api.modelcontextprotocol.org/`, and `tools.mcp.com/` are all reserved.
 8730 | 
 8731 | **Name:**
 8732 | 
 8733 | * Unless empty, MUST begin and end with an alphanumeric character (`[a-z0-9A-Z]`).
 8734 | * MAY contain hyphens (`-`), underscores (`_`), dots (`.`), and alphanumerics in between.
 8735 | 
 8736 | 
 8737 | # Lifecycle
 8738 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle
 8739 | 
 8740 | 
 8741 | 
 8742 | <div id="enable-section-numbers" />
 8743 | 
 8744 | <Info>**Protocol Revision**: 2025-06-18</Info>
 8745 | 
 8746 | The Model Context Protocol (MCP) defines a rigorous lifecycle for client-server
 8747 | connections that ensures proper capability negotiation and state management.
 8748 | 
 8749 | 1. **Initialization**: Capability negotiation and protocol version agreement
 8750 | 2. **Operation**: Normal protocol communication
 8751 | 3. **Shutdown**: Graceful termination of the connection
 8752 | 
 8753 | ```mermaid
 8754 | sequenceDiagram
 8755 |     participant Client
 8756 |     participant Server
 8757 | 
 8758 |     Note over Client,Server: Initialization Phase
 8759 |     activate Client
 8760 |     Client->>+Server: initialize request
 8761 |     Server-->>Client: initialize response
 8762 |     Client--)Server: initialized notification
 8763 | 
 8764 |     Note over Client,Server: Operation Phase
 8765 |     rect rgb(200, 220, 250)
 8766 |         note over Client,Server: Normal protocol operations
 8767 |     end
 8768 | 
 8769 |     Note over Client,Server: Shutdown
 8770 |     Client--)-Server: Disconnect
 8771 |     deactivate Server
 8772 |     Note over Client,Server: Connection closed
 8773 | ```
 8774 | 
 8775 | ## Lifecycle Phases
 8776 | 
 8777 | ### Initialization
 8778 | 
 8779 | The initialization phase **MUST** be the first interaction between client and server.
 8780 | During this phase, the client and server:
 8781 | 
 8782 | * Establish protocol version compatibility
 8783 | * Exchange and negotiate capabilities
 8784 | * Share implementation details
 8785 | 
 8786 | The client **MUST** initiate this phase by sending an `initialize` request containing:
 8787 | 
 8788 | * Protocol version supported
 8789 | * Client capabilities
 8790 | * Client implementation information
 8791 | 
 8792 | ```json
 8793 | {
 8794 |   "jsonrpc": "2.0",
 8795 |   "id": 1,
 8796 |   "method": "initialize",
 8797 |   "params": {
 8798 |     "protocolVersion": "2024-11-05",
 8799 |     "capabilities": {
 8800 |       "roots": {
 8801 |         "listChanged": true
 8802 |       },
 8803 |       "sampling": {},
 8804 |       "elicitation": {}
 8805 |     },
 8806 |     "clientInfo": {
 8807 |       "name": "ExampleClient",
 8808 |       "title": "Example Client Display Name",
 8809 |       "version": "1.0.0"
 8810 |     }
 8811 |   }
 8812 | }
 8813 | ```
 8814 | 
 8815 | The server **MUST** respond with its own capabilities and information:
 8816 | 
 8817 | ```json
 8818 | {
 8819 |   "jsonrpc": "2.0",
 8820 |   "id": 1,
 8821 |   "result": {
 8822 |     "protocolVersion": "2024-11-05",
 8823 |     "capabilities": {
 8824 |       "logging": {},
 8825 |       "prompts": {
 8826 |         "listChanged": true
 8827 |       },
 8828 |       "resources": {
 8829 |         "subscribe": true,
 8830 |         "listChanged": true
 8831 |       },
 8832 |       "tools": {
 8833 |         "listChanged": true
 8834 |       }
 8835 |     },
 8836 |     "serverInfo": {
 8837 |       "name": "ExampleServer",
 8838 |       "title": "Example Server Display Name",
 8839 |       "version": "1.0.0"
 8840 |     },
 8841 |     "instructions": "Optional instructions for the client"
 8842 |   }
 8843 | }
 8844 | ```
 8845 | 
 8846 | After successful initialization, the client **MUST** send an `initialized` notification
 8847 | to indicate it is ready to begin normal operations:
 8848 | 
 8849 | ```json
 8850 | {
 8851 |   "jsonrpc": "2.0",
 8852 |   "method": "notifications/initialized"
 8853 | }
 8854 | ```
 8855 | 
 8856 | * The client **SHOULD NOT** send requests other than
 8857 |   [pings](/specification/2025-06-18/basic/utilities/ping) before the server has responded to the
 8858 |   `initialize` request.
 8859 | * The server **SHOULD NOT** send requests other than
 8860 |   [pings](/specification/2025-06-18/basic/utilities/ping) and
 8861 |   [logging](/specification/2025-06-18/server/utilities/logging) before receiving the `initialized`
 8862 |   notification.
 8863 | 
 8864 | #### Version Negotiation
 8865 | 
 8866 | In the `initialize` request, the client **MUST** send a protocol version it supports.
 8867 | This **SHOULD** be the *latest* version supported by the client.
 8868 | 
 8869 | If the server supports the requested protocol version, it **MUST** respond with the same
 8870 | version. Otherwise, the server **MUST** respond with another protocol version it
 8871 | supports. This **SHOULD** be the *latest* version supported by the server.
 8872 | 
 8873 | If the client does not support the version in the server's response, it **SHOULD**
 8874 | disconnect.
 8875 | 
 8876 | <Note>
 8877 |   If using HTTP, the client **MUST** include the `MCP-Protocol-Version: <protocol-version>` HTTP header on all subsequent requests to the MCP
 8878 |   server.
 8879 |   For details, see [the Protocol Version Header section in Transports](/specification/2025-06-18/basic/transports#protocol-version-header).
 8880 | </Note>
 8881 | 
 8882 | #### Capability Negotiation
 8883 | 
 8884 | Client and server capabilities establish which optional protocol features will be
 8885 | available during the session.
 8886 | 
 8887 | Key capabilities include:
 8888 | 
 8889 | | Category | Capability     | Description                                                                               |
 8890 | | -------- | -------------- | ----------------------------------------------------------------------------------------- |
 8891 | | Client   | `roots`        | Ability to provide filesystem [roots](/specification/2025-06-18/client/roots)             |
 8892 | | Client   | `sampling`     | Support for LLM [sampling](/specification/2025-06-18/client/sampling) requests            |
 8893 | | Client   | `elicitation`  | Support for server [elicitation](/specification/2025-06-18/client/elicitation) requests   |
 8894 | | Client   | `experimental` | Describes support for non-standard experimental features                                  |
 8895 | | Server   | `prompts`      | Offers [prompt templates](/specification/2025-06-18/server/prompts)                       |
 8896 | | Server   | `resources`    | Provides readable [resources](/specification/2025-06-18/server/resources)                 |
 8897 | | Server   | `tools`        | Exposes callable [tools](/specification/2025-06-18/server/tools)                          |
 8898 | | Server   | `logging`      | Emits structured [log messages](/specification/2025-06-18/server/utilities/logging)       |
 8899 | | Server   | `completions`  | Supports argument [autocompletion](/specification/2025-06-18/server/utilities/completion) |
 8900 | | Server   | `experimental` | Describes support for non-standard experimental features                                  |
 8901 | 
 8902 | Capability objects can describe sub-capabilities like:
 8903 | 
 8904 | * `listChanged`: Support for list change notifications (for prompts, resources, and
 8905 |   tools)
 8906 | * `subscribe`: Support for subscribing to individual items' changes (resources only)
 8907 | 
 8908 | ### Operation
 8909 | 
 8910 | During the operation phase, the client and server exchange messages according to the
 8911 | negotiated capabilities.
 8912 | 
 8913 | Both parties **MUST**:
 8914 | 
 8915 | * Respect the negotiated protocol version
 8916 | * Only use capabilities that were successfully negotiated
 8917 | 
 8918 | ### Shutdown
 8919 | 
 8920 | During the shutdown phase, one side (usually the client) cleanly terminates the protocol
 8921 | connection. No specific shutdown messages are defined—instead, the underlying transport
 8922 | mechanism should be used to signal connection termination:
 8923 | 
 8924 | #### stdio
 8925 | 
 8926 | For the stdio [transport](/specification/2025-06-18/basic/transports), the client **SHOULD** initiate
 8927 | shutdown by:
 8928 | 
 8929 | 1. First, closing the input stream to the child process (the server)
 8930 | 2. Waiting for the server to exit, or sending `SIGTERM` if the server does not exit
 8931 |    within a reasonable time
 8932 | 3. Sending `SIGKILL` if the server does not exit within a reasonable time after `SIGTERM`
 8933 | 
 8934 | The server **MAY** initiate shutdown by closing its output stream to the client and
 8935 | exiting.
 8936 | 
 8937 | #### HTTP
 8938 | 
 8939 | For HTTP [transports](/specification/2025-06-18/basic/transports), shutdown is indicated by closing the
 8940 | associated HTTP connection(s).
 8941 | 
 8942 | ## Timeouts
 8943 | 
 8944 | Implementations **SHOULD** establish timeouts for all sent requests, to prevent hung
 8945 | connections and resource exhaustion. When the request has not received a success or error
 8946 | response within the timeout period, the sender **SHOULD** issue a [cancellation
 8947 | notification](/specification/2025-06-18/basic/utilities/cancellation) for that request and stop waiting for
 8948 | a response.
 8949 | 
 8950 | SDKs and other middleware **SHOULD** allow these timeouts to be configured on a
 8951 | per-request basis.
 8952 | 
 8953 | Implementations **MAY** choose to reset the timeout clock when receiving a [progress
 8954 | notification](/specification/2025-06-18/basic/utilities/progress) corresponding to the request, as this
 8955 | implies that work is actually happening. However, implementations **SHOULD** always
 8956 | enforce a maximum timeout, regardless of progress notifications, to limit the impact of a
 8957 | misbehaving client or server.
 8958 | 
 8959 | ## Error Handling
 8960 | 
 8961 | Implementations **SHOULD** be prepared to handle these error cases:
 8962 | 
 8963 | * Protocol version mismatch
 8964 | * Failure to negotiate required capabilities
 8965 | * Request [timeouts](#timeouts)
 8966 | 
 8967 | Example initialization error:
 8968 | 
 8969 | ```json
 8970 | {
 8971 |   "jsonrpc": "2.0",
 8972 |   "id": 1,
 8973 |   "error": {
 8974 |     "code": -32602,
 8975 |     "message": "Unsupported protocol version",
 8976 |     "data": {
 8977 |       "supported": ["2024-11-05"],
 8978 |       "requested": "1.0.0"
 8979 |     }
 8980 |   }
 8981 | }
 8982 | ```
 8983 | 
 8984 | 
 8985 | # Security Best Practices
 8986 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices
 8987 | 
 8988 | 
 8989 | 
 8990 | <div id="enable-section-numbers" />
 8991 | 
 8992 | ## Introduction
 8993 | 
 8994 | ### Purpose and Scope
 8995 | 
 8996 | This document provides security considerations for the Model Context Protocol (MCP), complementing the MCP Authorization specification. This document identifies security risks, attack vectors, and best practices specific to MCP implementations.
 8997 | 
 8998 | The primary audience for this document includes developers implementing MCP authorization flows, MCP server operators, and security professionals evaluating MCP-based systems. This document should be read alongside the MCP Authorization specification and [OAuth 2.0 security best practices](https://datatracker.ietf.org/doc/html/rfc9700).
 8999 | 
 9000 | ## Attacks and Mitigations
 9001 | 
 9002 | This section gives a detailed description of attacks on MCP implementations, along with potential countermeasures.
 9003 | 
 9004 | ### Confused Deputy Problem
 9005 | 
 9006 | Attackers can exploit MCP servers proxying other resource servers, creating "[confused deputy](https://en.wikipedia.org/wiki/Confused_deputy_problem)" vulnerabilities.
 9007 | 
 9008 | #### Terminology
 9009 | 
 9010 | **MCP Proxy Server**
 9011 | : An MCP server that connects MCP clients to third-party APIs, offering MCP features while delegating operations and acting as a single OAuth client to the third-party API server.
 9012 | 
 9013 | **Third-Party Authorization Server**
 9014 | : Authorization server that protects the third-party API. It may lack dynamic client registration support, requiring MCP proxy to use a static client ID for all requests.
 9015 | 
 9016 | **Third-Party API**
 9017 | : The protected resource server that provides the actual API functionality. Access to this
 9018 | API requires tokens issued by the third-party authorization server.
 9019 | 
 9020 | **Static Client ID**
 9021 | : A fixed OAuth 2.0 client identifier used by the MCP proxy server when communicating with
 9022 | the third-party authorization server. This Client ID refers to the MCP server acting as a client
 9023 | to the Third-Party API. It is the same value for all MCP server to Third-Party API interactions regardless of
 9024 | which MCP client initiated the request.
 9025 | 
 9026 | #### Architecture and Attack Flows
 9027 | 
 9028 | ##### Normal OAuth proxy usage (preserves user consent)
 9029 | 
 9030 | ```mermaid
 9031 | sequenceDiagram
 9032 |     participant UA as User-Agent (Browser)
 9033 |     participant MC as MCP Client
 9034 |     participant M as MCP Proxy Server
 9035 |     participant TAS as Third-Party Authorization Server
 9036 | 
 9037 |     Note over UA,M: Initial Auth flow completed
 9038 | 
 9039 |     Note over UA,TAS: Step 1: Legitimate user consent for Third Party Server
 9040 | 
 9041 |     M->>UA: Redirect to third party authorization server
 9042 |     UA->>TAS: Authorization request (client_id: mcp-proxy)
 9043 |     TAS->>UA: Authorization consent screen
 9044 |     Note over UA: Review consent screen
 9045 |     UA->>TAS: Approve
 9046 |     TAS->>UA: Set consent cookie for client ID: mcp-proxy
 9047 |     TAS->>UA: 3P Authorization code + redirect to mcp-proxy-server.com
 9048 |     UA->>M: 3P Authorization code
 9049 |     Note over M,TAS: Exchange 3P code for 3P token
 9050 |     Note over M: Generate MCP authorization code
 9051 |     M->>UA: Redirect to MCP Client with MCP authorization code
 9052 | 
 9053 |     Note over M,UA: Exchange code for token, etc.
 9054 | ```
 9055 | 
 9056 | ##### Malicious OAuth proxy usage (skips user consent)
 9057 | 
 9058 | ```mermaid
 9059 | sequenceDiagram
 9060 |     participant UA as User-Agent (Browser)
 9061 |     participant M as MCP Proxy Server
 9062 |     participant TAS as Third-Party Authorization Server
 9063 |     participant A as Attacker
 9064 | 
 9065 | 
 9066 |     Note over UA,A: Step 2: Attack (leveraging existing cookie, skipping consent)
 9067 |     A->>M: Dynamically register malicious client, redirect_uri: attacker.com
 9068 |     A->>UA: Sends malicious link
 9069 |     UA->>TAS: Authorization request (client_id: mcp-proxy) + consent cookie
 9070 |     rect rgba(255, 17, 0, 0.67)
 9071 |     TAS->>TAS: Cookie present, consent skipped
 9072 |     end
 9073 | 
 9074 |    TAS->>UA: 3P Authorization code + redirect to mcp-proxy-server.com
 9075 |    UA->>M: 3P Authorization code
 9076 |    Note over M,TAS: Exchange 3P code for 3P token
 9077 |    Note over M: Generate MCP authorization code
 9078 |    M->>UA: Redirect to attacker.com with MCP Authorization code
 9079 |    UA->>A: MCP Authorization code delivered to attacker.com
 9080 |    Note over M,A: Attacker exchanges MCP code for MCP token
 9081 |    A->>M: Attacker impersonates user to MCP server
 9082 | ```
 9083 | 
 9084 | #### Attack Description
 9085 | 
 9086 | When an MCP proxy server uses a static client ID to authenticate with a third-party
 9087 | authorization server that does not support dynamic client registration, the following
 9088 | attack becomes possible:
 9089 | 
 9090 | 1. A user authenticates normally through the MCP proxy server to access the third-party API
 9091 | 2. During this flow, the third-party authorization server sets a cookie on the user agent
 9092 |    indicating consent for the static client ID
 9093 | 3. An attacker later sends the user a malicious link containing a crafted authorization request which contains a malicious redirect URI along with a new dynamically registered client ID
 9094 | 4. When the user clicks the link, their browser still has the consent cookie from the previous legitimate request
 9095 | 5. The third-party authorization server detects the cookie and skips the consent screen
 9096 | 6. The MCP authorization code is redirected to the attacker's server (specified in the crafted redirect\_uri during dynamic client registration)
 9097 | 7. The attacker exchanges the stolen authorization code for access tokens for the MCP server without the user's explicit approval
 9098 | 8. Attacker now has access to the third-party API as the compromised user
 9099 | 
 9100 | #### Mitigation
 9101 | 
 9102 | MCP proxy servers using static client IDs **MUST** obtain user consent for each dynamically
 9103 | registered client before forwarding to third-party authorization servers (which may require additional consent).
 9104 | 
 9105 | ### Token Passthrough
 9106 | 
 9107 | "Token passthrough" is an anti-pattern where an MCP server accepts tokens from an MCP client without validating that the tokens were properly issued *to the MCP server* and "passing them through" to the downstream API.
 9108 | 
 9109 | #### Risks
 9110 | 
 9111 | Token passthrough is explicitly forbidden in the [authorization specification](/specification/2025-06-18/basic/authorization) as it introduces a number of security risks, that include:
 9112 | 
 9113 | * **Security Control Circumvention**
 9114 |   * The MCP Server or downstream APIs might implement important security controls like rate limiting, request validation, or traffic monitoring, that depend on the token audience or other credential constraints. If clients can obtain and use tokens directly with the downstream APIs without the MCP server validating them properly or ensuring that the tokens are issued for the right service, they bypass these controls.
 9115 | * **Accountability and Audit Trail Issues**
 9116 |   * The MCP Server will be unable to identify or distinguish between MCP Clients when clients are calling with an upstream-issued access token which may be opaque to the MCP Server.
 9117 |   * The downstream Resource Server’s logs may show requests that appear to come from a different source with a different identity, rather than the MCP server that is actually forwarding the tokens.
 9118 |   * Both factors make incident investigation, controls, and auditing more difficult.
 9119 |   * If the MCP Server passes tokens without validating their claims (e.g., roles, privileges, or audience) or other metadata, a malicious actor in possession of a stolen token can use the server as a proxy for data exfiltration.
 9120 | * **Trust Boundary Issues**
 9121 |   * The downstream Resource Server grants trust to specific entities. This trust might include assumptions about origin or client behavior patterns. Breaking this trust boundary could lead to unexpected issues.
 9122 |   * If the token is accepted by multiple services without proper validation, an attacker compromising one service can use the token to access other connected services.
 9123 | * **Future Compatibility Risk**
 9124 |   * Even if an MCP Server starts as a "pure proxy" today, it might need to add security controls later. Starting with proper token audience separation makes it easier to evolve the security model.
 9125 | 
 9126 | #### Mitigation
 9127 | 
 9128 | MCP servers **MUST NOT** accept any tokens that were not explicitly issued for the MCP server.
 9129 | 
 9130 | ### Session Hijacking
 9131 | 
 9132 | Session hijacking is an attack vector where a client is provided a session ID by the server, and an unauthorized party is able to obtain and use that same session ID to impersonate the original client and perform unauthorized actions on their behalf.
 9133 | 
 9134 | #### Session Hijack Prompt Injection
 9135 | 
 9136 | ```mermaid
 9137 | sequenceDiagram
 9138 |     participant Client
 9139 |     participant ServerA
 9140 |     participant Queue
 9141 |     participant ServerB
 9142 |     participant Attacker
 9143 | 
 9144 |     Client->>ServerA: Initialize (connect to streamable HTTP server)
 9145 |     ServerA-->>Client: Respond with session ID
 9146 | 
 9147 |     Attacker->>ServerB: Access/guess session ID
 9148 |     Note right of Attacker: Attacker knows/guesses session ID
 9149 | 
 9150 |     Attacker->>ServerB: Trigger event (malicious payload, using session ID)
 9151 |     ServerB->>Queue: Enqueue event (keyed by session ID)
 9152 | 
 9153 |     ServerA->>Queue: Poll for events (using session ID)
 9154 |     Queue-->>ServerA: Event data (malicious payload)
 9155 | 
 9156 |     ServerA-->>Client: Async response (malicious payload)
 9157 |     Client->>Client: Acts based on malicious payload
 9158 | ```
 9159 | 
 9160 | #### Session Hijack Impersonation
 9161 | 
 9162 | ```mermaid
 9163 | sequenceDiagram
 9164 |     participant Client
 9165 |     participant Server
 9166 |     participant Attacker
 9167 | 
 9168 |     Client->>Server: Initialize (login/authenticate)
 9169 |     Server-->>Client: Respond with session ID (persistent session created)
 9170 | 
 9171 |     Attacker->>Server: Access/guess session ID
 9172 |     Note right of Attacker: Attacker knows/guesses session ID
 9173 | 
 9174 |     Attacker->>Server: Make API call (using session ID, no re-auth)
 9175 |     Server-->>Attacker: Respond as if Attacker is Client (session hijack)
 9176 | ```
 9177 | 
 9178 | #### Attack Description
 9179 | 
 9180 | When you have multiple stateful HTTP servers that handle MCP requests, the following attack vectors are possible:
 9181 | 
 9182 | **Session Hijack Prompt Injection**
 9183 | 
 9184 | 1. The client connects to **Server A** and receives a session ID.
 9185 | 
 9186 | 2. The attacker obtains an existing session ID and sends a malicious event to **Server B** with said session ID.
 9187 | 
 9188 |    * When a server supports [redelivery/resumable streams](/specification/2025-06-18/basic/transports#resumability-and-redelivery), deliberately terminating the request before receiving the response could lead to it being resumed by the original client via the GET request for server sent events.
 9189 |    * If a particular server initiates server sent events as a consequence of a tool call such as a `notifications/tools/list_changed`, where it is possible to affect the tools that are offered by the server, a client could end up with tools that they were not aware were enabled.
 9190 | 
 9191 | 3. **Server B** enqueues the event (associated with session ID) into a shared queue.
 9192 | 
 9193 | 4. **Server A** polls the queue for events using the session ID and retrieves the malicious payload.
 9194 | 
 9195 | 5. **Server A** sends the malicious payload to the client as an asynchronous or resumed response.
 9196 | 
 9197 | 6. The client receives and acts on the malicious payload, leading to potential compromise.
 9198 | 
 9199 | **Session Hijack Impersonation**
 9200 | 
 9201 | 1. The MCP client authenticates with the MCP server, creating a persistent session ID.
 9202 | 2. The attacker obtains the session ID.
 9203 | 3. The attacker makes calls to the MCP server using the session ID.
 9204 | 4. MCP server does not check for additional authorization and treats the attacker as a legitimate user, allowing unauthorized access or actions.
 9205 | 
 9206 | #### Mitigation
 9207 | 
 9208 | To prevent session hijacking and event injection attacks, the following mitigations should be implemented:
 9209 | 
 9210 | MCP servers that implement authorization **MUST** verify all inbound requests.
 9211 | MCP Servers **MUST NOT** use sessions for authentication.
 9212 | 
 9213 | MCP servers **MUST** use secure, non-deterministic session IDs.
 9214 | Generated session IDs (e.g., UUIDs) **SHOULD** use secure random number generators. Avoid predictable or sequential session identifiers that could be guessed by an attacker. Rotating or expiring session IDs can also reduce the risk.
 9215 | 
 9216 | MCP servers **SHOULD** bind session IDs to user-specific information.
 9217 | When storing or transmitting session-related data (e.g., in a queue), combine the session ID with information unique to the authorized user, such as their internal user ID. Use a key format like `<user_id>:<session_id>`. This ensures that even if an attacker guesses a session ID, they cannot impersonate another user as the user ID is derived from the user token and not provided by the client.
 9218 | 
 9219 | MCP servers can optionally leverage additional unique identifiers.
 9220 | 
 9221 | 
 9222 | # Transports
 9223 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports
 9224 | 
 9225 | 
 9226 | 
 9227 | <div id="enable-section-numbers" />
 9228 | 
 9229 | <Info>**Protocol Revision**: 2025-06-18</Info>
 9230 | 
 9231 | MCP uses JSON-RPC to encode messages. JSON-RPC messages **MUST** be UTF-8 encoded.
 9232 | 
 9233 | The protocol currently defines two standard transport mechanisms for client-server
 9234 | communication:
 9235 | 
 9236 | 1. [stdio](#stdio), communication over standard in and standard out
 9237 | 2. [Streamable HTTP](#streamable-http)
 9238 | 
 9239 | Clients **SHOULD** support stdio whenever possible.
 9240 | 
 9241 | It is also possible for clients and servers to implement
 9242 | [custom transports](#custom-transports) in a pluggable fashion.
 9243 | 
 9244 | ## stdio
 9245 | 
 9246 | In the **stdio** transport:
 9247 | 
 9248 | * The client launches the MCP server as a subprocess.
 9249 | * The server reads JSON-RPC messages from its standard input (`stdin`) and sends messages
 9250 |   to its standard output (`stdout`).
 9251 | * Messages are individual JSON-RPC requests, notifications, or responses.
 9252 | * Messages are delimited by newlines, and **MUST NOT** contain embedded newlines.
 9253 | * The server **MAY** write UTF-8 strings to its standard error (`stderr`) for logging
 9254 |   purposes. Clients **MAY** capture, forward, or ignore this logging.
 9255 | * The server **MUST NOT** write anything to its `stdout` that is not a valid MCP message.
 9256 | * The client **MUST NOT** write anything to the server's `stdin` that is not a valid MCP
 9257 |   message.
 9258 | 
 9259 | ```mermaid
 9260 | sequenceDiagram
 9261 |     participant Client
 9262 |     participant Server Process
 9263 | 
 9264 |     Client->>+Server Process: Launch subprocess
 9265 |     loop Message Exchange
 9266 |         Client->>Server Process: Write to stdin
 9267 |         Server Process->>Client: Write to stdout
 9268 |         Server Process--)Client: Optional logs on stderr
 9269 |     end
 9270 |     Client->>Server Process: Close stdin, terminate subprocess
 9271 |     deactivate Server Process
 9272 | ```
 9273 | 
 9274 | ## Streamable HTTP
 9275 | 
 9276 | <Info>
 9277 |   This replaces the [HTTP+SSE
 9278 |   transport](/specification/2024-11-05/basic/transports#http-with-sse) from
 9279 |   protocol version 2024-11-05. See the [backwards compatibility](#backwards-compatibility)
 9280 |   guide below.
 9281 | </Info>
 9282 | 
 9283 | In the **Streamable HTTP** transport, the server operates as an independent process that
 9284 | can handle multiple client connections. This transport uses HTTP POST and GET requests.
 9285 | Server can optionally make use of
 9286 | [Server-Sent Events](https://en.wikipedia.org/wiki/Server-sent_events) (SSE) to stream
 9287 | multiple server messages. This permits basic MCP servers, as well as more feature-rich
 9288 | servers supporting streaming and server-to-client notifications and requests.
 9289 | 
 9290 | The server **MUST** provide a single HTTP endpoint path (hereafter referred to as the
 9291 | **MCP endpoint**) that supports both POST and GET methods. For example, this could be a
 9292 | URL like `https://example.com/mcp`.
 9293 | 
 9294 | #### Security Warning
 9295 | 
 9296 | When implementing Streamable HTTP transport:
 9297 | 
 9298 | 1. Servers **MUST** validate the `Origin` header on all incoming connections to prevent DNS rebinding attacks
 9299 | 2. When running locally, servers **SHOULD** bind only to localhost (127.0.0.1) rather than all network interfaces (0.0.0.0)
 9300 | 3. Servers **SHOULD** implement proper authentication for all connections
 9301 | 
 9302 | Without these protections, attackers could use DNS rebinding to interact with local MCP servers from remote websites.
 9303 | 
 9304 | ### Sending Messages to the Server
 9305 | 
 9306 | Every JSON-RPC message sent from the client **MUST** be a new HTTP POST request to the
 9307 | MCP endpoint.
 9308 | 
 9309 | 1. The client **MUST** use HTTP POST to send JSON-RPC messages to the MCP endpoint.
 9310 | 2. The client **MUST** include an `Accept` header, listing both `application/json` and
 9311 |    `text/event-stream` as supported content types.
 9312 | 3. The body of the POST request **MUST** be a single JSON-RPC *request*, *notification*, or *response*.
 9313 | 4. If the input is a JSON-RPC *response* or *notification*:
 9314 |    * If the server accepts the input, the server **MUST** return HTTP status code 202
 9315 |      Accepted with no body.
 9316 |    * If the server cannot accept the input, it **MUST** return an HTTP error status code
 9317 |      (e.g., 400 Bad Request). The HTTP response body **MAY** comprise a JSON-RPC *error
 9318 |      response* that has no `id`.
 9319 | 5. If the input is a JSON-RPC *request*, the server **MUST** either
 9320 |    return `Content-Type: text/event-stream`, to initiate an SSE stream, or
 9321 |    `Content-Type: application/json`, to return one JSON object. The client **MUST**
 9322 |    support both these cases.
 9323 | 6. If the server initiates an SSE stream:
 9324 |    * The SSE stream **SHOULD** eventually include JSON-RPC *response* for the
 9325 |      JSON-RPC *request* sent in the POST body.
 9326 |    * The server **MAY** send JSON-RPC *requests* and *notifications* before sending the
 9327 |      JSON-RPC *response*. These messages **SHOULD** relate to the originating client
 9328 |      *request*.
 9329 |    * The server **SHOULD NOT** close the SSE stream before sending the JSON-RPC *response*
 9330 |      for the received JSON-RPC *request*, unless the [session](#session-management)
 9331 |      expires.
 9332 |    * After the JSON-RPC *response* has been sent, the server **SHOULD** close the SSE
 9333 |      stream.
 9334 |    * Disconnection **MAY** occur at any time (e.g., due to network conditions).
 9335 |      Therefore:
 9336 |      * Disconnection **SHOULD NOT** be interpreted as the client cancelling its request.
 9337 |      * To cancel, the client **SHOULD** explicitly send an MCP `CancelledNotification`.
 9338 |      * To avoid message loss due to disconnection, the server **MAY** make the stream
 9339 |        [resumable](#resumability-and-redelivery).
 9340 | 
 9341 | ### Listening for Messages from the Server
 9342 | 
 9343 | 1. The client **MAY** issue an HTTP GET to the MCP endpoint. This can be used to open an
 9344 |    SSE stream, allowing the server to communicate to the client, without the client first
 9345 |    sending data via HTTP POST.
 9346 | 2. The client **MUST** include an `Accept` header, listing `text/event-stream` as a
 9347 |    supported content type.
 9348 | 3. The server **MUST** either return `Content-Type: text/event-stream` in response to
 9349 |    this HTTP GET, or else return HTTP 405 Method Not Allowed, indicating that the server
 9350 |    does not offer an SSE stream at this endpoint.
 9351 | 4. If the server initiates an SSE stream:
 9352 |    * The server **MAY** send JSON-RPC *requests* and *notifications* on the stream.
 9353 |    * These messages **SHOULD** be unrelated to any concurrently-running JSON-RPC
 9354 |      *request* from the client.
 9355 |    * The server **MUST NOT** send a JSON-RPC *response* on the stream **unless**
 9356 |      [resuming](#resumability-and-redelivery) a stream associated with a previous client
 9357 |      request.
 9358 |    * The server **MAY** close the SSE stream at any time.
 9359 |    * The client **MAY** close the SSE stream at any time.
 9360 | 
 9361 | ### Multiple Connections
 9362 | 
 9363 | 1. The client **MAY** remain connected to multiple SSE streams simultaneously.
 9364 | 2. The server **MUST** send each of its JSON-RPC messages on only one of the connected
 9365 |    streams; that is, it **MUST NOT** broadcast the same message across multiple streams.
 9366 |    * The risk of message loss **MAY** be mitigated by making the stream
 9367 |      [resumable](#resumability-and-redelivery).
 9368 | 
 9369 | ### Resumability and Redelivery
 9370 | 
 9371 | To support resuming broken connections, and redelivering messages that might otherwise be
 9372 | lost:
 9373 | 
 9374 | 1. Servers **MAY** attach an `id` field to their SSE events, as described in the
 9375 |    [SSE standard](https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation).
 9376 |    * If present, the ID **MUST** be globally unique across all streams within that
 9377 |      [session](#session-management)—or all streams with that specific client, if session
 9378 |      management is not in use.
 9379 | 2. If the client wishes to resume after a broken connection, it **SHOULD** issue an HTTP
 9380 |    GET to the MCP endpoint, and include the
 9381 |    [`Last-Event-ID`](https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header)
 9382 |    header to indicate the last event ID it received.
 9383 |    * The server **MAY** use this header to replay messages that would have been sent
 9384 |      after the last event ID, *on the stream that was disconnected*, and to resume the
 9385 |      stream from that point.
 9386 |    * The server **MUST NOT** replay messages that would have been delivered on a
 9387 |      different stream.
 9388 | 
 9389 | In other words, these event IDs should be assigned by servers on a *per-stream* basis, to
 9390 | act as a cursor within that particular stream.
 9391 | 
 9392 | ### Session Management
 9393 | 
 9394 | An MCP "session" consists of logically related interactions between a client and a
 9395 | server, beginning with the [initialization phase](/specification/2025-06-18/basic/lifecycle). To support
 9396 | servers which want to establish stateful sessions:
 9397 | 
 9398 | 1. A server using the Streamable HTTP transport **MAY** assign a session ID at
 9399 |    initialization time, by including it in an `Mcp-Session-Id` header on the HTTP
 9400 |    response containing the `InitializeResult`.
 9401 |    * The session ID **SHOULD** be globally unique and cryptographically secure (e.g., a
 9402 |      securely generated UUID, a JWT, or a cryptographic hash).
 9403 |    * The session ID **MUST** only contain visible ASCII characters (ranging from 0x21 to
 9404 |      0x7E).
 9405 | 2. If an `Mcp-Session-Id` is returned by the server during initialization, clients using
 9406 |    the Streamable HTTP transport **MUST** include it in the `Mcp-Session-Id` header on
 9407 |    all of their subsequent HTTP requests.
 9408 |    * Servers that require a session ID **SHOULD** respond to requests without an
 9409 |      `Mcp-Session-Id` header (other than initialization) with HTTP 400 Bad Request.
 9410 | 3. The server **MAY** terminate the session at any time, after which it **MUST** respond
 9411 |    to requests containing that session ID with HTTP 404 Not Found.
 9412 | 4. When a client receives HTTP 404 in response to a request containing an
 9413 |    `Mcp-Session-Id`, it **MUST** start a new session by sending a new `InitializeRequest`
 9414 |    without a session ID attached.
 9415 | 5. Clients that no longer need a particular session (e.g., because the user is leaving
 9416 |    the client application) **SHOULD** send an HTTP DELETE to the MCP endpoint with the
 9417 |    `Mcp-Session-Id` header, to explicitly terminate the session.
 9418 |    * The server **MAY** respond to this request with HTTP 405 Method Not Allowed,
 9419 |      indicating that the server does not allow clients to terminate sessions.
 9420 | 
 9421 | ### Sequence Diagram
 9422 | 
 9423 | ```mermaid
 9424 | sequenceDiagram
 9425 |     participant Client
 9426 |     participant Server
 9427 | 
 9428 |     note over Client, Server: initialization
 9429 | 
 9430 |     Client->>+Server: POST InitializeRequest
 9431 |     Server->>-Client: InitializeResponse<br>Mcp-Session-Id: 1868a90c...
 9432 | 
 9433 |     Client->>+Server: POST InitializedNotification<br>Mcp-Session-Id: 1868a90c...
 9434 |     Server->>-Client: 202 Accepted
 9435 | 
 9436 |     note over Client, Server: client requests
 9437 |     Client->>+Server: POST ... request ...<br>Mcp-Session-Id: 1868a90c...
 9438 | 
 9439 |     alt single HTTP response
 9440 |       Server->>Client: ... response ...
 9441 |     else server opens SSE stream
 9442 |       loop while connection remains open
 9443 |           Server-)Client: ... SSE messages from server ...
 9444 |       end
 9445 |       Server-)Client: SSE event: ... response ...
 9446 |     end
 9447 |     deactivate Server
 9448 | 
 9449 |     note over Client, Server: client notifications/responses
 9450 |     Client->>+Server: POST ... notification/response ...<br>Mcp-Session-Id: 1868a90c...
 9451 |     Server->>-Client: 202 Accepted
 9452 | 
 9453 |     note over Client, Server: server requests
 9454 |     Client->>+Server: GET<br>Mcp-Session-Id: 1868a90c...
 9455 |     loop while connection remains open
 9456 |         Server-)Client: ... SSE messages from server ...
 9457 |     end
 9458 |     deactivate Server
 9459 | 
 9460 | ```
 9461 | 
 9462 | ### Protocol Version Header
 9463 | 
 9464 | If using HTTP, the client **MUST** include the `MCP-Protocol-Version: <protocol-version>` HTTP header on all subsequent requests to the MCP
 9465 | server, allowing the MCP server to respond based on the MCP protocol version.
 9466 | 
 9467 | For example: `MCP-Protocol-Version: 2025-06-18`
 9468 | 
 9469 | The protocol version sent by the client **SHOULD** be the one [negotiated during
 9470 | initialization](/specification/2025-06-18/basic/lifecycle#version-negotiation).
 9471 | 
 9472 | For backwards compatibility, if the server does *not* receive an `MCP-Protocol-Version`
 9473 | header, and has no other way to identify the version - for example, by relying on the
 9474 | protocol version negotiated during initialization - the server **SHOULD** assume protocol
 9475 | version `2025-06-18`.
 9476 | 
 9477 | If the server receives a request with an invalid or unsupported
 9478 | `MCP-Protocol-Version`, it **MUST** respond with `400 Bad Request`.
 9479 | 
 9480 | ### Backwards Compatibility
 9481 | 
 9482 | Clients and servers can maintain backwards compatibility with the deprecated [HTTP+SSE
 9483 | transport](/specification/2024-11-05/basic/transports#http-with-sse) (from
 9484 | protocol version 2024-11-05) as follows:
 9485 | 
 9486 | **Servers** wanting to support older clients should:
 9487 | 
 9488 | * Continue to host both the SSE and POST endpoints of the old transport, alongside the
 9489 |   new "MCP endpoint" defined for the Streamable HTTP transport.
 9490 |   * It is also possible to combine the old POST endpoint and the new MCP endpoint, but
 9491 |     this may introduce unneeded complexity.
 9492 | 
 9493 | **Clients** wanting to support older servers should:
 9494 | 
 9495 | 1. Accept an MCP server URL from the user, which may point to either a server using the
 9496 |    old transport or the new transport.
 9497 | 2. Attempt to POST an `InitializeRequest` to the server URL, with an `Accept` header as
 9498 |    defined above:
 9499 |    * If it succeeds, the client can assume this is a server supporting the new Streamable
 9500 |      HTTP transport.
 9501 |    * If it fails with an HTTP 4xx status code (e.g., 405 Method Not Allowed or 404 Not
 9502 |      Found):
 9503 |      * Issue a GET request to the server URL, expecting that this will open an SSE stream
 9504 |        and return an `endpoint` event as the first event.
 9505 |      * When the `endpoint` event arrives, the client can assume this is a server running
 9506 |        the old HTTP+SSE transport, and should use that transport for all subsequent
 9507 |        communication.
 9508 | 
 9509 | ## Custom Transports
 9510 | 
 9511 | Clients and servers **MAY** implement additional custom transport mechanisms to suit
 9512 | their specific needs. The protocol is transport-agnostic and can be implemented over any
 9513 | communication channel that supports bidirectional message exchange.
 9514 | 
 9515 | Implementers who choose to support custom transports **MUST** ensure they preserve the
 9516 | JSON-RPC message format and lifecycle requirements defined by MCP. Custom transports
 9517 | **SHOULD** document their specific connection establishment and message exchange patterns
 9518 | to aid interoperability.
 9519 | 
 9520 | 
 9521 | # Cancellation
 9522 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/cancellation
 9523 | 
 9524 | 
 9525 | 
 9526 | <div id="enable-section-numbers" />
 9527 | 
 9528 | <Info>**Protocol Revision**: 2025-06-18</Info>
 9529 | 
 9530 | The Model Context Protocol (MCP) supports optional cancellation of in-progress requests
 9531 | through notification messages. Either side can send a cancellation notification to
 9532 | indicate that a previously-issued request should be terminated.
 9533 | 
 9534 | ## Cancellation Flow
 9535 | 
 9536 | When a party wants to cancel an in-progress request, it sends a `notifications/cancelled`
 9537 | notification containing:
 9538 | 
 9539 | * The ID of the request to cancel
 9540 | * An optional reason string that can be logged or displayed
 9541 | 
 9542 | ```json
 9543 | {
 9544 |   "jsonrpc": "2.0",
 9545 |   "method": "notifications/cancelled",
 9546 |   "params": {
 9547 |     "requestId": "123",
 9548 |     "reason": "User requested cancellation"
 9549 |   }
 9550 | }
 9551 | ```
 9552 | 
 9553 | ## Behavior Requirements
 9554 | 
 9555 | 1. Cancellation notifications **MUST** only reference requests that:
 9556 |    * Were previously issued in the same direction
 9557 |    * Are believed to still be in-progress
 9558 | 2. The `initialize` request **MUST NOT** be cancelled by clients
 9559 | 3. Receivers of cancellation notifications **SHOULD**:
 9560 |    * Stop processing the cancelled request
 9561 |    * Free associated resources
 9562 |    * Not send a response for the cancelled request
 9563 | 4. Receivers **MAY** ignore cancellation notifications if:
 9564 |    * The referenced request is unknown
 9565 |    * Processing has already completed
 9566 |    * The request cannot be cancelled
 9567 | 5. The sender of the cancellation notification **SHOULD** ignore any response to the
 9568 |    request that arrives afterward
 9569 | 
 9570 | ## Timing Considerations
 9571 | 
 9572 | Due to network latency, cancellation notifications may arrive after request processing
 9573 | has completed, and potentially after a response has already been sent.
 9574 | 
 9575 | Both parties **MUST** handle these race conditions gracefully:
 9576 | 
 9577 | ```mermaid
 9578 | sequenceDiagram
 9579 |    participant Client
 9580 |    participant Server
 9581 | 
 9582 |    Client->>Server: Request (ID: 123)
 9583 |    Note over Server: Processing starts
 9584 |    Client--)Server: notifications/cancelled (ID: 123)
 9585 |    alt
 9586 |       Note over Server: Processing may have<br/>completed before<br/>cancellation arrives
 9587 |    else If not completed
 9588 |       Note over Server: Stop processing
 9589 |    end
 9590 | ```
 9591 | 
 9592 | ## Implementation Notes
 9593 | 
 9594 | * Both parties **SHOULD** log cancellation reasons for debugging
 9595 | * Application UIs **SHOULD** indicate when cancellation is requested
 9596 | 
 9597 | ## Error Handling
 9598 | 
 9599 | Invalid cancellation notifications **SHOULD** be ignored:
 9600 | 
 9601 | * Unknown request IDs
 9602 | * Already completed requests
 9603 | * Malformed notifications
 9604 | 
 9605 | This maintains the "fire and forget" nature of notifications while allowing for race
 9606 | conditions in asynchronous communication.
 9607 | 
 9608 | 
 9609 | # Ping
 9610 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/ping
 9611 | 
 9612 | 
 9613 | 
 9614 | <div id="enable-section-numbers" />
 9615 | 
 9616 | <Info>**Protocol Revision**: 2025-06-18</Info>
 9617 | 
 9618 | The Model Context Protocol includes an optional ping mechanism that allows either party
 9619 | to verify that their counterpart is still responsive and the connection is alive.
 9620 | 
 9621 | ## Overview
 9622 | 
 9623 | The ping functionality is implemented through a simple request/response pattern. Either
 9624 | the client or server can initiate a ping by sending a `ping` request.
 9625 | 
 9626 | ## Message Format
 9627 | 
 9628 | A ping request is a standard JSON-RPC request with no parameters:
 9629 | 
 9630 | ```json
 9631 | {
 9632 |   "jsonrpc": "2.0",
 9633 |   "id": "123",
 9634 |   "method": "ping"
 9635 | }
 9636 | ```
 9637 | 
 9638 | ## Behavior Requirements
 9639 | 
 9640 | 1. The receiver **MUST** respond promptly with an empty response:
 9641 | 
 9642 | ```json
 9643 | {
 9644 |   "jsonrpc": "2.0",
 9645 |   "id": "123",
 9646 |   "result": {}
 9647 | }
 9648 | ```
 9649 | 
 9650 | 2. If no response is received within a reasonable timeout period, the sender **MAY**:
 9651 |    * Consider the connection stale
 9652 |    * Terminate the connection
 9653 |    * Attempt reconnection procedures
 9654 | 
 9655 | ## Usage Patterns
 9656 | 
 9657 | ```mermaid
 9658 | sequenceDiagram
 9659 |     participant Sender
 9660 |     participant Receiver
 9661 | 
 9662 |     Sender->>Receiver: ping request
 9663 |     Receiver->>Sender: empty response
 9664 | ```
 9665 | 
 9666 | ## Implementation Considerations
 9667 | 
 9668 | * Implementations **SHOULD** periodically issue pings to detect connection health
 9669 | * The frequency of pings **SHOULD** be configurable
 9670 | * Timeouts **SHOULD** be appropriate for the network environment
 9671 | * Excessive pinging **SHOULD** be avoided to reduce network overhead
 9672 | 
 9673 | ## Error Handling
 9674 | 
 9675 | * Timeouts **SHOULD** be treated as connection failures
 9676 | * Multiple failed pings **MAY** trigger connection reset
 9677 | * Implementations **SHOULD** log ping failures for diagnostics
 9678 | 
 9679 | 
 9680 | # Progress
 9681 | Source: https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/progress
 9682 | 
 9683 | 
 9684 | 
 9685 | <div id="enable-section-numbers" />
 9686 | 
 9687 | <Info>**Protocol Revision**: 2025-06-18</Info>
 9688 | 
 9689 | The Model Context Protocol (MCP) supports optional progress tracking for long-running
 9690 | operations through notification messages. Either side can send progress notifications to
 9691 | provide updates about operation status.
 9692 | 
 9693 | ## Progress Flow
 9694 | 
 9695 | When a party wants to *receive* progress updates for a request, it includes a
 9696 | `progressToken` in the request metadata.
 9697 | 
 9698 | * Progress tokens **MUST** be a string or integer value
 9699 | * Progress tokens can be chosen by the sender using any means, but **MUST** be unique
 9700 |   across all active requests.
 9701 | 
 9702 | ```json
 9703 | {
 9704 |   "jsonrpc": "2.0",
 9705 |   "id": 1,
 9706 |   "method": "some_method",
 9707 |   "params": {
 9708 |     "_meta": {
 9709 |       "progressToken": "abc123"
 9710 |     }
 9711 |   }
 9712 | }
 9713 | ```
 9714 | 
 9715 | The receiver **MAY** then send progress notifications containing:
 9716 | 
 9717 | * The original progress token
 9718 | * The current progress value so far
 9719 | * An optional "total" value
 9720 | * An optional "message" value
 9721 | 
 9722 | ```json
 9723 | {
 9724 |   "jsonrpc": "2.0",
 9725 |   "method": "notifications/progress",
 9726 |   "params": {
 9727 |     "progressToken": "abc123",
 9728 |     "progress": 50,
 9729 |     "total": 100,
 9730 |     "message": "Reticulating splines..."
 9731 |   }
 9732 | }
 9733 | ```
 9734 | 
 9735 | * The `progress` value **MUST** increase with each notification, even if the total is
 9736 |   unknown.
 9737 | * The `progress` and the `total` values **MAY** be floating point.
 9738 | * The `message` field **SHOULD** provide relevant human readable progress information.
 9739 | 
 9740 | ## Behavior Requirements
 9741 | 
 9742 | 1. Progress notifications **MUST** only reference tokens that:
 9743 | 
 9744 |    * Were provided in an active request
 9745 |    * Are associated with an in-progress operation
 9746 | 
 9747 | 2. Receivers of progress requests **MAY**:
 9748 |    * Choose not to send any progress notifications
 9749 |    * Send notifications at whatever frequency they deem appropriate
 9750 |    * Omit the total value if unknown
 9751 | 
 9752 | ```mermaid
 9753 | sequenceDiagram
 9754 |     participant Sender
 9755 |     participant Receiver
 9756 | 
 9757 |     Note over Sender,Receiver: Request with progress token
 9758 |     Sender->>Receiver: Method request with progressToken
 9759 | 
 9760 |     Note over Sender,Receiver: Progress updates
 9761 |     loop Progress Updates
 9762 |         Receiver-->>Sender: Progress notification (0.2/1.0)
 9763 |         Receiver-->>Sender: Progress notification (0.6/1.0)
 9764 |         Receiver-->>Sender: Progress notification (1.0/1.0)
 9765 |     end
 9766 | 
 9767 |     Note over Sender,Receiver: Operation complete
 9768 |     Receiver->>Sender: Method response
 9769 | ```
 9770 | 
 9771 | ## Implementation Notes
 9772 | 
 9773 | * Senders and receivers **SHOULD** track active progress tokens
 9774 | * Both parties **SHOULD** implement rate limiting to prevent flooding
 9775 | * Progress notifications **MUST** stop after completion
 9776 | 
 9777 | 
 9778 | # Key Changes
 9779 | Source: https://modelcontextprotocol.io/specification/2025-06-18/changelog
 9780 | 
 9781 | 
 9782 | 
 9783 | <div id="enable-section-numbers" />
 9784 | 
 9785 | This document lists changes made to the Model Context Protocol (MCP) specification since
 9786 | the previous revision, [2025-03-26](/specification/2025-03-26).
 9787 | 
 9788 | ## Major changes
 9789 | 
 9790 | 1. Remove support for JSON-RPC **[batching](https://www.jsonrpc.org/specification#batch)**
 9791 |    (PR [#416](https://github.com/modelcontextprotocol/specification/pull/416))
 9792 | 2. Add support for [structured tool output](/specification/2025-06-18/server/tools#structured-content)
 9793 |    (PR [#371](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/371))
 9794 | 3. Classify MCP servers as [OAuth Resource Servers](/specification/2025-06-18/basic/authorization#authorization-server-discovery),
 9795 |    adding protected resource metadata to discover the corresponding Authorization server.
 9796 |    (PR [#338](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/338))
 9797 | 4. Require MCP clients to implement Resource Indicators as described in [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) to prevent
 9798 |    malicious servers from obtaining access tokens.
 9799 |    (PR [#734](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/734))
 9800 | 5. Clarify [security considerations](/specification/2025-06-18/basic/authorization#security-considerations) and best practices
 9801 |    in the authorization spec and in a new [security best practices page](/specification/2025-06-18/basic/security_best_practices).
 9802 | 6. Add support for **[elicitation](/specification/2025-06-18/client/elicitation)**, enabling servers to request additional
 9803 |    information from users during interactions.
 9804 |    (PR [#382](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/382))
 9805 | 7. Add support for **[resource links](/specification/2025-06-18/server/tools#resource-links)** in
 9806 |    tool call results. (PR [#603](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/603))
 9807 | 8. Require [negotiated protocol version to be specified](/specification/2025-06-18/basic/transports#protocol-version-header)
 9808 |    via `MCP-Protocol-Version` header in subsequent requests when using HTTP (PR [#548](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/548)).
 9809 | 9. Change **SHOULD** to **MUST** in [Lifecycle Operation](/specification/2025-06-18/basic/lifecycle#operation)
 9810 | 
 9811 | ## Other schema changes
 9812 | 
 9813 | 1. Add `_meta` field to additional interface types (PR [#710](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/710)),
 9814 |    and specify [proper usage](/specification/2025-06-18/basic#meta).
 9815 | 2. Add `context` field to `CompletionRequest`, providing for completion requests to include
 9816 |    previously-resolved variables (PR [#598](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/598)).
 9817 | 3. Add `title` field for human-friendly display names, so that `name` can be used as a programmatic
 9818 |    identifier (PR [#663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/663))
 9819 | 
 9820 | ## Full changelog
 9821 | 
 9822 | For a complete list of all changes that have been made since the last protocol revision,
 9823 | [see GitHub](https://github.com/modelcontextprotocol/specification/compare/2025-03-26...2025-06-18).
 9824 | 
 9825 | 
 9826 | # Elicitation
 9827 | Source: https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation
 9828 | 
 9829 | 
 9830 | 
 9831 | <div id="enable-section-numbers" />
 9832 | 
 9833 | <Info>**Protocol Revision**: 2025-06-18</Info>
 9834 | 
 9835 | <Note>
 9836 |   Elicitation is newly introduced in this version of the MCP specification and its design may evolve in future protocol versions.
 9837 | </Note>
 9838 | 
 9839 | The Model Context Protocol (MCP) provides a standardized way for servers to request additional
 9840 | information from users through the client during interactions. This flow allows clients to
 9841 | maintain control over user interactions and data sharing while enabling servers to gather
 9842 | necessary information dynamically.
 9843 | Servers request structured data from users with JSON schemas to validate responses.
 9844 | 
 9845 | ## User Interaction Model
 9846 | 
 9847 | Elicitation in MCP allows servers to implement interactive workflows by enabling user input
 9848 | requests to occur *nested* inside other MCP server features.
 9849 | 
 9850 | Implementations are free to expose elicitation through any interface pattern that suits
 9851 | their needs—the protocol itself does not mandate any specific user interaction
 9852 | model.
 9853 | 
 9854 | <Warning>
 9855 |   For trust & safety and security:
 9856 | 
 9857 |   * Servers **MUST NOT** use elicitation to request sensitive information.
 9858 | 
 9859 |   Applications **SHOULD**:
 9860 | 
 9861 |   * Provide UI that makes it clear which server is requesting information
 9862 |   * Allow users to review and modify their responses before sending
 9863 |   * Respect user privacy and provide clear reject and cancel options
 9864 | </Warning>
 9865 | 
 9866 | ## Capabilities
 9867 | 
 9868 | Clients that support elicitation **MUST** declare the `elicitation` capability during
 9869 | [initialization](/specification/2025-06-18/basic/lifecycle#initialization):
 9870 | 
 9871 | ```json
 9872 | {
 9873 |   "capabilities": {
 9874 |     "elicitation": {}
 9875 |   }
 9876 | }
 9877 | ```
 9878 | 
 9879 | ## Protocol Messages
 9880 | 
 9881 | ### Creating Elicitation Requests
 9882 | 
 9883 | To request information from a user, servers send an `elicitation/create` request:
 9884 | 
 9885 | #### Simple Text Request
 9886 | 
 9887 | **Request:**
 9888 | 
 9889 | ```json
 9890 | {
 9891 |   "jsonrpc": "2.0",
 9892 |   "id": 1,
 9893 |   "method": "elicitation/create",
 9894 |   "params": {
 9895 |     "message": "Please provide your GitHub username",
 9896 |     "requestedSchema": {
 9897 |       "type": "object",
 9898 |       "properties": {
 9899 |         "name": {
 9900 |           "type": "string"
 9901 |         }
 9902 |       },
 9903 |       "required": ["name"]
 9904 |     }
 9905 |   }
 9906 | }
 9907 | ```
 9908 | 
 9909 | **Response:**
 9910 | 
 9911 | ```json
 9912 | {
 9913 |   "jsonrpc": "2.0",
 9914 |   "id": 1,
 9915 |   "result": {
 9916 |     "action": "accept",
 9917 |     "content": {
 9918 |       "name": "octocat"
 9919 |     }
 9920 |   }
 9921 | }
 9922 | ```
 9923 | 
 9924 | #### Structured Data Request
 9925 | 
 9926 | **Request:**
 9927 | 
 9928 | ```json
 9929 | {
 9930 |   "jsonrpc": "2.0",
 9931 |   "id": 2,
 9932 |   "method": "elicitation/create",
 9933 |   "params": {
 9934 |     "message": "Please provide your contact information",
 9935 |     "requestedSchema": {
 9936 |       "type": "object",
 9937 |       "properties": {
 9938 |         "name": {
 9939 |           "type": "string",
 9940 |           "description": "Your full name"
 9941 |         },
 9942 |         "email": {
 9943 |           "type": "string",
 9944 |           "format": "email",
 9945 |           "description": "Your email address"
 9946 |         },
 9947 |         "age": {
 9948 |           "type": "number",
 9949 |           "minimum": 18,
 9950 |           "description": "Your age"
 9951 |         }
 9952 |       },
 9953 |       "required": ["name", "email"]
 9954 |     }
 9955 |   }
 9956 | }
 9957 | ```
 9958 | 
 9959 | **Response:**
 9960 | 
 9961 | ```json
 9962 | {
 9963 |   "jsonrpc": "2.0",
 9964 |   "id": 2,
 9965 |   "result": {
 9966 |     "action": "accept",
 9967 |     "content": {
 9968 |       "name": "Monalisa Octocat",
 9969 |       "email": "[email protected]",
 9970 |       "age": 30
 9971 |     }
 9972 |   }
 9973 | }
 9974 | ```
 9975 | 
 9976 | **Reject Response Example:**
 9977 | 
 9978 | ```json
 9979 | {
 9980 |   "jsonrpc": "2.0",
 9981 |   "id": 2,
 9982 |   "result": {
 9983 |     "action": "reject"
 9984 |   }
 9985 | }
 9986 | ```
 9987 | 
 9988 | **Cancel Response Example:**
 9989 | 
 9990 | ```json
 9991 | {
 9992 |   "jsonrpc": "2.0",
 9993 |   "id": 2,
 9994 |   "result": {
 9995 |     "action": "cancel"
 9996 |   }
 9997 | }
 9998 | ```
 9999 | 
10000 | ## Message Flow
10001 | 
10002 | ```mermaid
10003 | sequenceDiagram
10004 |     participant User
10005 |     participant Client
10006 |     participant Server
10007 | 
10008 |     Note over Server,Client: Server initiates elicitation
10009 |     Server->>Client: elicitation/create
10010 | 
10011 |     Note over Client,User: Human interaction
10012 |     Client->>User: Present elicitation UI
10013 |     User-->>Client: Provide requested information
10014 | 
10015 |     Note over Server,Client: Complete request
10016 |     Client-->>Server: Return user response
10017 | 
10018 |     Note over Server: Continue processing with new information
10019 | ```
10020 | 
10021 | ## Request Schema
10022 | 
10023 | The `requestedSchema` field allows servers to define the structure of the expected response using a restricted subset of JSON Schema. To simplify implementation for clients, elicitation schemas are limited to flat objects with primitive properties only:
10024 | 
10025 | ```json
10026 | "requestedSchema": {
10027 |   "type": "object",
10028 |   "properties": {
10029 |     "propertyName": {
10030 |       "type": "string",
10031 |       "title": "Display Name",
10032 |       "description": "Description of the property"
10033 |     },
10034 |     "anotherProperty": {
10035 |       "type": "number",
10036 |       "minimum": 0,
10037 |       "maximum": 100
10038 |     }
10039 |   },
10040 |   "required": ["propertyName"]
10041 | }
10042 | ```
10043 | 
10044 | ### Supported Schema Types
10045 | 
10046 | The schema is restricted to these primitive types:
10047 | 
10048 | 1. **String Schema**
10049 | 
10050 |    ```json
10051 |    {
10052 |      "type": "string",
10053 |      "title": "Display Name",
10054 |      "description": "Description text",
10055 |      "minLength": 3,
10056 |      "maxLength": 50,
10057 |      "format": "email" // Supported: "email", "uri", "date", "date-time"
10058 |    }
10059 |    ```
10060 | 
10061 |    Supported formats: `email`, `uri`, `date`, `date-time`
10062 | 
10063 | 2. **Number Schema**
10064 | 
10065 |    ```json
10066 |    {
10067 |      "type": "number", // or "integer"
10068 |      "title": "Display Name",
10069 |      "description": "Description text",
10070 |      "minimum": 0,
10071 |      "maximum": 100
10072 |    }
10073 |    ```
10074 | 
10075 | 3. **Boolean Schema**
10076 | 
10077 |    ```json
10078 |    {
10079 |      "type": "boolean",
10080 |      "title": "Display Name",
10081 |      "description": "Description text",
10082 |      "default": false
10083 |    }
10084 |    ```
10085 | 
10086 | 4. **Enum Schema**
10087 |    ```json
10088 |    {
10089 |      "type": "string",
10090 |      "title": "Display Name",
10091 |      "description": "Description text",
10092 |      "enum": ["option1", "option2", "option3"],
10093 |      "enumNames": ["Option 1", "Option 2", "Option 3"]
10094 |    }
10095 |    ```
10096 | 
10097 | Clients can use this schema to:
10098 | 
10099 | 1. Generate appropriate input forms
10100 | 2. Validate user input before sending
10101 | 3. Provide better guidance to users
10102 | 
10103 | Note that complex nested structures, arrays of objects, and other advanced JSON Schema features are intentionally not supported to simplify client implementation.
10104 | 
10105 | ## Response Actions
10106 | 
10107 | Elicitation responses use a three-action model to clearly distinguish between different user actions:
10108 | 
10109 | ```json
10110 | {
10111 |   "jsonrpc": "2.0",
10112 |   "id": 1,
10113 |   "result": {
10114 |     "action": "accept", // or "reject" or "cancel"
10115 |     "content": {
10116 |       "propertyName": "value",
10117 |       "anotherProperty": 42
10118 |     }
10119 |   }
10120 | }
10121 | ```
10122 | 
10123 | The three response actions are:
10124 | 
10125 | 1. **Accept** (`action: "accept"`): User explicitly approved and submitted with data
10126 | 
10127 |    * The `content` field contains the submitted data matching the requested schema
10128 |    * Example: User clicked "Submit", "OK", "Confirm", etc.
10129 | 
10130 | 2. **Reject** (`action: "reject"`): User explicitly rejected the request
10131 | 
10132 |    * The `content` field is typically omitted
10133 |    * Example: User clicked "Reject", "Decline", "No", etc.
10134 | 
10135 | 3. **Cancel** (`action: "cancel"`): User dismissed without making an explicit choice
10136 |    * The `content` field is typically omitted
10137 |    * Example: User closed the dialog, clicked outside, pressed Escape, etc.
10138 | 
10139 | Servers should handle each state appropriately:
10140 | 
10141 | * **Accept**: Process the submitted data
10142 | * **Reject**: Handle explicit rejection (e.g., offer alternatives)
10143 | * **Cancel**: Handle dismissal (e.g., prompt again later)
10144 | 
10145 | ## Security Considerations
10146 | 
10147 | 1. Servers **MUST NOT** request sensitive information through elicitation
10148 | 2. Clients **SHOULD** implement user approval controls
10149 | 3. Both parties **SHOULD** validate elicitation content against the provided schema
10150 | 4. Clients **SHOULD** provide clear indication of which server is requesting information
10151 | 5. Clients **SHOULD** allow users to reject elicitation requests at any time
10152 | 6. Clients **SHOULD** implement rate limiting
10153 | 7. Clients **SHOULD** present elicitation requests in a way that makes it clear what information is being requested and why
10154 | 
10155 | 
10156 | # Roots
10157 | Source: https://modelcontextprotocol.io/specification/2025-06-18/client/roots
10158 | 
10159 | 
10160 | 
10161 | <div id="enable-section-numbers" />
10162 | 
10163 | <Info>**Protocol Revision**: 2025-06-18</Info>
10164 | 
10165 | The Model Context Protocol (MCP) provides a standardized way for clients to expose
10166 | filesystem "roots" to servers. Roots define the boundaries of where servers can operate
10167 | within the filesystem, allowing them to understand which directories and files they have
10168 | access to. Servers can request the list of roots from supporting clients and receive
10169 | notifications when that list changes.
10170 | 
10171 | ## User Interaction Model
10172 | 
10173 | Roots in MCP are typically exposed through workspace or project configuration interfaces.
10174 | 
10175 | For example, implementations could offer a workspace/project picker that allows users to
10176 | select directories and files the server should have access to. This can be combined with
10177 | automatic workspace detection from version control systems or project files.
10178 | 
10179 | However, implementations are free to expose roots through any interface pattern that
10180 | suits their needs—the protocol itself does not mandate any specific user
10181 | interaction model.
10182 | 
10183 | ## Capabilities
10184 | 
10185 | Clients that support roots **MUST** declare the `roots` capability during
10186 | [initialization](/specification/2025-06-18/basic/lifecycle#initialization):
10187 | 
10188 | ```json
10189 | {
10190 |   "capabilities": {
10191 |     "roots": {
10192 |       "listChanged": true
10193 |     }
10194 |   }
10195 | }
10196 | ```
10197 | 
10198 | `listChanged` indicates whether the client will emit notifications when the list of roots
10199 | changes.
10200 | 
10201 | ## Protocol Messages
10202 | 
10203 | ### Listing Roots
10204 | 
10205 | To retrieve roots, servers send a `roots/list` request:
10206 | 
10207 | **Request:**
10208 | 
10209 | ```json
10210 | {
10211 |   "jsonrpc": "2.0",
10212 |   "id": 1,
10213 |   "method": "roots/list"
10214 | }
10215 | ```
10216 | 
10217 | **Response:**
10218 | 
10219 | ```json
10220 | {
10221 |   "jsonrpc": "2.0",
10222 |   "id": 1,
10223 |   "result": {
10224 |     "roots": [
10225 |       {
10226 |         "uri": "file:///home/user/projects/myproject",
10227 |         "name": "My Project"
10228 |       }
10229 |     ]
10230 |   }
10231 | }
10232 | ```
10233 | 
10234 | ### Root List Changes
10235 | 
10236 | When roots change, clients that support `listChanged` **MUST** send a notification:
10237 | 
10238 | ```json
10239 | {
10240 |   "jsonrpc": "2.0",
10241 |   "method": "notifications/roots/list_changed"
10242 | }
10243 | ```
10244 | 
10245 | ## Message Flow
10246 | 
10247 | ```mermaid
10248 | sequenceDiagram
10249 |     participant Server
10250 |     participant Client
10251 | 
10252 |     Note over Server,Client: Discovery
10253 |     Server->>Client: roots/list
10254 |     Client-->>Server: Available roots
10255 | 
10256 |     Note over Server,Client: Changes
10257 |     Client--)Server: notifications/roots/list_changed
10258 |     Server->>Client: roots/list
10259 |     Client-->>Server: Updated roots
10260 | ```
10261 | 
10262 | ## Data Types
10263 | 
10264 | ### Root
10265 | 
10266 | A root definition includes:
10267 | 
10268 | * `uri`: Unique identifier for the root. This **MUST** be a `file://` URI in the current
10269 |   specification.
10270 | * `name`: Optional human-readable name for display purposes.
10271 | 
10272 | Example roots for different use cases:
10273 | 
10274 | #### Project Directory
10275 | 
10276 | ```json
10277 | {
10278 |   "uri": "file:///home/user/projects/myproject",
10279 |   "name": "My Project"
10280 | }
10281 | ```
10282 | 
10283 | #### Multiple Repositories
10284 | 
10285 | ```json
10286 | [
10287 |   {
10288 |     "uri": "file:///home/user/repos/frontend",
10289 |     "name": "Frontend Repository"
10290 |   },
10291 |   {
10292 |     "uri": "file:///home/user/repos/backend",
10293 |     "name": "Backend Repository"
10294 |   }
10295 | ]
10296 | ```
10297 | 
10298 | ## Error Handling
10299 | 
10300 | Clients **SHOULD** return standard JSON-RPC errors for common failure cases:
10301 | 
10302 | * Client does not support roots: `-32601` (Method not found)
10303 | * Internal errors: `-32603`
10304 | 
10305 | Example error:
10306 | 
10307 | ```json
10308 | {
10309 |   "jsonrpc": "2.0",
10310 |   "id": 1,
10311 |   "error": {
10312 |     "code": -32601,
10313 |     "message": "Roots not supported",
10314 |     "data": {
10315 |       "reason": "Client does not have roots capability"
10316 |     }
10317 |   }
10318 | }
10319 | ```
10320 | 
10321 | ## Security Considerations
10322 | 
10323 | 1. Clients **MUST**:
10324 | 
10325 |    * Only expose roots with appropriate permissions
10326 |    * Validate all root URIs to prevent path traversal
10327 |    * Implement proper access controls
10328 |    * Monitor root accessibility
10329 | 
10330 | 2. Servers **SHOULD**:
10331 |    * Handle cases where roots become unavailable
10332 |    * Respect root boundaries during operations
10333 |    * Validate all paths against provided roots
10334 | 
10335 | ## Implementation Guidelines
10336 | 
10337 | 1. Clients **SHOULD**:
10338 | 
10339 |    * Prompt users for consent before exposing roots to servers
10340 |    * Provide clear user interfaces for root management
10341 |    * Validate root accessibility before exposing
10342 |    * Monitor for root changes
10343 | 
10344 | 2. Servers **SHOULD**:
10345 |    * Check for roots capability before usage
10346 |    * Handle root list changes gracefully
10347 |    * Respect root boundaries in operations
10348 |    * Cache root information appropriately
10349 | 
10350 | 
10351 | # Sampling
10352 | Source: https://modelcontextprotocol.io/specification/2025-06-18/client/sampling
10353 | 
10354 | 
10355 | 
10356 | <div id="enable-section-numbers" />
10357 | 
10358 | <Info>**Protocol Revision**: 2025-06-18</Info>
10359 | 
10360 | The Model Context Protocol (MCP) provides a standardized way for servers to request LLM
10361 | sampling ("completions" or "generations") from language models via clients. This flow
10362 | allows clients to maintain control over model access, selection, and permissions while
10363 | enabling servers to leverage AI capabilities—with no server API keys necessary.
10364 | Servers can request text, audio, or image-based interactions and optionally include
10365 | context from MCP servers in their prompts.
10366 | 
10367 | ## User Interaction Model
10368 | 
10369 | Sampling in MCP allows servers to implement agentic behaviors, by enabling LLM calls to
10370 | occur *nested* inside other MCP server features.
10371 | 
10372 | Implementations are free to expose sampling through any interface pattern that suits
10373 | their needs—the protocol itself does not mandate any specific user interaction
10374 | model.
10375 | 
10376 | <Warning>
10377 |   For trust & safety and security, there **SHOULD** always
10378 |   be a human in the loop with the ability to deny sampling requests.
10379 | 
10380 |   Applications **SHOULD**:
10381 | 
10382 |   * Provide UI that makes it easy and intuitive to review sampling requests
10383 |   * Allow users to view and edit prompts before sending
10384 |   * Present generated responses for review before delivery
10385 | </Warning>
10386 | 
10387 | ## Capabilities
10388 | 
10389 | Clients that support sampling **MUST** declare the `sampling` capability during
10390 | [initialization](/specification/2025-06-18/basic/lifecycle#initialization):
10391 | 
10392 | ```json
10393 | {
10394 |   "capabilities": {
10395 |     "sampling": {}
10396 |   }
10397 | }
10398 | ```
10399 | 
10400 | ## Protocol Messages
10401 | 
10402 | ### Creating Messages
10403 | 
10404 | To request a language model generation, servers send a `sampling/createMessage` request:
10405 | 
10406 | **Request:**
10407 | 
10408 | ```json
10409 | {
10410 |   "jsonrpc": "2.0",
10411 |   "id": 1,
10412 |   "method": "sampling/createMessage",
10413 |   "params": {
10414 |     "messages": [
10415 |       {
10416 |         "role": "user",
10417 |         "content": {
10418 |           "type": "text",
10419 |           "text": "What is the capital of France?"
10420 |         }
10421 |       }
10422 |     ],
10423 |     "modelPreferences": {
10424 |       "hints": [
10425 |         {
10426 |           "name": "claude-3-sonnet"
10427 |         }
10428 |       ],
10429 |       "intelligencePriority": 0.8,
10430 |       "speedPriority": 0.5
10431 |     },
10432 |     "systemPrompt": "You are a helpful assistant.",
10433 |     "maxTokens": 100
10434 |   }
10435 | }
10436 | ```
10437 | 
10438 | **Response:**
10439 | 
10440 | ```json
10441 | {
10442 |   "jsonrpc": "2.0",
10443 |   "id": 1,
10444 |   "result": {
10445 |     "role": "assistant",
10446 |     "content": {
10447 |       "type": "text",
10448 |       "text": "The capital of France is Paris."
10449 |     },
10450 |     "model": "claude-3-sonnet-20240307",
10451 |     "stopReason": "endTurn"
10452 |   }
10453 | }
10454 | ```
10455 | 
10456 | ## Message Flow
10457 | 
10458 | ```mermaid
10459 | sequenceDiagram
10460 |     participant Server
10461 |     participant Client
10462 |     participant User
10463 |     participant LLM
10464 | 
10465 |     Note over Server,Client: Server initiates sampling
10466 |     Server->>Client: sampling/createMessage
10467 | 
10468 |     Note over Client,User: Human-in-the-loop review
10469 |     Client->>User: Present request for approval
10470 |     User-->>Client: Review and approve/modify
10471 | 
10472 |     Note over Client,LLM: Model interaction
10473 |     Client->>LLM: Forward approved request
10474 |     LLM-->>Client: Return generation
10475 | 
10476 |     Note over Client,User: Response review
10477 |     Client->>User: Present response for approval
10478 |     User-->>Client: Review and approve/modify
10479 | 
10480 |     Note over Server,Client: Complete request
10481 |     Client-->>Server: Return approved response
10482 | ```
10483 | 
10484 | ## Data Types
10485 | 
10486 | ### Messages
10487 | 
10488 | Sampling messages can contain:
10489 | 
10490 | #### Text Content
10491 | 
10492 | ```json
10493 | {
10494 |   "type": "text",
10495 |   "text": "The message content"
10496 | }
10497 | ```
10498 | 
10499 | #### Image Content
10500 | 
10501 | ```json
10502 | {
10503 |   "type": "image",
10504 |   "data": "base64-encoded-image-data",
10505 |   "mimeType": "image/jpeg"
10506 | }
10507 | ```
10508 | 
10509 | #### Audio Content
10510 | 
10511 | ```json
10512 | {
10513 |   "type": "audio",
10514 |   "data": "base64-encoded-audio-data",
10515 |   "mimeType": "audio/wav"
10516 | }
10517 | ```
10518 | 
10519 | ### Model Preferences
10520 | 
10521 | Model selection in MCP requires careful abstraction since servers and clients may use
10522 | different AI providers with distinct model offerings. A server cannot simply request a
10523 | specific model by name since the client may not have access to that exact model or may
10524 | prefer to use a different provider's equivalent model.
10525 | 
10526 | To solve this, MCP implements a preference system that combines abstract capability
10527 | priorities with optional model hints:
10528 | 
10529 | #### Capability Priorities
10530 | 
10531 | Servers express their needs through three normalized priority values (0-1):
10532 | 
10533 | * `costPriority`: How important is minimizing costs? Higher values prefer cheaper models.
10534 | * `speedPriority`: How important is low latency? Higher values prefer faster models.
10535 | * `intelligencePriority`: How important are advanced capabilities? Higher values prefer
10536 |   more capable models.
10537 | 
10538 | #### Model Hints
10539 | 
10540 | While priorities help select models based on characteristics, `hints` allow servers to
10541 | suggest specific models or model families:
10542 | 
10543 | * Hints are treated as substrings that can match model names flexibly
10544 | * Multiple hints are evaluated in order of preference
10545 | * Clients **MAY** map hints to equivalent models from different providers
10546 | * Hints are advisory—clients make final model selection
10547 | 
10548 | For example:
10549 | 
10550 | ```json
10551 | {
10552 |   "hints": [
10553 |     { "name": "claude-3-sonnet" }, // Prefer Sonnet-class models
10554 |     { "name": "claude" } // Fall back to any Claude model
10555 |   ],
10556 |   "costPriority": 0.3, // Cost is less important
10557 |   "speedPriority": 0.8, // Speed is very important
10558 |   "intelligencePriority": 0.5 // Moderate capability needs
10559 | }
10560 | ```
10561 | 
10562 | The client processes these preferences to select an appropriate model from its available
10563 | options. For instance, if the client doesn't have access to Claude models but has Gemini,
10564 | it might map the sonnet hint to `gemini-1.5-pro` based on similar capabilities.
10565 | 
10566 | ## Error Handling
10567 | 
10568 | Clients **SHOULD** return errors for common failure cases:
10569 | 
10570 | Example error:
10571 | 
10572 | ```json
10573 | {
10574 |   "jsonrpc": "2.0",
10575 |   "id": 1,
10576 |   "error": {
10577 |     "code": -1,
10578 |     "message": "User rejected sampling request"
10579 |   }
10580 | }
10581 | ```
10582 | 
10583 | ## Security Considerations
10584 | 
10585 | 1. Clients **SHOULD** implement user approval controls
10586 | 2. Both parties **SHOULD** validate message content
10587 | 3. Clients **SHOULD** respect model preference hints
10588 | 4. Clients **SHOULD** implement rate limiting
10589 | 5. Both parties **MUST** handle sensitive data appropriately
10590 | 
10591 | 
10592 | # Specification
10593 | Source: https://modelcontextprotocol.io/specification/2025-06-18/index
10594 | 
10595 | 
10596 | 
10597 | <div id="enable-section-numbers" />
10598 | 
10599 | [Model Context Protocol](https://modelcontextprotocol.io) (MCP) is an open protocol that
10600 | enables seamless integration between LLM applications and external data sources and
10601 | tools. Whether you're building an AI-powered IDE, enhancing a chat interface, or creating
10602 | custom AI workflows, MCP provides a standardized way to connect LLMs with the context
10603 | they need.
10604 | 
10605 | This specification defines the authoritative protocol requirements, based on the
10606 | TypeScript schema in
10607 | [schema.ts](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.ts).
10608 | 
10609 | For implementation guides and examples, visit
10610 | [modelcontextprotocol.io](https://modelcontextprotocol.io).
10611 | 
10612 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
10613 | NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
10614 | interpreted as described in [BCP 14](https://datatracker.ietf.org/doc/html/bcp14)
10615 | \[[RFC2119](https://datatracker.ietf.org/doc/html/rfc2119)]
10616 | \[[RFC8174](https://datatracker.ietf.org/doc/html/rfc8174)] when, and only when, they
10617 | appear in all capitals, as shown here.
10618 | 
10619 | ## Overview
10620 | 
10621 | MCP provides a standardized way for applications to:
10622 | 
10623 | * Share contextual information with language models
10624 | * Expose tools and capabilities to AI systems
10625 | * Build composable integrations and workflows
10626 | 
10627 | The protocol uses [JSON-RPC](https://www.jsonrpc.org/) 2.0 messages to establish
10628 | communication between:
10629 | 
10630 | * **Hosts**: LLM applications that initiate connections
10631 | * **Clients**: Connectors within the host application
10632 | * **Servers**: Services that provide context and capabilities
10633 | 
10634 | MCP takes some inspiration from the
10635 | [Language Server Protocol](https://microsoft.github.io/language-server-protocol/), which
10636 | standardizes how to add support for programming languages across a whole ecosystem of
10637 | development tools. In a similar way, MCP standardizes how to integrate additional context
10638 | and tools into the ecosystem of AI applications.
10639 | 
10640 | ## Key Details
10641 | 
10642 | ### Base Protocol
10643 | 
10644 | * [JSON-RPC](https://www.jsonrpc.org/) message format
10645 | * Stateful connections
10646 | * Server and client capability negotiation
10647 | 
10648 | ### Features
10649 | 
10650 | Servers offer any of the following features to clients:
10651 | 
10652 | * **Resources**: Context and data, for the user or the AI model to use
10653 | * **Prompts**: Templated messages and workflows for users
10654 | * **Tools**: Functions for the AI model to execute
10655 | 
10656 | Clients may offer the following features to servers:
10657 | 
10658 | * **Sampling**: Server-initiated agentic behaviors and recursive LLM interactions
10659 | * **Roots**: Server-initiated inquiries into uri or filesystem boundaries to operate in
10660 | * **Elicitation**: Server-initiated requests for additional information from users
10661 | 
10662 | ### Additional Utilities
10663 | 
10664 | * Configuration
10665 | * Progress tracking
10666 | * Cancellation
10667 | * Error reporting
10668 | * Logging
10669 | 
10670 | ## Security and Trust & Safety
10671 | 
10672 | The Model Context Protocol enables powerful capabilities through arbitrary data access
10673 | and code execution paths. With this power comes important security and trust
10674 | considerations that all implementors must carefully address.
10675 | 
10676 | ### Key Principles
10677 | 
10678 | 1. **User Consent and Control**
10679 | 
10680 |    * Users must explicitly consent to and understand all data access and operations
10681 |    * Users must retain control over what data is shared and what actions are taken
10682 |    * Implementors should provide clear UIs for reviewing and authorizing activities
10683 | 
10684 | 2. **Data Privacy**
10685 | 
10686 |    * Hosts must obtain explicit user consent before exposing user data to servers
10687 |    * Hosts must not transmit resource data elsewhere without user consent
10688 |    * User data should be protected with appropriate access controls
10689 | 
10690 | 3. **Tool Safety**
10691 | 
10692 |    * Tools represent arbitrary code execution and must be treated with appropriate
10693 |      caution.
10694 |      * In particular, descriptions of tool behavior such as annotations should be
10695 |        considered untrusted, unless obtained from a trusted server.
10696 |    * Hosts must obtain explicit user consent before invoking any tool
10697 |    * Users should understand what each tool does before authorizing its use
10698 | 
10699 | 4. **LLM Sampling Controls**
10700 |    * Users must explicitly approve any LLM sampling requests
10701 |    * Users should control:
10702 |      * Whether sampling occurs at all
10703 |      * The actual prompt that will be sent
10704 |      * What results the server can see
10705 |    * The protocol intentionally limits server visibility into prompts
10706 | 
10707 | ### Implementation Guidelines
10708 | 
10709 | While MCP itself cannot enforce these security principles at the protocol level,
10710 | implementors **SHOULD**:
10711 | 
10712 | 1. Build robust consent and authorization flows into their applications
10713 | 2. Provide clear documentation of security implications
10714 | 3. Implement appropriate access controls and data protections
10715 | 4. Follow security best practices in their integrations
10716 | 5. Consider privacy implications in their feature designs
10717 | 
10718 | ## Learn More
10719 | 
10720 | Explore the detailed specification for each protocol component:
10721 | 
10722 | <CardGroup cols={5}>
10723 |   <Card title="Architecture" icon="sitemap" href="/specification/2025-06-18/architecture" />
10724 | 
10725 |   <Card title="Base Protocol" icon="code" href="/specification/2025-06-18/basic" />
10726 | 
10727 |   <Card title="Server Features" icon="server" href="/specification/2025-06-18/server" />
10728 | 
10729 |   <Card title="Client Features" icon="user" href="/specification/2025-06-18/client" />
10730 | 
10731 |   <Card title="Contributing" icon="pencil" href="/development/contributing" />
10732 | </CardGroup>
10733 | 
10734 | 
10735 | # Overview
10736 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/index
10737 | 
10738 | 
10739 | 
10740 | <Info>**Protocol Revision**: 2025-06-18</Info>
10741 | 
10742 | Servers provide the fundamental building blocks for adding context to language models via
10743 | MCP. These primitives enable rich interactions between clients, servers, and language
10744 | models:
10745 | 
10746 | * **Prompts**: Pre-defined templates or instructions that guide language model
10747 |   interactions
10748 | * **Resources**: Structured data or content that provides additional context to the model
10749 | * **Tools**: Executable functions that allow models to perform actions or retrieve
10750 |   information
10751 | 
10752 | Each primitive can be summarized in the following control hierarchy:
10753 | 
10754 | | Primitive | Control                | Description                                        | Example                         |
10755 | | --------- | ---------------------- | -------------------------------------------------- | ------------------------------- |
10756 | | Prompts   | User-controlled        | Interactive templates invoked by user choice       | Slash commands, menu options    |
10757 | | Resources | Application-controlled | Contextual data attached and managed by the client | File contents, git history      |
10758 | | Tools     | Model-controlled       | Functions exposed to the LLM to take actions       | API POST requests, file writing |
10759 | 
10760 | Explore these key primitives in more detail below:
10761 | 
10762 | <CardGroup cols={3}>
10763 |   <Card title="Prompts" icon="message" href="/specification/2025-06-18/server/prompts" />
10764 | 
10765 |   <Card title="Resources" icon="file-lines" href="/specification/2025-06-18/server/resources" />
10766 | 
10767 |   <Card title="Tools" icon="wrench" href="/specification/2025-06-18/server/tools" />
10768 | </CardGroup>
10769 | 
10770 | 
10771 | # Prompts
10772 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/prompts
10773 | 
10774 | 
10775 | 
10776 | <div id="enable-section-numbers" />
10777 | 
10778 | <Info>**Protocol Revision**: 2025-06-18</Info>
10779 | 
10780 | The Model Context Protocol (MCP) provides a standardized way for servers to expose prompt
10781 | templates to clients. Prompts allow servers to provide structured messages and
10782 | instructions for interacting with language models. Clients can discover available
10783 | prompts, retrieve their contents, and provide arguments to customize them.
10784 | 
10785 | ## User Interaction Model
10786 | 
10787 | Prompts are designed to be **user-controlled**, meaning they are exposed from servers to
10788 | clients with the intention of the user being able to explicitly select them for use.
10789 | 
10790 | Typically, prompts would be triggered through user-initiated commands in the user
10791 | interface, which allows users to naturally discover and invoke available prompts.
10792 | 
10793 | For example, as slash commands:
10794 | 
10795 | ![Example of prompt exposed as slash command](https://mintlify.s3.us-west-1.amazonaws.com/mcp/specification/2025-06-18/server/slash-command.png)
10796 | 
10797 | However, implementors are free to expose prompts through any interface pattern that suits
10798 | their needs—the protocol itself does not mandate any specific user interaction
10799 | model.
10800 | 
10801 | ## Capabilities
10802 | 
10803 | Servers that support prompts **MUST** declare the `prompts` capability during
10804 | [initialization](/specification/2025-06-18/basic/lifecycle#initialization):
10805 | 
10806 | ```json
10807 | {
10808 |   "capabilities": {
10809 |     "prompts": {
10810 |       "listChanged": true
10811 |     }
10812 |   }
10813 | }
10814 | ```
10815 | 
10816 | `listChanged` indicates whether the server will emit notifications when the list of
10817 | available prompts changes.
10818 | 
10819 | ## Protocol Messages
10820 | 
10821 | ### Listing Prompts
10822 | 
10823 | To retrieve available prompts, clients send a `prompts/list` request. This operation
10824 | supports [pagination](/specification/2025-06-18/server/utilities/pagination).
10825 | 
10826 | **Request:**
10827 | 
10828 | ```json
10829 | {
10830 |   "jsonrpc": "2.0",
10831 |   "id": 1,
10832 |   "method": "prompts/list",
10833 |   "params": {
10834 |     "cursor": "optional-cursor-value"
10835 |   }
10836 | }
10837 | ```
10838 | 
10839 | **Response:**
10840 | 
10841 | ```json
10842 | {
10843 |   "jsonrpc": "2.0",
10844 |   "id": 1,
10845 |   "result": {
10846 |     "prompts": [
10847 |       {
10848 |         "name": "code_review",
10849 |         "title": "Request Code Review",
10850 |         "description": "Asks the LLM to analyze code quality and suggest improvements",
10851 |         "arguments": [
10852 |           {
10853 |             "name": "code",
10854 |             "description": "The code to review",
10855 |             "required": true
10856 |           }
10857 |         ]
10858 |       }
10859 |     ],
10860 |     "nextCursor": "next-page-cursor"
10861 |   }
10862 | }
10863 | ```
10864 | 
10865 | ### Getting a Prompt
10866 | 
10867 | To retrieve a specific prompt, clients send a `prompts/get` request. Arguments may be
10868 | auto-completed through [the completion API](/specification/2025-06-18/server/utilities/completion).
10869 | 
10870 | **Request:**
10871 | 
10872 | ```json
10873 | {
10874 |   "jsonrpc": "2.0",
10875 |   "id": 2,
10876 |   "method": "prompts/get",
10877 |   "params": {
10878 |     "name": "code_review",
10879 |     "arguments": {
10880 |       "code": "def hello():\n    print('world')"
10881 |     }
10882 |   }
10883 | }
10884 | ```
10885 | 
10886 | **Response:**
10887 | 
10888 | ```json
10889 | {
10890 |   "jsonrpc": "2.0",
10891 |   "id": 2,
10892 |   "result": {
10893 |     "description": "Code review prompt",
10894 |     "messages": [
10895 |       {
10896 |         "role": "user",
10897 |         "content": {
10898 |           "type": "text",
10899 |           "text": "Please review this Python code:\ndef hello():\n    print('world')"
10900 |         }
10901 |       }
10902 |     ]
10903 |   }
10904 | }
10905 | ```
10906 | 
10907 | ### List Changed Notification
10908 | 
10909 | When the list of available prompts changes, servers that declared the `listChanged`
10910 | capability **SHOULD** send a notification:
10911 | 
10912 | ```json
10913 | {
10914 |   "jsonrpc": "2.0",
10915 |   "method": "notifications/prompts/list_changed"
10916 | }
10917 | ```
10918 | 
10919 | ## Message Flow
10920 | 
10921 | ```mermaid
10922 | sequenceDiagram
10923 |     participant Client
10924 |     participant Server
10925 | 
10926 |     Note over Client,Server: Discovery
10927 |     Client->>Server: prompts/list
10928 |     Server-->>Client: List of prompts
10929 | 
10930 |     Note over Client,Server: Usage
10931 |     Client->>Server: prompts/get
10932 |     Server-->>Client: Prompt content
10933 | 
10934 |     opt listChanged
10935 |       Note over Client,Server: Changes
10936 |       Server--)Client: prompts/list_changed
10937 |       Client->>Server: prompts/list
10938 |       Server-->>Client: Updated prompts
10939 |     end
10940 | ```
10941 | 
10942 | ## Data Types
10943 | 
10944 | ### Prompt
10945 | 
10946 | A prompt definition includes:
10947 | 
10948 | * `name`: Unique identifier for the prompt
10949 | * `title`: Optional human-readable name of the prompt for display purposes.
10950 | * `description`: Optional human-readable description
10951 | * `arguments`: Optional list of arguments for customization
10952 | 
10953 | ### PromptMessage
10954 | 
10955 | Messages in a prompt can contain:
10956 | 
10957 | * `role`: Either "user" or "assistant" to indicate the speaker
10958 | * `content`: One of the following content types:
10959 | 
10960 | #### Text Content
10961 | 
10962 | Text content represents plain text messages:
10963 | 
10964 | ```json
10965 | {
10966 |   "type": "text",
10967 |   "text": "The text content of the message"
10968 | }
10969 | ```
10970 | 
10971 | This is the most common content type used for natural language interactions.
10972 | 
10973 | #### Image Content
10974 | 
10975 | Image content allows including visual information in messages:
10976 | 
10977 | ```json
10978 | {
10979 |   "type": "image",
10980 |   "data": "base64-encoded-image-data",
10981 |   "mimeType": "image/png"
10982 | }
10983 | ```
10984 | 
10985 | The image data **MUST** be base64-encoded and include a valid MIME type. This enables
10986 | multi-modal interactions where visual context is important.
10987 | 
10988 | #### Audio Content
10989 | 
10990 | Audio content allows including audio information in messages:
10991 | 
10992 | ```json
10993 | {
10994 |   "type": "audio",
10995 |   "data": "base64-encoded-audio-data",
10996 |   "mimeType": "audio/wav"
10997 | }
10998 | ```
10999 | 
11000 | The audio data MUST be base64-encoded and include a valid MIME type. This enables
11001 | multi-modal interactions where audio context is important.
11002 | 
11003 | #### Embedded Resources
11004 | 
11005 | Embedded resources allow referencing server-side resources directly in messages:
11006 | 
11007 | ```json
11008 | {
11009 |   "type": "resource",
11010 |   "resource": {
11011 |     "uri": "resource://example",
11012 |     "name": "example",
11013 |     "title": "My Example Resource",
11014 |     "mimeType": "text/plain",
11015 |     "text": "Resource content"
11016 |   }
11017 | }
11018 | ```
11019 | 
11020 | Resources can contain either text or binary (blob) data and **MUST** include:
11021 | 
11022 | * A valid resource URI
11023 | * The appropriate MIME type
11024 | * Either text content or base64-encoded blob data
11025 | 
11026 | Embedded resources enable prompts to seamlessly incorporate server-managed content like
11027 | documentation, code samples, or other reference materials directly into the conversation
11028 | flow.
11029 | 
11030 | ## Error Handling
11031 | 
11032 | Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
11033 | 
11034 | * Invalid prompt name: `-32602` (Invalid params)
11035 | * Missing required arguments: `-32602` (Invalid params)
11036 | * Internal errors: `-32603` (Internal error)
11037 | 
11038 | ## Implementation Considerations
11039 | 
11040 | 1. Servers **SHOULD** validate prompt arguments before processing
11041 | 2. Clients **SHOULD** handle pagination for large prompt lists
11042 | 3. Both parties **SHOULD** respect capability negotiation
11043 | 
11044 | ## Security
11045 | 
11046 | Implementations **MUST** carefully validate all prompt inputs and outputs to prevent
11047 | injection attacks or unauthorized access to resources.
11048 | 
11049 | 
11050 | # Resources
11051 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/resources
11052 | 
11053 | 
11054 | 
11055 | <div id="enable-section-numbers" />
11056 | 
11057 | <Info>**Protocol Revision**: 2025-06-18</Info>
11058 | 
11059 | The Model Context Protocol (MCP) provides a standardized way for servers to expose
11060 | resources to clients. Resources allow servers to share data that provides context to
11061 | language models, such as files, database schemas, or application-specific information.
11062 | Each resource is uniquely identified by a
11063 | [URI](https://datatracker.ietf.org/doc/html/rfc3986).
11064 | 
11065 | ## User Interaction Model
11066 | 
11067 | Resources in MCP are designed to be **application-driven**, with host applications
11068 | determining how to incorporate context based on their needs.
11069 | 
11070 | For example, applications could:
11071 | 
11072 | * Expose resources through UI elements for explicit selection, in a tree or list view
11073 | * Allow the user to search through and filter available resources
11074 | * Implement automatic context inclusion, based on heuristics or the AI model's selection
11075 | 
11076 | ![Example of resource context picker](https://mintlify.s3.us-west-1.amazonaws.com/mcp/specification/2025-06-18/server/resource-picker.png)
11077 | 
11078 | However, implementations are free to expose resources through any interface pattern that
11079 | suits their needs—the protocol itself does not mandate any specific user
11080 | interaction model.
11081 | 
11082 | ## Capabilities
11083 | 
11084 | Servers that support resources **MUST** declare the `resources` capability:
11085 | 
11086 | ```json
11087 | {
11088 |   "capabilities": {
11089 |     "resources": {
11090 |       "subscribe": true,
11091 |       "listChanged": true
11092 |     }
11093 |   }
11094 | }
11095 | ```
11096 | 
11097 | The capability supports two optional features:
11098 | 
11099 | * `subscribe`: whether the client can subscribe to be notified of changes to individual
11100 |   resources.
11101 | * `listChanged`: whether the server will emit notifications when the list of available
11102 |   resources changes.
11103 | 
11104 | Both `subscribe` and `listChanged` are optional—servers can support neither,
11105 | either, or both:
11106 | 
11107 | ```json
11108 | {
11109 |   "capabilities": {
11110 |     "resources": {} // Neither feature supported
11111 |   }
11112 | }
11113 | ```
11114 | 
11115 | ```json
11116 | {
11117 |   "capabilities": {
11118 |     "resources": {
11119 |       "subscribe": true // Only subscriptions supported
11120 |     }
11121 |   }
11122 | }
11123 | ```
11124 | 
11125 | ```json
11126 | {
11127 |   "capabilities": {
11128 |     "resources": {
11129 |       "listChanged": true // Only list change notifications supported
11130 |     }
11131 |   }
11132 | }
11133 | ```
11134 | 
11135 | ## Protocol Messages
11136 | 
11137 | ### Listing Resources
11138 | 
11139 | To discover available resources, clients send a `resources/list` request. This operation
11140 | supports [pagination](/specification/2025-06-18/server/utilities/pagination).
11141 | 
11142 | **Request:**
11143 | 
11144 | ```json
11145 | {
11146 |   "jsonrpc": "2.0",
11147 |   "id": 1,
11148 |   "method": "resources/list",
11149 |   "params": {
11150 |     "cursor": "optional-cursor-value"
11151 |   }
11152 | }
11153 | ```
11154 | 
11155 | **Response:**
11156 | 
11157 | ```json
11158 | {
11159 |   "jsonrpc": "2.0",
11160 |   "id": 1,
11161 |   "result": {
11162 |     "resources": [
11163 |       {
11164 |         "uri": "file:///project/src/main.rs",
11165 |         "name": "main.rs",
11166 |         "title": "Rust Software Application Main File",
11167 |         "description": "Primary application entry point",
11168 |         "mimeType": "text/x-rust"
11169 |       }
11170 |     ],
11171 |     "nextCursor": "next-page-cursor"
11172 |   }
11173 | }
11174 | ```
11175 | 
11176 | ### Reading Resources
11177 | 
11178 | To retrieve resource contents, clients send a `resources/read` request:
11179 | 
11180 | **Request:**
11181 | 
11182 | ```json
11183 | {
11184 |   "jsonrpc": "2.0",
11185 |   "id": 2,
11186 |   "method": "resources/read",
11187 |   "params": {
11188 |     "uri": "file:///project/src/main.rs"
11189 |   }
11190 | }
11191 | ```
11192 | 
11193 | **Response:**
11194 | 
11195 | ```json
11196 | {
11197 |   "jsonrpc": "2.0",
11198 |   "id": 2,
11199 |   "result": {
11200 |     "contents": [
11201 |       {
11202 |         "uri": "file:///project/src/main.rs",
11203 |         "name": "main.rs",
11204 |         "title": "Rust Software Application Main File",
11205 |         "mimeType": "text/x-rust",
11206 |         "text": "fn main() {\n    println!(\"Hello world!\");\n}"
11207 |       }
11208 |     ]
11209 |   }
11210 | }
11211 | ```
11212 | 
11213 | ### Resource Templates
11214 | 
11215 | Resource templates allow servers to expose parameterized resources using
11216 | [URI templates](https://datatracker.ietf.org/doc/html/rfc6570). Arguments may be
11217 | auto-completed through [the completion API](/specification/2025-06-18/server/utilities/completion).
11218 | 
11219 | **Request:**
11220 | 
11221 | ```json
11222 | {
11223 |   "jsonrpc": "2.0",
11224 |   "id": 3,
11225 |   "method": "resources/templates/list"
11226 | }
11227 | ```
11228 | 
11229 | **Response:**
11230 | 
11231 | ```json
11232 | {
11233 |   "jsonrpc": "2.0",
11234 |   "id": 3,
11235 |   "result": {
11236 |     "resourceTemplates": [
11237 |       {
11238 |         "uriTemplate": "file:///{path}",
11239 |         "name": "Project Files",
11240 |         "title": "📁 Project Files",
11241 |         "description": "Access files in the project directory",
11242 |         "mimeType": "application/octet-stream"
11243 |       }
11244 |     ]
11245 |   }
11246 | }
11247 | ```
11248 | 
11249 | ### List Changed Notification
11250 | 
11251 | When the list of available resources changes, servers that declared the `listChanged`
11252 | capability **SHOULD** send a notification:
11253 | 
11254 | ```json
11255 | {
11256 |   "jsonrpc": "2.0",
11257 |   "method": "notifications/resources/list_changed"
11258 | }
11259 | ```
11260 | 
11261 | ### Subscriptions
11262 | 
11263 | The protocol supports optional subscriptions to resource changes. Clients can subscribe
11264 | to specific resources and receive notifications when they change:
11265 | 
11266 | **Subscribe Request:**
11267 | 
11268 | ```json
11269 | {
11270 |   "jsonrpc": "2.0",
11271 |   "id": 4,
11272 |   "method": "resources/subscribe",
11273 |   "params": {
11274 |     "uri": "file:///project/src/main.rs"
11275 |   }
11276 | }
11277 | ```
11278 | 
11279 | **Update Notification:**
11280 | 
11281 | ```json
11282 | {
11283 |   "jsonrpc": "2.0",
11284 |   "method": "notifications/resources/updated",
11285 |   "params": {
11286 |     "uri": "file:///project/src/main.rs",
11287 |     "title": "Rust Software Application Main File"
11288 |   }
11289 | }
11290 | ```
11291 | 
11292 | ## Message Flow
11293 | 
11294 | ```mermaid
11295 | sequenceDiagram
11296 |     participant Client
11297 |     participant Server
11298 | 
11299 |     Note over Client,Server: Resource Discovery
11300 |     Client->>Server: resources/list
11301 |     Server-->>Client: List of resources
11302 | 
11303 |     Note over Client,Server: Resource Access
11304 |     Client->>Server: resources/read
11305 |     Server-->>Client: Resource contents
11306 | 
11307 |     Note over Client,Server: Subscriptions
11308 |     Client->>Server: resources/subscribe
11309 |     Server-->>Client: Subscription confirmed
11310 | 
11311 |     Note over Client,Server: Updates
11312 |     Server--)Client: notifications/resources/updated
11313 |     Client->>Server: resources/read
11314 |     Server-->>Client: Updated contents
11315 | ```
11316 | 
11317 | ## Data Types
11318 | 
11319 | ### Resource
11320 | 
11321 | A resource definition includes:
11322 | 
11323 | * `uri`: Unique identifier for the resource
11324 | * `name`: The name of the resource.
11325 | * `title`: Optional human-readable name of the resource for display purposes.
11326 | * `description`: Optional description
11327 | * `mimeType`: Optional MIME type
11328 | * `size`: Optional size in bytes
11329 | 
11330 | ### Resource Contents
11331 | 
11332 | Resources can contain either text or binary data:
11333 | 
11334 | #### Text Content
11335 | 
11336 | ```json
11337 | {
11338 |   "uri": "file:///example.txt",
11339 |   "name": "example.txt",
11340 |   "title": "Example Text File",
11341 |   "mimeType": "text/plain",
11342 |   "text": "Resource content"
11343 | }
11344 | ```
11345 | 
11346 | #### Binary Content
11347 | 
11348 | ```json
11349 | {
11350 |   "uri": "file:///example.png",
11351 |   "name": "example.png",
11352 |   "title": "Example Image",
11353 |   "mimeType": "image/png",
11354 |   "blob": "base64-encoded-data"
11355 | }
11356 | ```
11357 | 
11358 | ## Common URI Schemes
11359 | 
11360 | The protocol defines several standard URI schemes. This list not
11361 | exhaustive—implementations are always free to use additional, custom URI schemes.
11362 | 
11363 | ### https\://
11364 | 
11365 | Used to represent a resource available on the web.
11366 | 
11367 | Servers **SHOULD** use this scheme only when the client is able to fetch and load the
11368 | resource directly from the web on its own—that is, it doesn’t need to read the resource
11369 | via the MCP server.
11370 | 
11371 | For other use cases, servers **SHOULD** prefer to use another URI scheme, or define a
11372 | custom one, even if the server will itself be downloading resource contents over the
11373 | internet.
11374 | 
11375 | ### file://
11376 | 
11377 | Used to identify resources that behave like a filesystem. However, the resources do not
11378 | need to map to an actual physical filesystem.
11379 | 
11380 | MCP servers **MAY** identify file:// resources with an
11381 | [XDG MIME type](https://specifications.freedesktop.org/shared-mime-info-spec/0.14/ar01s02.html#id-1.3.14),
11382 | like `inode/directory`, to represent non-regular files (such as directories) that don’t
11383 | otherwise have a standard MIME type.
11384 | 
11385 | ### git://
11386 | 
11387 | Git version control integration.
11388 | 
11389 | ### Custom URI Schemes
11390 | 
11391 | Custom URI schemes **MUST** be in accordance with [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986),
11392 | taking the above guidance in to account.
11393 | 
11394 | ## Error Handling
11395 | 
11396 | Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
11397 | 
11398 | * Resource not found: `-32002`
11399 | * Internal errors: `-32603`
11400 | 
11401 | Example error:
11402 | 
11403 | ```json
11404 | {
11405 |   "jsonrpc": "2.0",
11406 |   "id": 5,
11407 |   "error": {
11408 |     "code": -32002,
11409 |     "message": "Resource not found",
11410 |     "data": {
11411 |       "uri": "file:///nonexistent.txt"
11412 |     }
11413 |   }
11414 | }
11415 | ```
11416 | 
11417 | ## Security Considerations
11418 | 
11419 | 1. Servers **MUST** validate all resource URIs
11420 | 2. Access controls **SHOULD** be implemented for sensitive resources
11421 | 3. Binary data **MUST** be properly encoded
11422 | 4. Resource permissions **SHOULD** be checked before operations
11423 | 
11424 | 
11425 | # Tools
11426 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/tools
11427 | 
11428 | 
11429 | 
11430 | <div id="enable-section-numbers" />
11431 | 
11432 | <Info>**Protocol Revision**: 2025-06-18</Info>
11433 | 
11434 | The Model Context Protocol (MCP) allows servers to expose tools that can be invoked by
11435 | language models. Tools enable models to interact with external systems, such as querying
11436 | databases, calling APIs, or performing computations. Each tool is uniquely identified by
11437 | a name and includes metadata describing its schema.
11438 | 
11439 | ## User Interaction Model
11440 | 
11441 | Tools in MCP are designed to be **model-controlled**, meaning that the language model can
11442 | discover and invoke tools automatically based on its contextual understanding and the
11443 | user's prompts.
11444 | 
11445 | However, implementations are free to expose tools through any interface pattern that
11446 | suits their needs—the protocol itself does not mandate any specific user
11447 | interaction model.
11448 | 
11449 | <Warning>
11450 |   For trust & safety and security, there **SHOULD** always
11451 |   be a human in the loop with the ability to deny tool invocations.
11452 | 
11453 |   Applications **SHOULD**:
11454 | 
11455 |   * Provide UI that makes clear which tools are being exposed to the AI model
11456 |   * Insert clear visual indicators when tools are invoked
11457 |   * Present confirmation prompts to the user for operations, to ensure a human is in the
11458 |     loop
11459 | </Warning>
11460 | 
11461 | ## Capabilities
11462 | 
11463 | Servers that support tools **MUST** declare the `tools` capability:
11464 | 
11465 | ```json
11466 | {
11467 |   "capabilities": {
11468 |     "tools": {
11469 |       "listChanged": true
11470 |     }
11471 |   }
11472 | }
11473 | ```
11474 | 
11475 | `listChanged` indicates whether the server will emit notifications when the list of
11476 | available tools changes.
11477 | 
11478 | ## Protocol Messages
11479 | 
11480 | ### Listing Tools
11481 | 
11482 | To discover available tools, clients send a `tools/list` request. This operation supports
11483 | [pagination](/specification/2025-06-18/server/utilities/pagination).
11484 | 
11485 | **Request:**
11486 | 
11487 | ```json
11488 | {
11489 |   "jsonrpc": "2.0",
11490 |   "id": 1,
11491 |   "method": "tools/list",
11492 |   "params": {
11493 |     "cursor": "optional-cursor-value"
11494 |   }
11495 | }
11496 | ```
11497 | 
11498 | **Response:**
11499 | 
11500 | ```json
11501 | {
11502 |   "jsonrpc": "2.0",
11503 |   "id": 1,
11504 |   "result": {
11505 |     "tools": [
11506 |       {
11507 |         "name": "get_weather",
11508 |         "title": "Weather Information Provider",
11509 |         "description": "Get current weather information for a location",
11510 |         "inputSchema": {
11511 |           "type": "object",
11512 |           "properties": {
11513 |             "location": {
11514 |               "type": "string",
11515 |               "description": "City name or zip code"
11516 |             }
11517 |           },
11518 |           "required": ["location"]
11519 |         }
11520 |       }
11521 |     ],
11522 |     "nextCursor": "next-page-cursor"
11523 |   }
11524 | }
11525 | ```
11526 | 
11527 | ### Calling Tools
11528 | 
11529 | To invoke a tool, clients send a `tools/call` request:
11530 | 
11531 | **Request:**
11532 | 
11533 | ```json
11534 | {
11535 |   "jsonrpc": "2.0",
11536 |   "id": 2,
11537 |   "method": "tools/call",
11538 |   "params": {
11539 |     "name": "get_weather",
11540 |     "arguments": {
11541 |       "location": "New York"
11542 |     }
11543 |   }
11544 | }
11545 | ```
11546 | 
11547 | **Response:**
11548 | 
11549 | ```json
11550 | {
11551 |   "jsonrpc": "2.0",
11552 |   "id": 2,
11553 |   "result": {
11554 |     "content": [
11555 |       {
11556 |         "type": "text",
11557 |         "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
11558 |       }
11559 |     ],
11560 |     "isError": false
11561 |   }
11562 | }
11563 | ```
11564 | 
11565 | ### List Changed Notification
11566 | 
11567 | When the list of available tools changes, servers that declared the `listChanged`
11568 | capability **SHOULD** send a notification:
11569 | 
11570 | ```json
11571 | {
11572 |   "jsonrpc": "2.0",
11573 |   "method": "notifications/tools/list_changed"
11574 | }
11575 | ```
11576 | 
11577 | ## Message Flow
11578 | 
11579 | ```mermaid
11580 | sequenceDiagram
11581 |     participant LLM
11582 |     participant Client
11583 |     participant Server
11584 | 
11585 |     Note over Client,Server: Discovery
11586 |     Client->>Server: tools/list
11587 |     Server-->>Client: List of tools
11588 | 
11589 |     Note over Client,LLM: Tool Selection
11590 |     LLM->>Client: Select tool to use
11591 | 
11592 |     Note over Client,Server: Invocation
11593 |     Client->>Server: tools/call
11594 |     Server-->>Client: Tool result
11595 |     Client->>LLM: Process result
11596 | 
11597 |     Note over Client,Server: Updates
11598 |     Server--)Client: tools/list_changed
11599 |     Client->>Server: tools/list
11600 |     Server-->>Client: Updated tools
11601 | ```
11602 | 
11603 | ## Data Types
11604 | 
11605 | ### Tool
11606 | 
11607 | A tool definition includes:
11608 | 
11609 | * `name`: Unique identifier for the tool
11610 | * `title`: Optional human-readable name of the tool for display purposes.
11611 | * `description`: Human-readable description of functionality
11612 | * `inputSchema`: JSON Schema defining expected parameters
11613 | * `outputSchema`: Optional JSON Schema defining expected output structure
11614 | * `annotations`: optional properties describing tool behavior
11615 | 
11616 | <Warning>
11617 |   For trust & safety and security, clients **MUST** consider
11618 |   tool annotations to be untrusted unless they come from trusted servers.
11619 | </Warning>
11620 | 
11621 | ### Tool Result
11622 | 
11623 | Tool results may contain [**structured**](#structured-content) or **unstructured** content.
11624 | 
11625 | **Unstructured** content is returned in the `content` field of a result, and can contain multiple content items of different types:
11626 | 
11627 | #### Text Content
11628 | 
11629 | ```json
11630 | {
11631 |   "type": "text",
11632 |   "text": "Tool result text"
11633 | }
11634 | ```
11635 | 
11636 | #### Image Content
11637 | 
11638 | ```json
11639 | {
11640 |   "type": "image",
11641 |   "data": "base64-encoded-data",
11642 |   "mimeType": "image/png"
11643 | }
11644 | ```
11645 | 
11646 | #### Audio Content
11647 | 
11648 | ```json
11649 | {
11650 |   "type": "audio",
11651 |   "data": "base64-encoded-audio-data",
11652 |   "mimeType": "audio/wav"
11653 | }
11654 | ```
11655 | 
11656 | #### Resource Links
11657 | 
11658 | A tool **MAY** return links to [Resources](/specification/2025-06-18/server/resources), to provide additional context
11659 | or data. In this case, the tool will return a URI that can be subscribed to or fetched by the client:
11660 | 
11661 | ```json
11662 | {
11663 |   "type": "resource_link",
11664 |   "uri": "file:///project/src/main.rs",
11665 |   "name": "main.rs",
11666 |   "description": "Primary application entry point",
11667 |   "mimeType": "text/x-rust"
11668 | }
11669 | ```
11670 | 
11671 | <Info>
11672 |   Resource links returned by tools are not guaranteed to appear in the results
11673 |   of a `resources/list` request.
11674 | </Info>
11675 | 
11676 | #### Embedded Resources
11677 | 
11678 | [Resources](/specification/2025-06-18/server/resources) **MAY** be embedded to provide additional context
11679 | or data using a suitable [URI scheme](./resources#common-uri-schemes). Servers that use embedded resources **SHOULD** implement the `resources` capability:
11680 | 
11681 | ```json
11682 | {
11683 |   "type": "resource",
11684 |   "resource": {
11685 |     "uri": "file:///project/src/main.rs",
11686 |     "title": "Project Rust Main File",
11687 |     "mimeType": "text/x-rust",
11688 |     "text": "fn main() {\n    println!(\"Hello world!\");\n}"
11689 |   }
11690 | }
11691 | ```
11692 | 
11693 | #### Structured Content
11694 | 
11695 | **Structured** content is returned as a JSON object in the `structuredContent` field of a result.
11696 | 
11697 | For backwards compatibility, a tool that returns structured content SHOULD also return functionally equivalent unstructured content.
11698 | (For example, serialized JSON can be returned in a `TextContent` block.)
11699 | 
11700 | #### Output Schema
11701 | 
11702 | Tools may also provide an output schema for validation of structured results.
11703 | If an output schema is provided:
11704 | 
11705 | * Servers **MUST** provide structured results that conform to this schema.
11706 | * Clients **SHOULD** validate structured results against this schema.
11707 | 
11708 | Example tool with output schema:
11709 | 
11710 | ```json
11711 | {
11712 |   "name": "get_weather_data",
11713 |   "title": "Weather Data Retriever",
11714 |   "description": "Get current weather data for a location",
11715 |   "inputSchema": {
11716 |     "type": "object",
11717 |     "properties": {
11718 |       "location": {
11719 |         "type": "string",
11720 |         "description": "City name or zip code"
11721 |       }
11722 |     },
11723 |     "required": ["location"]
11724 |   },
11725 |   "outputSchema": {
11726 |     "type": "object",
11727 |     "properties": {
11728 |       "temperature": {
11729 |         "type": "number",
11730 |         "description": "Temperature in celsius"
11731 |       },
11732 |       "conditions": {
11733 |         "type": "string",
11734 |         "description": "Weather conditions description"
11735 |       },
11736 |       "humidity": {
11737 |         "type": "number",
11738 |         "description": "Humidity percentage"
11739 |       }
11740 |     },
11741 |     "required": ["temperature", "conditions", "humidity"]
11742 |   }
11743 | }
11744 | ```
11745 | 
11746 | Example valid response for this tool:
11747 | 
11748 | ```json
11749 | {
11750 |   "jsonrpc": "2.0",
11751 |   "id": 5,
11752 |   "result": {
11753 |     "content": [
11754 |       {
11755 |         "type": "text",
11756 |         "text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\", \"humidity\": 65}"
11757 |       }
11758 |     ],
11759 |     "structuredContent": {
11760 |       "temperature": 22.5,
11761 |       "conditions": "Partly cloudy",
11762 |       "humidity": 65
11763 |     }
11764 |   }
11765 | }
11766 | ```
11767 | 
11768 | Providing an output schema helps clients and LLMs understand and properly handle structured tool outputs by:
11769 | 
11770 | * Enabling strict schema validation of responses
11771 | * Providing type information for better integration with programming languages
11772 | * Guiding clients and LLMs to properly parse and utilize the returned data
11773 | * Supporting better documentation and developer experience
11774 | 
11775 | ## Error Handling
11776 | 
11777 | Tools use two error reporting mechanisms:
11778 | 
11779 | 1. **Protocol Errors**: Standard JSON-RPC errors for issues like:
11780 | 
11781 |    * Unknown tools
11782 |    * Invalid arguments
11783 |    * Server errors
11784 | 
11785 | 2. **Tool Execution Errors**: Reported in tool results with `isError: true`:
11786 |    * API failures
11787 |    * Invalid input data
11788 |    * Business logic errors
11789 | 
11790 | Example protocol error:
11791 | 
11792 | ```json
11793 | {
11794 |   "jsonrpc": "2.0",
11795 |   "id": 3,
11796 |   "error": {
11797 |     "code": -32602,
11798 |     "message": "Unknown tool: invalid_tool_name"
11799 |   }
11800 | }
11801 | ```
11802 | 
11803 | Example tool execution error:
11804 | 
11805 | ```json
11806 | {
11807 |   "jsonrpc": "2.0",
11808 |   "id": 4,
11809 |   "result": {
11810 |     "content": [
11811 |       {
11812 |         "type": "text",
11813 |         "text": "Failed to fetch weather data: API rate limit exceeded"
11814 |       }
11815 |     ],
11816 |     "isError": true
11817 |   }
11818 | }
11819 | ```
11820 | 
11821 | ## Security Considerations
11822 | 
11823 | 1. Servers **MUST**:
11824 | 
11825 |    * Validate all tool inputs
11826 |    * Implement proper access controls
11827 |    * Rate limit tool invocations
11828 |    * Sanitize tool outputs
11829 | 
11830 | 2. Clients **SHOULD**:
11831 |    * Prompt for user confirmation on sensitive operations
11832 |    * Show tool inputs to the user before calling the server, to avoid malicious or
11833 |      accidental data exfiltration
11834 |    * Validate tool results before passing to LLM
11835 |    * Implement timeouts for tool calls
11836 |    * Log tool usage for audit purposes
11837 | 
11838 | 
11839 | # Completion
11840 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/completion
11841 | 
11842 | 
11843 | 
11844 | <div id="enable-section-numbers" />
11845 | 
11846 | <Info>**Protocol Revision**: 2025-06-18</Info>
11847 | 
11848 | The Model Context Protocol (MCP) provides a standardized way for servers to offer
11849 | argument autocompletion suggestions for prompts and resource URIs. This enables rich,
11850 | IDE-like experiences where users receive contextual suggestions while entering argument
11851 | values.
11852 | 
11853 | ## User Interaction Model
11854 | 
11855 | Completion in MCP is designed to support interactive user experiences similar to IDE code
11856 | completion.
11857 | 
11858 | For example, applications may show completion suggestions in a dropdown or popup menu as
11859 | users type, with the ability to filter and select from available options.
11860 | 
11861 | However, implementations are free to expose completion through any interface pattern that
11862 | suits their needs—the protocol itself does not mandate any specific user
11863 | interaction model.
11864 | 
11865 | ## Capabilities
11866 | 
11867 | Servers that support completions **MUST** declare the `completions` capability:
11868 | 
11869 | ```json
11870 | {
11871 |   "capabilities": {
11872 |     "completions": {}
11873 |   }
11874 | }
11875 | ```
11876 | 
11877 | ## Protocol Messages
11878 | 
11879 | ### Requesting Completions
11880 | 
11881 | To get completion suggestions, clients send a `completion/complete` request specifying
11882 | what is being completed through a reference type:
11883 | 
11884 | **Request:**
11885 | 
11886 | ```json
11887 | {
11888 |   "jsonrpc": "2.0",
11889 |   "id": 1,
11890 |   "method": "completion/complete",
11891 |   "params": {
11892 |     "ref": {
11893 |       "type": "ref/prompt",
11894 |       "name": "code_review"
11895 |     },
11896 |     "argument": {
11897 |       "name": "language",
11898 |       "value": "py"
11899 |     }
11900 |   }
11901 | }
11902 | ```
11903 | 
11904 | **Response:**
11905 | 
11906 | ```json
11907 | {
11908 |   "jsonrpc": "2.0",
11909 |   "id": 1,
11910 |   "result": {
11911 |     "completion": {
11912 |       "values": ["python", "pytorch", "pyside"],
11913 |       "total": 10,
11914 |       "hasMore": true
11915 |     }
11916 |   }
11917 | }
11918 | ```
11919 | 
11920 | For prompts or URI templates with multiple arguments, clients should include previous completions in the `context.arguments` object to provide context for subsequent requests.
11921 | 
11922 | **Request:**
11923 | 
11924 | ```json
11925 | {
11926 |   "jsonrpc": "2.0",
11927 |   "id": 1,
11928 |   "method": "completion/complete",
11929 |   "params": {
11930 |     "ref": {
11931 |       "type": "ref/prompt",
11932 |       "name": "code_review"
11933 |     },
11934 |     "argument": {
11935 |       "name": "framework",
11936 |       "value": "fla"
11937 |     },
11938 |     "context": {
11939 |       "arguments": {
11940 |         "language": "python"
11941 |       }
11942 |     }
11943 |   }
11944 | }
11945 | ```
11946 | 
11947 | **Response:**
11948 | 
11949 | ```json
11950 | {
11951 |   "jsonrpc": "2.0",
11952 |   "id": 1,
11953 |   "result": {
11954 |     "completion": {
11955 |       "values": ["flask"],
11956 |       "total": 1,
11957 |       "hasMore": false
11958 |     }
11959 |   }
11960 | }
11961 | ```
11962 | 
11963 | ### Reference Types
11964 | 
11965 | The protocol supports two types of completion references:
11966 | 
11967 | | Type           | Description                 | Example                                             |
11968 | | -------------- | --------------------------- | --------------------------------------------------- |
11969 | | `ref/prompt`   | References a prompt by name | `{"type": "ref/prompt", "name": "code_review"}`     |
11970 | | `ref/resource` | References a resource URI   | `{"type": "ref/resource", "uri": "file:///{path}"}` |
11971 | 
11972 | ### Completion Results
11973 | 
11974 | Servers return an array of completion values ranked by relevance, with:
11975 | 
11976 | * Maximum 100 items per response
11977 | * Optional total number of available matches
11978 | * Boolean indicating if additional results exist
11979 | 
11980 | ## Message Flow
11981 | 
11982 | ```mermaid
11983 | sequenceDiagram
11984 |     participant Client
11985 |     participant Server
11986 | 
11987 |     Note over Client: User types argument
11988 |     Client->>Server: completion/complete
11989 |     Server-->>Client: Completion suggestions
11990 | 
11991 |     Note over Client: User continues typing
11992 |     Client->>Server: completion/complete
11993 |     Server-->>Client: Refined suggestions
11994 | ```
11995 | 
11996 | ## Data Types
11997 | 
11998 | ### CompleteRequest
11999 | 
12000 | * `ref`: A `PromptReference` or `ResourceReference`
12001 | * `argument`: Object containing:
12002 |   * `name`: Argument name
12003 |   * `value`: Current value
12004 | * `context`: Object containing:
12005 |   * `arguments`: A mapping of already-resolved argument names to their values.
12006 | 
12007 | ### CompleteResult
12008 | 
12009 | * `completion`: Object containing:
12010 |   * `values`: Array of suggestions (max 100)
12011 |   * `total`: Optional total matches
12012 |   * `hasMore`: Additional results flag
12013 | 
12014 | ## Error Handling
12015 | 
12016 | Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
12017 | 
12018 | * Method not found: `-32601` (Capability not supported)
12019 | * Invalid prompt name: `-32602` (Invalid params)
12020 | * Missing required arguments: `-32602` (Invalid params)
12021 | * Internal errors: `-32603` (Internal error)
12022 | 
12023 | ## Implementation Considerations
12024 | 
12025 | 1. Servers **SHOULD**:
12026 | 
12027 |    * Return suggestions sorted by relevance
12028 |    * Implement fuzzy matching where appropriate
12029 |    * Rate limit completion requests
12030 |    * Validate all inputs
12031 | 
12032 | 2. Clients **SHOULD**:
12033 |    * Debounce rapid completion requests
12034 |    * Cache completion results where appropriate
12035 |    * Handle missing or partial results gracefully
12036 | 
12037 | ## Security
12038 | 
12039 | Implementations **MUST**:
12040 | 
12041 | * Validate all completion inputs
12042 | * Implement appropriate rate limiting
12043 | * Control access to sensitive suggestions
12044 | * Prevent completion-based information disclosure
12045 | 
12046 | 
12047 | # Logging
12048 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging
12049 | 
12050 | 
12051 | 
12052 | <div id="enable-section-numbers" />
12053 | 
12054 | <Info>**Protocol Revision**: 2025-06-18</Info>
12055 | 
12056 | The Model Context Protocol (MCP) provides a standardized way for servers to send
12057 | structured log messages to clients. Clients can control logging verbosity by setting
12058 | minimum log levels, with servers sending notifications containing severity levels,
12059 | optional logger names, and arbitrary JSON-serializable data.
12060 | 
12061 | ## User Interaction Model
12062 | 
12063 | Implementations are free to expose logging through any interface pattern that suits their
12064 | needs—the protocol itself does not mandate any specific user interaction model.
12065 | 
12066 | ## Capabilities
12067 | 
12068 | Servers that emit log message notifications **MUST** declare the `logging` capability:
12069 | 
12070 | ```json
12071 | {
12072 |   "capabilities": {
12073 |     "logging": {}
12074 |   }
12075 | }
12076 | ```
12077 | 
12078 | ## Log Levels
12079 | 
12080 | The protocol follows the standard syslog severity levels specified in
12081 | [RFC 5424](https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1):
12082 | 
12083 | | Level     | Description                      | Example Use Case           |
12084 | | --------- | -------------------------------- | -------------------------- |
12085 | | debug     | Detailed debugging information   | Function entry/exit points |
12086 | | info      | General informational messages   | Operation progress updates |
12087 | | notice    | Normal but significant events    | Configuration changes      |
12088 | | warning   | Warning conditions               | Deprecated feature usage   |
12089 | | error     | Error conditions                 | Operation failures         |
12090 | | critical  | Critical conditions              | System component failures  |
12091 | | alert     | Action must be taken immediately | Data corruption detected   |
12092 | | emergency | System is unusable               | Complete system failure    |
12093 | 
12094 | ## Protocol Messages
12095 | 
12096 | ### Setting Log Level
12097 | 
12098 | To configure the minimum log level, clients **MAY** send a `logging/setLevel` request:
12099 | 
12100 | **Request:**
12101 | 
12102 | ```json
12103 | {
12104 |   "jsonrpc": "2.0",
12105 |   "id": 1,
12106 |   "method": "logging/setLevel",
12107 |   "params": {
12108 |     "level": "info"
12109 |   }
12110 | }
12111 | ```
12112 | 
12113 | ### Log Message Notifications
12114 | 
12115 | Servers send log messages using `notifications/message` notifications:
12116 | 
12117 | ```json
12118 | {
12119 |   "jsonrpc": "2.0",
12120 |   "method": "notifications/message",
12121 |   "params": {
12122 |     "level": "error",
12123 |     "logger": "database",
12124 |     "data": {
12125 |       "error": "Connection failed",
12126 |       "details": {
12127 |         "host": "localhost",
12128 |         "port": 5432
12129 |       }
12130 |     }
12131 |   }
12132 | }
12133 | ```
12134 | 
12135 | ## Message Flow
12136 | 
12137 | ```mermaid
12138 | sequenceDiagram
12139 |     participant Client
12140 |     participant Server
12141 | 
12142 |     Note over Client,Server: Configure Logging
12143 |     Client->>Server: logging/setLevel (info)
12144 |     Server-->>Client: Empty Result
12145 | 
12146 |     Note over Client,Server: Server Activity
12147 |     Server--)Client: notifications/message (info)
12148 |     Server--)Client: notifications/message (warning)
12149 |     Server--)Client: notifications/message (error)
12150 | 
12151 |     Note over Client,Server: Level Change
12152 |     Client->>Server: logging/setLevel (error)
12153 |     Server-->>Client: Empty Result
12154 |     Note over Server: Only sends error level<br/>and above
12155 | ```
12156 | 
12157 | ## Error Handling
12158 | 
12159 | Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
12160 | 
12161 | * Invalid log level: `-32602` (Invalid params)
12162 | * Configuration errors: `-32603` (Internal error)
12163 | 
12164 | ## Implementation Considerations
12165 | 
12166 | 1. Servers **SHOULD**:
12167 | 
12168 |    * Rate limit log messages
12169 |    * Include relevant context in data field
12170 |    * Use consistent logger names
12171 |    * Remove sensitive information
12172 | 
12173 | 2. Clients **MAY**:
12174 |    * Present log messages in the UI
12175 |    * Implement log filtering/search
12176 |    * Display severity visually
12177 |    * Persist log messages
12178 | 
12179 | ## Security
12180 | 
12181 | 1. Log messages **MUST NOT** contain:
12182 | 
12183 |    * Credentials or secrets
12184 |    * Personal identifying information
12185 |    * Internal system details that could aid attacks
12186 | 
12187 | 2. Implementations **SHOULD**:
12188 |    * Rate limit messages
12189 |    * Validate all data fields
12190 |    * Control log access
12191 |    * Monitor for sensitive content
12192 | 
12193 | 
12194 | # Pagination
12195 | Source: https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/pagination
12196 | 
12197 | 
12198 | 
12199 | <div id="enable-section-numbers" />
12200 | 
12201 | <Info>**Protocol Revision**: 2025-06-18</Info>
12202 | 
12203 | The Model Context Protocol (MCP) supports paginating list operations that may return
12204 | large result sets. Pagination allows servers to yield results in smaller chunks rather
12205 | than all at once.
12206 | 
12207 | Pagination is especially important when connecting to external services over the
12208 | internet, but also useful for local integrations to avoid performance issues with large
12209 | data sets.
12210 | 
12211 | ## Pagination Model
12212 | 
12213 | Pagination in MCP uses an opaque cursor-based approach, instead of numbered pages.
12214 | 
12215 | * The **cursor** is an opaque string token, representing a position in the result set
12216 | * **Page size** is determined by the server, and clients **MUST NOT** assume a fixed page
12217 |   size
12218 | 
12219 | ## Response Format
12220 | 
12221 | Pagination starts when the server sends a **response** that includes:
12222 | 
12223 | * The current page of results
12224 | * An optional `nextCursor` field if more results exist
12225 | 
12226 | ```json
12227 | {
12228 |   "jsonrpc": "2.0",
12229 |   "id": "123",
12230 |   "result": {
12231 |     "resources": [...],
12232 |     "nextCursor": "eyJwYWdlIjogM30="
12233 |   }
12234 | }
12235 | ```
12236 | 
12237 | ## Request Format
12238 | 
12239 | After receiving a cursor, the client can *continue* paginating by issuing a request
12240 | including that cursor:
12241 | 
12242 | ```json
12243 | {
12244 |   "jsonrpc": "2.0",
12245 |   "method": "resources/list",
12246 |   "params": {
12247 |     "cursor": "eyJwYWdlIjogMn0="
12248 |   }
12249 | }
12250 | ```
12251 | 
12252 | ## Pagination Flow
12253 | 
12254 | ```mermaid
12255 | sequenceDiagram
12256 |     participant Client
12257 |     participant Server
12258 | 
12259 |     Client->>Server: List Request (no cursor)
12260 |     loop Pagination Loop
12261 |       Server-->>Client: Page of results + nextCursor
12262 |       Client->>Server: List Request (with cursor)
12263 |     end
12264 | ```
12265 | 
12266 | ## Operations Supporting Pagination
12267 | 
12268 | The following MCP operations support pagination:
12269 | 
12270 | * `resources/list` - List available resources
12271 | * `resources/templates/list` - List resource templates
12272 | * `prompts/list` - List available prompts
12273 | * `tools/list` - List available tools
12274 | 
12275 | ## Implementation Guidelines
12276 | 
12277 | 1. Servers **SHOULD**:
12278 | 
12279 |    * Provide stable cursors
12280 |    * Handle invalid cursors gracefully
12281 | 
12282 | 2. Clients **SHOULD**:
12283 | 
12284 |    * Treat a missing `nextCursor` as the end of results
12285 |    * Support both paginated and non-paginated flows
12286 | 
12287 | 3. Clients **MUST** treat cursors as opaque tokens:
12288 |    * Don't make assumptions about cursor format
12289 |    * Don't attempt to parse or modify cursors
12290 |    * Don't persist cursors across sessions
12291 | 
12292 | ## Error Handling
12293 | 
12294 | Invalid cursors **SHOULD** result in an error with code -32602 (Invalid params).
12295 | 
12296 | 
12297 | # Versioning
12298 | Source: https://modelcontextprotocol.io/specification/versioning
12299 | 
12300 | 
12301 | 
12302 | The Model Context Protocol uses string-based version identifiers following the format
12303 | `YYYY-MM-DD`, to indicate the last date backwards incompatible changes were made.
12304 | 
12305 | <Info>
12306 |   The protocol version will *not* be incremented when the
12307 |   protocol is updated, as long as the changes maintain backwards compatibility. This allows
12308 |   for incremental improvements while preserving interoperability.
12309 | </Info>
12310 | 
12311 | ## Revisions
12312 | 
12313 | Revisions may be marked as:
12314 | 
12315 | * **Draft**: in-progress specifications, not yet ready for consumption.
12316 | * **Current**: the current protocol version, which is ready for use and may continue to
12317 |   receive backwards compatible changes.
12318 | * **Final**: past, complete specifications that will not be changed.
12319 | 
12320 | The **current** protocol version is [**2025-06-18**](/specification/2025-06-18/).
12321 | 
12322 | ## Negotiation
12323 | 
12324 | Version negotiation happens during
12325 | [initialization](/specification/2025-06-18/basic/lifecycle#initialization). Clients and
12326 | servers **MAY** support multiple protocol versions simultaneously, but they **MUST**
12327 | agree on a single version to use for the session.
12328 | 
12329 | The protocol provides appropriate error handling if version negotiation fails, allowing
12330 | clients to gracefully terminate connections when they cannot find a version compatible
12331 | with the server.
12332 | 
12333 | 
12334 | # Building MCP with LLMs
12335 | Source: https://modelcontextprotocol.io/tutorials/building-mcp-with-llms
12336 | 
12337 | Speed up your MCP development using LLMs such as Claude!
12338 | 
12339 | This guide will help you use LLMs to help you build custom Model Context Protocol (MCP) servers and clients. We'll be focusing on Claude for this tutorial, but you can do this with any frontier LLM.
12340 | 
12341 | ## Preparing the documentation
12342 | 
12343 | Before starting, gather the necessary documentation to help Claude understand MCP:
12344 | 
12345 | 1. Visit [https://modelcontextprotocol.io/llms-full.txt](https://modelcontextprotocol.io/llms-full.txt) and copy the full documentation text
12346 | 2. Navigate to either the [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) or [Python SDK repository](https://github.com/modelcontextprotocol/python-sdk)
12347 | 3. Copy the README files and other relevant documentation
12348 | 4. Paste these documents into your conversation with Claude
12349 | 
12350 | ## Describing your server
12351 | 
12352 | Once you've provided the documentation, clearly describe to Claude what kind of server you want to build. Be specific about:
12353 | 
12354 | * What resources your server will expose
12355 | * What tools it will provide
12356 | * Any prompts it should offer
12357 | * What external systems it needs to interact with
12358 | 
12359 | For example:
12360 | 
12361 | ```
12362 | Build an MCP server that:
12363 | - Connects to my company's PostgreSQL database
12364 | - Exposes table schemas as resources
12365 | - Provides tools for running read-only SQL queries
12366 | - Includes prompts for common data analysis tasks
12367 | ```
12368 | 
12369 | ## Working with Claude
12370 | 
12371 | When working with Claude on MCP servers:
12372 | 
12373 | 1. Start with the core functionality first, then iterate to add more features
12374 | 2. Ask Claude to explain any parts of the code you don't understand
12375 | 3. Request modifications or improvements as needed
12376 | 4. Have Claude help you test the server and handle edge cases
12377 | 
12378 | Claude can help implement all the key MCP features:
12379 | 
12380 | * Resource management and exposure
12381 | * Tool definitions and implementations
12382 | * Prompt templates and handlers
12383 | * Error handling and logging
12384 | * Connection and transport setup
12385 | 
12386 | ## Best practices
12387 | 
12388 | When building MCP servers with Claude:
12389 | 
12390 | * Break down complex servers into smaller pieces
12391 | * Test each component thoroughly before moving on
12392 | * Keep security in mind - validate inputs and limit access appropriately
12393 | * Document your code well for future maintenance
12394 | * Follow MCP protocol specifications carefully
12395 | 
12396 | ## Next steps
12397 | 
12398 | After Claude helps you build your server:
12399 | 
12400 | 1. Review the generated code carefully
12401 | 2. Test the server with the MCP Inspector tool
12402 | 3. Connect it to Claude.app or other MCP clients
12403 | 4. Iterate based on real usage and feedback
12404 | 
12405 | Remember that Claude can help you modify and improve your server as requirements change over time.
12406 | 
12407 | Need more guidance? Just ask Claude specific questions about implementing MCP features or troubleshooting issues that arise.
12408 | 
12409 | 
```
Page 2/2FirstPrevNextLast