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 |  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 |  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 | ```