From 0c2dc84461e089ea23c98a853b35438833afec10 Mon Sep 17 00:00:00 2001 From: Mark Garrison Date: Fri, 24 Oct 2025 06:50:52 -0600 Subject: [PATCH 01/12] initial implementation --- .cursor/rules/about-codebase.mdc | 5 +- .cursor/rules/best-practices.mdc | 4 + .cursor/rules/environment-variables.mdc | 7 +- .cursor/rules/mcp-server-pattern.mdc | 5 +- .cursor/rules/technologies.mdc | 5 +- .cursorindexingignore | 2 - README.md | 70 +- context/Python-MCP-SDK.md | 2375 ++- context/llms-full.txt | 22363 +++++++++------------- pyproject.toml | 12 +- src/codelogic_mcp_server/handlers.py | 1981 ++ src/codelogic_mcp_server/server.py | 6 + uv.lock | 405 +- 13 files changed, 13099 insertions(+), 14141 deletions(-) delete mode 100644 .cursorindexingignore diff --git a/.cursor/rules/about-codebase.mdc b/.cursor/rules/about-codebase.mdc index 3bcb166..cc801b6 100644 --- a/.cursor/rules/about-codebase.mdc +++ b/.cursor/rules/about-codebase.mdc @@ -5,4 +5,7 @@ alwaysApply: false --- - This repository contains a Model Context Protocol (MCP) server that integrates with CodeLogic's knowledge graph APIs - It enables AI programming assistants to access dependency data from CodeLogic to analyze code and database impacts -- The core package is in src/codelogic_mcp_server/ with server.py, handlers.py, and utils.py \ No newline at end of file +- **NEW**: Provides DevOps CI/CD integration capabilities for CodeLogic scanning in Jenkins, GitHub Actions, Azure DevOps, and GitLab CI +- **NEW**: Generates structured data for AI models to directly modify CI/CD files and implement CodeLogic scanning +- The core package is in src/codelogic_mcp_server/ with server.py, handlers.py, and utils.py +- **DevOps Tools**: codelogic-docker-agent, codelogic-build-info, codelogic-pipeline-helper for CI/CD integration \ No newline at end of file diff --git a/.cursor/rules/best-practices.mdc b/.cursor/rules/best-practices.mdc index dd47eee..78c77aa 100644 --- a/.cursor/rules/best-practices.mdc +++ b/.cursor/rules/best-practices.mdc @@ -6,3 +6,7 @@ alwaysApply: false - Use semantic search before grep for broader context - Maintain proper error handling and logging - Keep code changes atomic and focused +- **NEW**: For DevOps tools, provide structured JSON data for AI file modification +- **NEW**: Include specific file paths, line numbers, and exact code modifications +- **NEW**: Generate platform-specific CI/CD configurations (Jenkins, GitHub Actions, Azure DevOps, GitLab) +- **NEW**: Always include setup instructions and validation checks for DevOps integrations diff --git a/.cursor/rules/environment-variables.mdc b/.cursor/rules/environment-variables.mdc index 77b3b3c..b4303fd 100644 --- a/.cursor/rules/environment-variables.mdc +++ b/.cursor/rules/environment-variables.mdc @@ -8,4 +8,9 @@ alwaysApply: false - `CODELOGIC_PASSWORD`: Password for authentication - `CODELOGIC_WORKSPACE_NAME`: Workspace name - `CODELOGIC_DEBUG_MODE`: Enable debug logging -- `CODELOGIC_TEST_MODE`: Used by test framework \ No newline at end of file +- `CODELOGIC_TEST_MODE`: Used by test framework +- **NEW**: DevOps CI/CD Integration Variables: + - `CODELOGIC_HOST`: CodeLogic server host for Docker agents + - `AGENT_UUID`: CodeLogic agent UUID for authentication + - `AGENT_PASSWORD`: CodeLogic agent password for authentication + - `SCAN_SPACE_NAME`: Target scan space for CodeLogic scans \ No newline at end of file diff --git a/.cursor/rules/mcp-server-pattern.mdc b/.cursor/rules/mcp-server-pattern.mdc index c386bf8..2bbafbf 100644 --- a/.cursor/rules/mcp-server-pattern.mdc +++ b/.cursor/rules/mcp-server-pattern.mdc @@ -18,4 +18,7 @@ async def handle_call_tool(name: str, arguments: dict | None) -> list[types.Text - New tools should be added to handle_list_tools() with descriptive names (prefix: `codelogic-`) - Tool handlers should be implemented in handle_call_tool() - Create handler functions with proper error handling -- Return results as markdown-formatted text \ No newline at end of file +- Return results as markdown-formatted text +- **NEW**: For DevOps tools, return structured JSON data for AI file modification +- **NEW**: Include helper functions for generating platform-specific CI/CD configurations +- **NEW**: Use structured output patterns for file modifications with specific line numbers and content \ No newline at end of file diff --git a/.cursor/rules/technologies.mdc b/.cursor/rules/technologies.mdc index 68ca416..5d87f91 100644 --- a/.cursor/rules/technologies.mdc +++ b/.cursor/rules/technologies.mdc @@ -6,4 +6,7 @@ alwaysApply: false - Python 3.13+ with extensive use of async/await - Model Context Protocol SDK (`mcp[cli]`) - HTTPX for API requests -- Environment variables via dotenv for configuration \ No newline at end of file +- Environment variables via dotenv for configuration +- **NEW**: Docker for CodeLogic agent containerization +- **NEW**: CI/CD Platform Support: Jenkins (Groovy), GitHub Actions (YAML), Azure DevOps (YAML), GitLab CI (YAML) +- **NEW**: JSON structured output for AI model file modification \ No newline at end of file diff --git a/.cursorindexingignore b/.cursorindexingignore deleted file mode 100644 index 68347b3..0000000 --- a/.cursorindexingignore +++ /dev/null @@ -1,2 +0,0 @@ -# Don't index SpecStory auto-save files, but allow explicit context inclusion via @ references -.specstory/** diff --git a/README.md b/README.md index 157a3a1..565dde3 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,25 @@ An [MCP Server](https://modelcontextprotocol.io/introduction) to utilize Codelog ### Tools -The server implements two tools: +The server implements five tools: +#### Code Analysis Tools - **codelogic-method-impact**: Pulls an impact assessment from the CodeLogic server's APIs for your code. - Takes the given "method" that you're working on and its associated "class". - **codelogic-database-impact**: Analyzes impacts between code and database entities. - Takes the database entity type (column, table, or view) and its name. +#### DevOps & CI/CD Integration Tools +- **codelogic-docker-agent**: Generates Docker agent configurations for CodeLogic scanning in CI/CD pipelines. + - Supports .NET, Java, SQL, and TypeScript agents + - Generates configurations for Jenkins, GitHub Actions, Azure DevOps, and GitLab CI +- **codelogic-build-info**: Generates build information and send commands for CodeLogic integration. + - Supports Git information, build logs, and metadata collection + - Provides both Docker and standalone usage examples +- **codelogic-pipeline-helper**: Generates complete CI/CD pipeline configurations for CodeLogic integration. + - Creates comprehensive pipeline configurations with best practices + - Includes error handling, notifications, and scan space management strategies + ### Install #### Pre Requisites @@ -196,6 +208,41 @@ To configure the CodeLogic MCP server in Cursor: The CodeLogic MCP server tools will now be available in your Cursor workspace. +## DevOps Integration + +The CodeLogic MCP Server now includes powerful DevOps capabilities for integrating CodeLogic scanning into your CI/CD pipelines. These tools help DevOps teams: + +### Docker Agent Integration +- Generate Docker run commands for CodeLogic agents +- Create platform-specific configurations (Jenkins, GitHub Actions, Azure DevOps, GitLab CI) +- Set up proper environment variables and volume mounts +- Include build information collection + +### Build Information Management +- Send Git information, build logs, and metadata to CodeLogic servers +- Support multiple CI/CD platforms with platform-specific variables +- Handle log file management and rotation +- Provide both Docker and standalone usage options + +### Complete Pipeline Configuration +- Generate end-to-end CI/CD pipeline configurations +- Include error handling, notifications, and monitoring +- Support different scan space management strategies +- Follow DevOps best practices for security and performance + +### Example Usage + +```bash +# Generate Docker agent configuration for .NET +codelogic-docker-agent --agent-type=dotnet --scan-path=/app --application-name=MyApp --ci-platform=jenkins + +# Set up build information sending +codelogic-build-info --build-type=all --output-format=docker --ci-platform=github-actions + +# Create complete pipeline configuration +codelogic-pipeline-helper --ci-platform=jenkins --agent-type=dotnet --scan-triggers=main,develop +``` + ## AI Assistant Instructions/Rules To help the AI assistant use the CodeLogic tools effectively, you can add the following instructions/rules to your client's configuration. We recommend customizing these instructions to align with your team's specific coding standards, best practices, and workflow requirements: @@ -216,9 +263,16 @@ When modifying SQL code or database entities: - Always use codelogic-database-impact to analyze potential impacts - Highlight impact results for the modified database entities +For DevOps and CI/CD integration: +- Use codelogic-docker-agent to generate Docker agent configurations +- Use codelogic-build-info to set up build information sending +- Use codelogic-pipeline-helper to create complete CI/CD pipeline configurations +- Support Jenkins, GitHub Actions, Azure DevOps, and GitLab CI platforms + To use the CodeLogic tools effectively: - For code impacts: Ask about specific methods or functions - For database relationships: Ask about tables, views, or columns +- For DevOps: Ask about CI/CD integration, Docker agents, or build information - Review the impact results before making changes - Consider both direct and indirect impacts ``` @@ -239,9 +293,16 @@ When modifying SQL code or database entities: - Always use codelogic-database-impact to analyze potential impacts - Highlight impact results for the modified database entities +For DevOps and CI/CD integration: +- Use codelogic-docker-agent to generate Docker agent configurations +- Use codelogic-build-info to set up build information sending +- Use codelogic-pipeline-helper to create complete CI/CD pipeline configurations +- Support Jenkins, GitHub Actions, Azure DevOps, and GitLab CI platforms + To use the CodeLogic tools effectively: - For code impacts: Ask about specific methods or functions - For database relationships: Ask about tables, views, or columns +- For DevOps: Ask about CI/CD integration, Docker agents, or build information - Review the impact results before making changes - Consider both direct and indirect impacts ``` @@ -260,9 +321,16 @@ When modifying SQL code or database entities: - Always use codelogic-database-impact to analyze potential impacts - Highlight impact results for the modified database entities +For DevOps and CI/CD integration: +- Use codelogic-docker-agent to generate Docker agent configurations +- Use codelogic-build-info to set up build information sending +- Use codelogic-pipeline-helper to create complete CI/CD pipeline configurations +- Support Jenkins, GitHub Actions, Azure DevOps, and GitLab CI platforms + To use the CodeLogic tools effectively: - For code impacts: Ask about specific methods or functions - For database relationships: Ask about tables, views, or columns +- For DevOps: Ask about CI/CD integration, Docker agents, or build information - Review the impact results before making changes - Consider both direct and indirect impacts ``` diff --git a/context/Python-MCP-SDK.md b/context/Python-MCP-SDK.md index 05d6072..ced0eaf 100644 --- a/context/Python-MCP-SDK.md +++ b/context/Python-MCP-SDK.md @@ -8,8 +8,8 @@ [![MIT licensed][mit-badge]][mit-url] [![Python Version][python-badge]][python-url] [![Documentation][docs-badge]][docs-url] +[![Protocol][protocol-badge]][protocol-url] [![Specification][spec-badge]][spec-url] -[![GitHub Discussions][discussions-badge]][discussions-url] @@ -27,20 +27,41 @@ - [Server](#server) - [Resources](#resources) - [Tools](#tools) + - [Structured Output](#structured-output) - [Prompts](#prompts) - [Images](#images) - [Context](#context) + - [Getting Context in Functions](#getting-context-in-functions) + - [Context Properties and Methods](#context-properties-and-methods) + - [Completions](#completions) + - [Elicitation](#elicitation) + - [Sampling](#sampling) + - [Logging and Notifications](#logging-and-notifications) + - [Authentication](#authentication) + - [FastMCP Properties](#fastmcp-properties) + - [Session Properties and Methods](#session-properties-and-methods) + - [Request Context Properties](#request-context-properties) - [Running Your Server](#running-your-server) - [Development Mode](#development-mode) - [Claude Desktop Integration](#claude-desktop-integration) - [Direct Execution](#direct-execution) + - [Streamable HTTP Transport](#streamable-http-transport) + - [CORS Configuration for Browser-Based Clients](#cors-configuration-for-browser-based-clients) - [Mounting to an Existing ASGI Server](#mounting-to-an-existing-asgi-server) - - [Examples](#examples) - - [Echo Server](#echo-server) - - [SQLite Explorer](#sqlite-explorer) + - [StreamableHTTP servers](#streamablehttp-servers) + - [Basic mounting](#basic-mounting) + - [Host-based routing](#host-based-routing) + - [Multiple servers with path configuration](#multiple-servers-with-path-configuration) + - [Path configuration at initialization](#path-configuration-at-initialization) + - [SSE servers](#sse-servers) - [Advanced Usage](#advanced-usage) - [Low-Level Server](#low-level-server) + - [Structured Output Support](#structured-output-support) + - [Pagination (Advanced)](#pagination-advanced) - [Writing MCP Clients](#writing-mcp-clients) + - [Client Display Utilities](#client-display-utilities) + - [OAuth Authentication for Clients](#oauth-authentication-for-clients) + - [Parsing Tool Results](#parsing-tool-results) - [MCP Primitives](#mcp-primitives) - [Server Capabilities](#server-capabilities) - [Documentation](#documentation) @@ -53,12 +74,12 @@ [mit-url]: https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE [python-badge]: https://img.shields.io/pypi/pyversions/mcp.svg [python-url]: https://www.python.org/downloads/ -[docs-badge]: https://img.shields.io/badge/docs-modelcontextprotocol.io-blue.svg -[docs-url]: https://modelcontextprotocol.io +[docs-badge]: https://img.shields.io/badge/docs-python--sdk-blue.svg +[docs-url]: https://modelcontextprotocol.github.io/python-sdk/ +[protocol-badge]: https://img.shields.io/badge/protocol-modelcontextprotocol.io-blue.svg +[protocol-url]: https://modelcontextprotocol.io [spec-badge]: https://img.shields.io/badge/spec-spec.modelcontextprotocol.io-blue.svg [spec-url]: https://spec.modelcontextprotocol.io -[discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk -[discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions ## Overview @@ -66,14 +87,14 @@ The Model Context Protocol allows applications to provide context for LLMs in a - Build MCP clients that can connect to any MCP server - Create MCP servers that expose resources, prompts and tools -- Use standard transports like stdio and SSE +- Use standard transports like stdio, SSE, and Streamable HTTP - Handle all MCP protocol messages and lifecycle events ## Installation ### Adding MCP to your python project -We recommend using [uv](https://docs.astral.sh/uv/) to manage your Python projects. +We recommend using [uv](https://docs.astral.sh/uv/) to manage your Python projects. If you haven't created a uv-managed project yet, create one: @@ -89,6 +110,7 @@ If you haven't created a uv-managed project yet, create one: ``` Alternatively, for projects using pip for dependencies: + ```bash pip install "mcp[cli]" ``` @@ -105,8 +127,15 @@ uv run mcp Let's create a simple MCP server that exposes a calculator tool and some data: + ```python -# server.py +""" +FastMCP quickstart example. + +cd to the `examples/snippets/clients` directory and run: + uv run server fastmcp_quickstart stdio +""" + from mcp.server.fastmcp import FastMCP # Create an MCP server @@ -125,16 +154,34 @@ def add(a: int, b: int) -> int: def get_greeting(name: str) -> str: """Get a personalized greeting""" return f"Hello, {name}!" + + +# Add a prompt +@mcp.prompt() +def greet_user(name: str, style: str = "friendly") -> str: + """Generate a greeting prompt""" + styles = { + "friendly": "Please write a warm, friendly greeting", + "formal": "Please write a formal, professional greeting", + "casual": "Please write a casual, relaxed greeting", + } + + return f"{styles.get(style, styles['friendly'])} for someone named {name}." ``` +_Full example: [examples/snippets/servers/fastmcp_quickstart.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/fastmcp_quickstart.py)_ + + You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running: + ```bash -mcp install server.py +uv run mcp install server.py ``` Alternatively, you can test it with the MCP Inspector: + ```bash -mcp dev server.py +uv run mcp dev server.py ``` ## What is MCP? @@ -152,31 +199,46 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you bui The FastMCP server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing: + ```python -# Add lifespan support for startup/shutdown with strong typing -from contextlib import asynccontextmanager +"""Example showing lifespan support for startup/shutdown with strong typing.""" + from collections.abc import AsyncIterator +from contextlib import asynccontextmanager from dataclasses import dataclass -from fake_database import Database # Replace with your actual DB type - from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession -# Create a named server -mcp = FastMCP("My App") -# Specify dependencies for deployment and development -mcp = FastMCP("My App", dependencies=["pandas", "numpy"]) +# Mock database class for example +class Database: + """Mock database class for example.""" + + @classmethod + async def connect(cls) -> "Database": + """Connect to database.""" + return cls() + + async def disconnect(self) -> None: + """Disconnect from database.""" + pass + + def query(self) -> str: + """Execute a query.""" + return "Query result" @dataclass class AppContext: + """Application context with typed dependencies.""" + db: Database @asynccontextmanager async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]: - """Manage application lifecycle with type-safe context""" + """Manage application lifecycle with type-safe context.""" # Initialize on startup db = await Database.connect() try: @@ -192,433 +254,2157 @@ mcp = FastMCP("My App", lifespan=app_lifespan) # Access type-safe lifespan context in tools @mcp.tool() -def query_db(ctx: Context) -> str: - """Tool that uses initialized resources""" - db = ctx.request_context.lifespan_context["db"] +def query_db(ctx: Context[ServerSession, AppContext]) -> str: + """Tool that uses initialized resources.""" + db = ctx.request_context.lifespan_context.db return db.query() ``` +_Full example: [examples/snippets/servers/lifespan_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lifespan_example.py)_ + + ### Resources Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects: + ```python from mcp.server.fastmcp import FastMCP -mcp = FastMCP("My App") +mcp = FastMCP(name="Resource Example") -@mcp.resource("config://app") -def get_config() -> str: - """Static configuration data""" - return "App configuration here" +@mcp.resource("file://documents/{name}") +def read_document(name: str) -> str: + """Read a document by name.""" + # This would normally read from disk + return f"Content of {name}" -@mcp.resource("users://{user_id}/profile") -def get_user_profile(user_id: str) -> str: - """Dynamic user data""" - return f"Profile data for user {user_id}" +@mcp.resource("config://settings") +def get_settings() -> str: + """Get application settings.""" + return """{ + "theme": "dark", + "language": "en", + "debug": false +}""" ``` +_Full example: [examples/snippets/servers/basic_resource.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_resource.py)_ + + ### Tools Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects: + ```python -import httpx from mcp.server.fastmcp import FastMCP -mcp = FastMCP("My App") +mcp = FastMCP(name="Tool Example") @mcp.tool() -def calculate_bmi(weight_kg: float, height_m: float) -> float: - """Calculate BMI given weight in kg and height in meters""" - return weight_kg / (height_m**2) +def sum(a: int, b: int) -> int: + """Add two numbers together.""" + return a + b @mcp.tool() -async def fetch_weather(city: str) -> str: - """Fetch current weather for a city""" - async with httpx.AsyncClient() as client: - response = await client.get(f"https://api.weather.com/{city}") - return response.text +def get_weather(city: str, unit: str = "celsius") -> str: + """Get weather for a city.""" + # This would normally call a weather API + return f"Weather in {city}: 22degrees{unit[0].upper()}" ``` -### Prompts +_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_ + -Prompts are reusable templates that help LLMs interact with your server effectively: +Tools can optionally receive a Context object by including a parameter with the `Context` type annotation. This context is automatically injected by the FastMCP framework and provides access to MCP capabilities: + ```python -from mcp.server.fastmcp import FastMCP -from mcp.server.fastmcp.prompts import base - -mcp = FastMCP("My App") +from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession +mcp = FastMCP(name="Progress Example") -@mcp.prompt() -def review_code(code: str) -> str: - return f"Please review this code:\n\n{code}" +@mcp.tool() +async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str: + """Execute a task with progress updates.""" + await ctx.info(f"Starting: {task_name}") + + for i in range(steps): + progress = (i + 1) / steps + await ctx.report_progress( + progress=progress, + total=1.0, + message=f"Step {i + 1}/{steps}", + ) + await ctx.debug(f"Completed step {i + 1}") -@mcp.prompt() -def debug_error(error: str) -> list[base.Message]: - return [ - base.UserMessage("I'm seeing this error:"), - base.UserMessage(error), - base.AssistantMessage("I'll help debug that. What have you tried so far?"), - ] + return f"Task '{task_name}' completed" ``` -### Images +_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_ + -FastMCP provides an `Image` class that automatically handles image data: +#### Structured Output -```python -from mcp.server.fastmcp import FastMCP, Image -from PIL import Image as PILImage +Tools will return structured results by default, if their return type +annotation is compatible. Otherwise, they will return unstructured results. -mcp = FastMCP("My App") +Structured output supports these return types: +- Pydantic models (BaseModel subclasses) +- TypedDicts +- Dataclasses and other classes with type hints +- `dict[str, T]` (where T is any JSON-serializable type) +- Primitive types (str, int, float, bool, bytes, None) - wrapped in `{"result": value}` +- Generic types (list, tuple, Union, Optional, etc.) - wrapped in `{"result": value}` -@mcp.tool() -def create_thumbnail(image_path: str) -> Image: - """Create a thumbnail from an image""" - img = PILImage.open(image_path) - img.thumbnail((100, 100)) - return Image(data=img.tobytes(), format="png") -``` +Classes without type hints cannot be serialized for structured output. Only +classes with properly annotated attributes will be converted to Pydantic models +for schema generation and validation. -### Context +Structured results are automatically validated against the output schema +generated from the annotation. This ensures the tool returns well-typed, +validated data that clients can easily process. -The Context object gives your tools and resources access to MCP capabilities: +**Note:** For backward compatibility, unstructured results are also +returned. Unstructured results are provided for backward compatibility +with previous versions of the MCP specification, and are quirks-compatible +with previous versions of FastMCP in the current version of the SDK. -```python -from mcp.server.fastmcp import FastMCP, Context +**Note:** In cases where a tool function's return type annotation +causes the tool to be classified as structured _and this is undesirable_, +the classification can be suppressed by passing `structured_output=False` +to the `@tool` decorator. -mcp = FastMCP("My App") +##### Advanced: Direct CallToolResult +For full control over tool responses including the `_meta` field (for passing data to client applications without exposing it to the model), you can return `CallToolResult` directly: -@mcp.tool() -async def long_task(files: list[str], ctx: Context) -> str: - """Process multiple files with progress tracking""" - for i, file in enumerate(files): - ctx.info(f"Processing {file}") - await ctx.report_progress(i, len(files)) - data, mime_type = await ctx.read_resource(f"file://{file}") - return "Processing complete" -``` + +```python +"""Example showing direct CallToolResult return for advanced control.""" -## Running Your Server +from typing import Annotated -### Development Mode +from pydantic import BaseModel -The fastest way to test and debug your server is with the MCP Inspector: +from mcp.server.fastmcp import FastMCP +from mcp.types import CallToolResult, TextContent -```bash -mcp dev server.py +mcp = FastMCP("CallToolResult Example") -# Add dependencies -mcp dev server.py --with pandas --with numpy -# Mount local code -mcp dev server.py --with-editable . -``` +class ValidationModel(BaseModel): + """Model for validating structured output.""" -### Claude Desktop Integration + status: str + data: dict[str, int] -Once your server is ready, install it in Claude Desktop: -```bash -mcp install server.py +@mcp.tool() +def advanced_tool() -> CallToolResult: + """Return CallToolResult directly for full control including _meta field.""" + return CallToolResult( + content=[TextContent(type="text", text="Response visible to the model")], + _meta={"hidden": "data for client applications only"}, + ) -# Custom name -mcp install server.py --name "My Analytics Server" -# Environment variables -mcp install server.py -v API_KEY=abc123 -v DB_URL=postgres://... -mcp install server.py -f .env +@mcp.tool() +def validated_tool() -> Annotated[CallToolResult, ValidationModel]: + """Return CallToolResult with structured output validation.""" + return CallToolResult( + content=[TextContent(type="text", text="Validated response")], + structuredContent={"status": "success", "data": {"result": 42}}, + _meta={"internal": "metadata"}, + ) + + +@mcp.tool() +def empty_result_tool() -> CallToolResult: + """For empty results, return CallToolResult with empty content.""" + return CallToolResult(content=[]) ``` -### Direct Execution +_Full example: [examples/snippets/servers/direct_call_tool_result.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/direct_call_tool_result.py)_ + -For advanced scenarios like custom deployments: +**Important:** `CallToolResult` must always be returned (no `Optional` or `Union`). For empty results, use `CallToolResult(content=[])`. For optional simple types, use `str | None` without `CallToolResult`. + ```python +"""Example showing structured output with tools.""" + +from typing import TypedDict + +from pydantic import BaseModel, Field + from mcp.server.fastmcp import FastMCP -mcp = FastMCP("My App") +mcp = FastMCP("Structured Output Example") -if __name__ == "__main__": - mcp.run() -``` -Run it with: -```bash -python server.py -# or -mcp run server.py -``` +# Using Pydantic models for rich structured data +class WeatherData(BaseModel): + """Weather information structure.""" -### Mounting to an Existing ASGI Server + temperature: float = Field(description="Temperature in Celsius") + humidity: float = Field(description="Humidity percentage") + condition: str + wind_speed: float -You can mount the SSE server to an existing ASGI server using the `sse_app` method. This allows you to integrate the SSE server with other ASGI applications. -```python -from starlette.applications import Starlette -from starlette.routing import Mount, Host -from mcp.server.fastmcp import FastMCP +@mcp.tool() +def get_weather(city: str) -> WeatherData: + """Get weather for a city - returns structured data.""" + # Simulated weather data + return WeatherData( + temperature=22.5, + humidity=45.0, + condition="sunny", + wind_speed=5.2, + ) -mcp = FastMCP("My App") +# Using TypedDict for simpler structures +class LocationInfo(TypedDict): + latitude: float + longitude: float + name: str -# Mount the SSE server to the existing ASGI server -app = Starlette( - routes=[ - Mount('/', app=mcp.sse_app()), - ] -) -# or dynamically mount as host -app.router.routes.append(Host('mcp.acme.corp', app=mcp.sse_app())) -``` +@mcp.tool() +def get_location(address: str) -> LocationInfo: + """Get location coordinates""" + return LocationInfo(latitude=51.5074, longitude=-0.1278, name="London, UK") -For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes). -## Examples +# Using dict[str, Any] for flexible schemas +@mcp.tool() +def get_statistics(data_type: str) -> dict[str, float]: + """Get various statistics""" + return {"mean": 42.5, "median": 40.0, "std_dev": 5.2} -### Echo Server -A simple server demonstrating resources, tools, and prompts: +# Ordinary classes with type hints work for structured output +class UserProfile: + name: str + age: int + email: str | None = None + + def __init__(self, name: str, age: int, email: str | None = None): + self.name = name + self.age = age + self.email = email -```python -from mcp.server.fastmcp import FastMCP -mcp = FastMCP("Echo") +@mcp.tool() +def get_user(user_id: str) -> UserProfile: + """Get user profile - returns structured data""" + return UserProfile(name="Alice", age=30, email="alice@example.com") -@mcp.resource("echo://{message}") -def echo_resource(message: str) -> str: - """Echo a message as a resource""" - return f"Resource echo: {message}" +# Classes WITHOUT type hints cannot be used for structured output +class UntypedConfig: + def __init__(self, setting1, setting2): # type: ignore[reportMissingParameterType] + self.setting1 = setting1 + self.setting2 = setting2 @mcp.tool() -def echo_tool(message: str) -> str: - """Echo a message as a tool""" - return f"Tool echo: {message}" +def get_config() -> UntypedConfig: + """This returns unstructured output - no schema generated""" + return UntypedConfig("value1", "value2") -@mcp.prompt() -def echo_prompt(message: str) -> str: - """Create an echo prompt""" - return f"Please process this message: {message}" +# Lists and other types are wrapped automatically +@mcp.tool() +def list_cities() -> list[str]: + """Get a list of cities""" + return ["London", "Paris", "Tokyo"] + # Returns: {"result": ["London", "Paris", "Tokyo"]} + + +@mcp.tool() +def get_temperature(city: str) -> float: + """Get temperature as a simple float""" + return 22.5 + # Returns: {"result": 22.5} ``` -### SQLite Explorer +_Full example: [examples/snippets/servers/structured_output.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/structured_output.py)_ + -A more complex example showing database integration: +### Prompts -```python -import sqlite3 +Prompts are reusable templates that help LLMs interact with your server effectively: + +```python from mcp.server.fastmcp import FastMCP +from mcp.server.fastmcp.prompts import base -mcp = FastMCP("SQLite Explorer") +mcp = FastMCP(name="Prompt Example") -@mcp.resource("schema://main") -def get_schema() -> str: - """Provide the database schema as a resource""" - conn = sqlite3.connect("database.db") - schema = conn.execute("SELECT sql FROM sqlite_master WHERE type='table'").fetchall() - return "\n".join(sql[0] for sql in schema if sql[0]) +@mcp.prompt(title="Code Review") +def review_code(code: str) -> str: + return f"Please review this code:\n\n{code}" -@mcp.tool() -def query_data(sql: str) -> str: - """Execute SQL queries safely""" - conn = sqlite3.connect("database.db") - try: - result = conn.execute(sql).fetchall() - return "\n".join(str(row) for row in result) - except Exception as e: - return f"Error: {str(e)}" +@mcp.prompt(title="Debug Assistant") +def debug_error(error: str) -> list[base.Message]: + return [ + base.UserMessage("I'm seeing this error:"), + base.UserMessage(error), + base.AssistantMessage("I'll help debug that. What have you tried so far?"), + ] ``` -## Advanced Usage +_Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)_ + -### Low-Level Server +### Icons -For more control, you can use the low-level server implementation directly. This gives you full access to the protocol and allows you to customize every aspect of your server, including lifecycle management through the lifespan API: +MCP servers can provide icons for UI display. Icons can be added to the server implementation, tools, resources, and prompts: ```python -from contextlib import asynccontextmanager -from collections.abc import AsyncIterator +from mcp.server.fastmcp import FastMCP, Icon -from fake_database import Database # Replace with your actual DB type +# Create an icon from a file path or URL +icon = Icon( + src="icon.png", + mimeType="image/png", + sizes="64x64" +) -from mcp.server import Server +# Add icons to server +mcp = FastMCP( + "My Server", + website_url="https://example.com", + icons=[icon] +) +# Add icons to tools, resources, and prompts +@mcp.tool(icons=[icon]) +def my_tool(): + """Tool with an icon.""" + return "result" -@asynccontextmanager -async def server_lifespan(server: Server) -> AsyncIterator[dict]: - """Manage server startup and shutdown lifecycle.""" - # Initialize resources on startup - db = await Database.connect() - try: - yield {"db": db} - finally: - # Clean up on shutdown - await db.disconnect() +@mcp.resource("demo://resource", icons=[icon]) +def my_resource(): + """Resource with an icon.""" + return "content" +``` +_Full example: [examples/fastmcp/icons_demo.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/fastmcp/icons_demo.py)_ -# Pass lifespan to server -server = Server("example-server", lifespan=server_lifespan) +### Images + +FastMCP provides an `Image` class that automatically handles image data: + +```python +"""Example showing image handling with FastMCP.""" -# Access lifespan context in handlers -@server.call_tool() -async def query_db(name: str, arguments: dict) -> list: - ctx = server.request_context - db = ctx.lifespan_context["db"] - return await db.query(arguments["query"]) +from PIL import Image as PILImage + +from mcp.server.fastmcp import FastMCP, Image + +mcp = FastMCP("Image Example") + + +@mcp.tool() +def create_thumbnail(image_path: str) -> Image: + """Create a thumbnail from an image""" + img = PILImage.open(image_path) + img.thumbnail((100, 100)) + return Image(data=img.tobytes(), format="png") ``` -The lifespan API provides: -- A way to initialize resources when the server starts and clean them up when it stops -- Access to initialized resources through the request context in handlers -- Type-safe context passing between lifespan and request handlers +_Full example: [examples/snippets/servers/images.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/images.py)_ + -```python -import mcp.server.stdio -import mcp.types as types -from mcp.server.lowlevel import NotificationOptions, Server -from mcp.server.models import InitializationOptions +### Context -# Create a server instance -server = Server("example-server") +The Context object is automatically injected into tool and resource functions that request it via type hints. It provides access to MCP capabilities like logging, progress reporting, resource reading, user interaction, and request metadata. +#### Getting Context in Functions -@server.list_prompts() -async def handle_list_prompts() -> list[types.Prompt]: - return [ - types.Prompt( - name="example-prompt", - description="An example prompt template", - arguments=[ - types.PromptArgument( - name="arg1", description="Example argument", required=True - ) - ], - ) - ] +To use context in a tool or resource function, add a parameter with the `Context` type annotation: +```python +from mcp.server.fastmcp import Context, FastMCP -@server.get_prompt() -async def handle_get_prompt( - name: str, arguments: dict[str, str] | None -) -> types.GetPromptResult: - if name != "example-prompt": - raise ValueError(f"Unknown prompt: {name}") +mcp = FastMCP(name="Context Example") - return types.GetPromptResult( - description="Example prompt", - messages=[ - types.PromptMessage( - role="user", - content=types.TextContent(type="text", text="Example prompt text"), - ) - ], - ) +@mcp.tool() +async def my_tool(x: int, ctx: Context) -> str: + """Tool that uses context capabilities.""" + # The context parameter can have any name as long as it's type-annotated + return await process_with_context(x, ctx) +``` -async def run(): - async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): - await server.run( - read_stream, - write_stream, - InitializationOptions( - server_name="example", - server_version="0.1.0", - capabilities=server.get_capabilities( - notification_options=NotificationOptions(), - experimental_capabilities={}, - ), - ), - ) +#### Context Properties and Methods + +The Context object provides the following capabilities: + +- `ctx.request_id` - Unique ID for the current request +- `ctx.client_id` - Client ID if available +- `ctx.fastmcp` - Access to the FastMCP server instance (see [FastMCP Properties](#fastmcp-properties)) +- `ctx.session` - Access to the underlying session for advanced communication (see [Session Properties and Methods](#session-properties-and-methods)) +- `ctx.request_context` - Access to request-specific data and lifespan resources (see [Request Context Properties](#request-context-properties)) +- `await ctx.debug(message)` - Send debug log message +- `await ctx.info(message)` - Send info log message +- `await ctx.warning(message)` - Send warning log message +- `await ctx.error(message)` - Send error log message +- `await ctx.log(level, message, logger_name=None)` - Send log with custom level +- `await ctx.report_progress(progress, total=None, message=None)` - Report operation progress +- `await ctx.read_resource(uri)` - Read a resource by URI +- `await ctx.elicit(message, schema)` - Request additional information from user with validation + + +```python +from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession +mcp = FastMCP(name="Progress Example") -if __name__ == "__main__": - import asyncio - asyncio.run(run()) +@mcp.tool() +async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str: + """Execute a task with progress updates.""" + await ctx.info(f"Starting: {task_name}") + + for i in range(steps): + progress = (i + 1) / steps + await ctx.report_progress( + progress=progress, + total=1.0, + message=f"Step {i + 1}/{steps}", + ) + await ctx.debug(f"Completed step {i + 1}") + + return f"Task '{task_name}' completed" ``` -### Writing MCP Clients +_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_ + -The SDK provides a high-level client interface for connecting to MCP servers: +### Completions +MCP supports providing completion suggestions for prompt arguments and resource template parameters. With the context parameter, servers can provide completions based on previously resolved values: + +Client usage: + + ```python -from mcp import ClientSession, StdioServerParameters, types +""" +cd to the `examples/snippets` directory and run: + uv run completion-client +""" + +import asyncio +import os + +from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client +from mcp.types import PromptReference, ResourceTemplateReference # Create server parameters for stdio connection server_params = StdioServerParameters( - command="python", # Executable - args=["example_server.py"], # Optional command line arguments - env=None, # Optional environment variables + command="uv", # Using uv to run the server + args=["run", "server", "completion", "stdio"], # Server with completion support + env={"UV_INDEX": os.environ.get("UV_INDEX", "")}, ) -# Optional: create a sampling callback -async def handle_sampling_message( - message: types.CreateMessageRequestParams, -) -> types.CreateMessageResult: - return types.CreateMessageResult( - role="assistant", - content=types.TextContent( - type="text", - text="Hello, world! from model", - ), - model="gpt-3.5-turbo", - stopReason="endTurn", - ) - - async def run(): + """Run the completion client example.""" async with stdio_client(server_params) as (read, write): - async with ClientSession( - read, write, sampling_callback=handle_sampling_message - ) as session: + async with ClientSession(read, write) as session: # Initialize the connection await session.initialize() + # List available resource templates + templates = await session.list_resource_templates() + print("Available resource templates:") + for template in templates.resourceTemplates: + print(f" - {template.uriTemplate}") + # List available prompts prompts = await session.list_prompts() + print("\nAvailable prompts:") + for prompt in prompts.prompts: + print(f" - {prompt.name}") + + # Complete resource template arguments + if templates.resourceTemplates: + template = templates.resourceTemplates[0] + print(f"\nCompleting arguments for resource template: {template.uriTemplate}") + + # Complete without context + result = await session.complete( + ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate), + argument={"name": "owner", "value": "model"}, + ) + print(f"Completions for 'owner' starting with 'model': {result.completion.values}") + + # Complete with context - repo suggestions based on owner + result = await session.complete( + ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate), + argument={"name": "repo", "value": ""}, + context_arguments={"owner": "modelcontextprotocol"}, + ) + print(f"Completions for 'repo' with owner='modelcontextprotocol': {result.completion.values}") + + # Complete prompt arguments + if prompts.prompts: + prompt_name = prompts.prompts[0].name + print(f"\nCompleting arguments for prompt: {prompt_name}") + + result = await session.complete( + ref=PromptReference(type="ref/prompt", name=prompt_name), + argument={"name": "style", "value": ""}, + ) + print(f"Completions for 'style' argument: {result.completion.values}") + + +def main(): + """Entry point for the completion client.""" + asyncio.run(run()) + + +if __name__ == "__main__": + main() +``` + +_Full example: [examples/snippets/clients/completion_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/completion_client.py)_ + +### Elicitation + +Request additional information from users. This example shows an Elicitation during a Tool Call: + + +```python +from pydantic import BaseModel, Field + +from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession + +mcp = FastMCP(name="Elicitation Example") + + +class BookingPreferences(BaseModel): + """Schema for collecting user preferences.""" + + checkAlternative: bool = Field(description="Would you like to check another date?") + alternativeDate: str = Field( + default="2024-12-26", + description="Alternative date (YYYY-MM-DD)", + ) + + +@mcp.tool() +async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerSession, None]) -> str: + """Book a table with date availability check.""" + # Check if date is available + if date == "2024-12-25": + # Date unavailable - ask user for alternative + result = await ctx.elicit( + message=(f"No tables available for {party_size} on {date}. Would you like to try another date?"), + schema=BookingPreferences, + ) + + if result.action == "accept" and result.data: + if result.data.checkAlternative: + return f"[SUCCESS] Booked for {result.data.alternativeDate}" + return "[CANCELLED] No booking made" + return "[CANCELLED] Booking cancelled" + + # Date available + return f"[SUCCESS] Booked for {date} at {time}" +``` + +_Full example: [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)_ + + +Elicitation schemas support default values for all field types. Default values are automatically included in the JSON schema sent to clients, allowing them to pre-populate forms. + +The `elicit()` method returns an `ElicitationResult` with: + +- `action`: "accept", "decline", or "cancel" +- `data`: The validated response (only when accepted) +- `validation_error`: Any validation error message + +### Sampling + +Tools can interact with LLMs through sampling (generating text): + + +```python +from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession +from mcp.types import SamplingMessage, TextContent + +mcp = FastMCP(name="Sampling Example") + + +@mcp.tool() +async def generate_poem(topic: str, ctx: Context[ServerSession, None]) -> str: + """Generate a poem using LLM sampling.""" + prompt = f"Write a short poem about {topic}" + + result = await ctx.session.create_message( + messages=[ + SamplingMessage( + role="user", + content=TextContent(type="text", text=prompt), + ) + ], + max_tokens=100, + ) + + if result.content.type == "text": + return result.content.text + return str(result.content) +``` + +_Full example: [examples/snippets/servers/sampling.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/sampling.py)_ + + +### Logging and Notifications + +Tools can send logs and notifications through the context: + + +```python +from mcp.server.fastmcp import Context, FastMCP +from mcp.server.session import ServerSession + +mcp = FastMCP(name="Notifications Example") + + +@mcp.tool() +async def process_data(data: str, ctx: Context[ServerSession, None]) -> str: + """Process data with logging.""" + # Different log levels + await ctx.debug(f"Debug: Processing '{data}'") + await ctx.info("Info: Starting processing") + await ctx.warning("Warning: This is experimental") + await ctx.error("Error: (This is just a demo)") + + # Notify about resource changes + await ctx.session.send_resource_list_changed() + + return f"Processed: {data}" +``` + +_Full example: [examples/snippets/servers/notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/notifications.py)_ + + +### Authentication + +Authentication can be used by servers that want to expose tools accessing protected resources. + +`mcp.server.auth` implements OAuth 2.1 resource server functionality, where MCP servers act as Resource Servers (RS) that validate tokens issued by separate Authorization Servers (AS). This follows the [MCP authorization specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) and implements RFC 9728 (Protected Resource Metadata) for AS discovery. + +MCP servers can use authentication by providing an implementation of the `TokenVerifier` protocol: + + +```python +""" +Run from the repository root: + uv run examples/snippets/servers/oauth_server.py +""" + +from pydantic import AnyHttpUrl + +from mcp.server.auth.provider import AccessToken, TokenVerifier +from mcp.server.auth.settings import AuthSettings +from mcp.server.fastmcp import FastMCP + + +class SimpleTokenVerifier(TokenVerifier): + """Simple token verifier for demonstration.""" + + async def verify_token(self, token: str) -> AccessToken | None: + pass # This is where you would implement actual token validation + + +# Create FastMCP instance as a Resource Server +mcp = FastMCP( + "Weather Service", + # Token verifier for authentication + token_verifier=SimpleTokenVerifier(), + # Auth settings for RFC 9728 Protected Resource Metadata + auth=AuthSettings( + issuer_url=AnyHttpUrl("https://auth.example.com"), # Authorization Server URL + resource_server_url=AnyHttpUrl("http://localhost:3001"), # This server's URL + required_scopes=["user"], + ), +) + + +@mcp.tool() +async def get_weather(city: str = "London") -> dict[str, str]: + """Get weather data for a city""" + return { + "city": city, + "temperature": "22", + "condition": "Partly cloudy", + "humidity": "65%", + } + + +if __name__ == "__main__": + mcp.run(transport="streamable-http") +``` + +_Full example: [examples/snippets/servers/oauth_server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/oauth_server.py)_ + + +For a complete example with separate Authorization Server and Resource Server implementations, see [`examples/servers/simple-auth/`](examples/servers/simple-auth/). + +**Architecture:** + +- **Authorization Server (AS)**: Handles OAuth flows, user authentication, and token issuance +- **Resource Server (RS)**: Your MCP server that validates tokens and serves protected resources +- **Client**: Discovers AS through RFC 9728, obtains tokens, and uses them with the MCP server + +See [TokenVerifier](src/mcp/server/auth/provider.py) for more details on implementing token validation. + +### FastMCP Properties + +The FastMCP server instance accessible via `ctx.fastmcp` provides access to server configuration and metadata: + +- `ctx.fastmcp.name` - The server's name as defined during initialization +- `ctx.fastmcp.instructions` - Server instructions/description provided to clients +- `ctx.fastmcp.website_url` - Optional website URL for the server +- `ctx.fastmcp.icons` - Optional list of icons for UI display +- `ctx.fastmcp.settings` - Complete server configuration object containing: + - `debug` - Debug mode flag + - `log_level` - Current logging level + - `host` and `port` - Server network configuration + - `mount_path`, `sse_path`, `streamable_http_path` - Transport paths + - `stateless_http` - Whether the server operates in stateless mode + - And other configuration options + +```python +@mcp.tool() +def server_info(ctx: Context) -> dict: + """Get information about the current server.""" + return { + "name": ctx.fastmcp.name, + "instructions": ctx.fastmcp.instructions, + "debug_mode": ctx.fastmcp.settings.debug, + "log_level": ctx.fastmcp.settings.log_level, + "host": ctx.fastmcp.settings.host, + "port": ctx.fastmcp.settings.port, + } +``` + +### Session Properties and Methods + +The session object accessible via `ctx.session` provides advanced control over client communication: + +- `ctx.session.client_params` - Client initialization parameters and declared capabilities +- `await ctx.session.send_log_message(level, data, logger)` - Send log messages with full control +- `await ctx.session.create_message(messages, max_tokens)` - Request LLM sampling/completion +- `await ctx.session.send_progress_notification(token, progress, total, message)` - Direct progress updates +- `await ctx.session.send_resource_updated(uri)` - Notify clients that a specific resource changed +- `await ctx.session.send_resource_list_changed()` - Notify clients that the resource list changed +- `await ctx.session.send_tool_list_changed()` - Notify clients that the tool list changed +- `await ctx.session.send_prompt_list_changed()` - Notify clients that the prompt list changed + +```python +@mcp.tool() +async def notify_data_update(resource_uri: str, ctx: Context) -> str: + """Update data and notify clients of the change.""" + # Perform data update logic here + + # Notify clients that this specific resource changed + await ctx.session.send_resource_updated(AnyUrl(resource_uri)) + + # If this affects the overall resource list, notify about that too + await ctx.session.send_resource_list_changed() + + return f"Updated {resource_uri} and notified clients" +``` + +### Request Context Properties + +The request context accessible via `ctx.request_context` contains request-specific information and resources: + +- `ctx.request_context.lifespan_context` - Access to resources initialized during server startup + - Database connections, configuration objects, shared services + - Type-safe access to resources defined in your server's lifespan function +- `ctx.request_context.meta` - Request metadata from the client including: + - `progressToken` - Token for progress notifications + - Other client-provided metadata +- `ctx.request_context.request` - The original MCP request object for advanced processing +- `ctx.request_context.request_id` - Unique identifier for this request + +```python +# Example with typed lifespan context +@dataclass +class AppContext: + db: Database + config: AppConfig + +@mcp.tool() +def query_with_config(query: str, ctx: Context) -> str: + """Execute a query using shared database and configuration.""" + # Access typed lifespan context + app_ctx: AppContext = ctx.request_context.lifespan_context + + # Use shared resources + connection = app_ctx.db + settings = app_ctx.config + + # Execute query with configuration + result = connection.execute(query, timeout=settings.query_timeout) + return str(result) +``` + +_Full lifespan example: [examples/snippets/servers/lifespan_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lifespan_example.py)_ + +## Running Your Server + +### Development Mode + +The fastest way to test and debug your server is with the MCP Inspector: + +```bash +uv run mcp dev server.py + +# Add dependencies +uv run mcp dev server.py --with pandas --with numpy + +# Mount local code +uv run mcp dev server.py --with-editable . +``` + +### Claude Desktop Integration + +Once your server is ready, install it in Claude Desktop: + +```bash +uv run mcp install server.py + +# Custom name +uv run mcp install server.py --name "My Analytics Server" + +# Environment variables +uv run mcp install server.py -v API_KEY=abc123 -v DB_URL=postgres://... +uv run mcp install server.py -f .env +``` + +### Direct Execution + +For advanced scenarios like custom deployments: + + +```python +"""Example showing direct execution of an MCP server. + +This is the simplest way to run an MCP server directly. +cd to the `examples/snippets` directory and run: + uv run direct-execution-server + or + python servers/direct_execution.py +""" + +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP("My App") + + +@mcp.tool() +def hello(name: str = "World") -> str: + """Say hello to someone.""" + return f"Hello, {name}!" + + +def main(): + """Entry point for the direct execution server.""" + mcp.run() + + +if __name__ == "__main__": + main() +``` + +_Full example: [examples/snippets/servers/direct_execution.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/direct_execution.py)_ + + +Run it with: + +```bash +python servers/direct_execution.py +# or +uv run mcp run servers/direct_execution.py +``` + +Note that `uv run mcp run` or `uv run mcp dev` only supports server using FastMCP and not the low-level server variant. + +### Streamable HTTP Transport + +> **Note**: Streamable HTTP transport is superseding SSE transport for production deployments. + + +```python +""" +Run from the repository root: + uv run examples/snippets/servers/streamable_config.py +""" + +from mcp.server.fastmcp import FastMCP + +# Stateful server (maintains session state) +mcp = FastMCP("StatefulServer") + +# Other configuration options: +# Stateless server (no session persistence) +# mcp = FastMCP("StatelessServer", stateless_http=True) + +# Stateless server (no session persistence, no sse stream with supported client) +# mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True) + + +# Add a simple tool to demonstrate the server +@mcp.tool() +def greet(name: str = "World") -> str: + """Greet someone by name.""" + return f"Hello, {name}!" + + +# Run server with streamable_http transport +if __name__ == "__main__": + mcp.run(transport="streamable-http") +``` + +_Full example: [examples/snippets/servers/streamable_config.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_config.py)_ + + +You can mount multiple FastMCP servers in a Starlette application: + + +```python +""" +Run from the repository root: + uvicorn examples.snippets.servers.streamable_starlette_mount:app --reload +""" + +import contextlib + +from starlette.applications import Starlette +from starlette.routing import Mount + +from mcp.server.fastmcp import FastMCP + +# Create the Echo server +echo_mcp = FastMCP(name="EchoServer", stateless_http=True) + + +@echo_mcp.tool() +def echo(message: str) -> str: + """A simple echo tool""" + return f"Echo: {message}" + + +# Create the Math server +math_mcp = FastMCP(name="MathServer", stateless_http=True) + + +@math_mcp.tool() +def add_two(n: int) -> int: + """Tool to add two to the input""" + return n + 2 + + +# Create a combined lifespan to manage both session managers +@contextlib.asynccontextmanager +async def lifespan(app: Starlette): + async with contextlib.AsyncExitStack() as stack: + await stack.enter_async_context(echo_mcp.session_manager.run()) + await stack.enter_async_context(math_mcp.session_manager.run()) + yield + + +# Create the Starlette app and mount the MCP servers +app = Starlette( + routes=[ + Mount("/echo", echo_mcp.streamable_http_app()), + Mount("/math", math_mcp.streamable_http_app()), + ], + lifespan=lifespan, +) + +# Note: Clients connect to http://localhost:8000/echo/mcp and http://localhost:8000/math/mcp +# To mount at the root of each path (e.g., /echo instead of /echo/mcp): +# echo_mcp.settings.streamable_http_path = "/" +# math_mcp.settings.streamable_http_path = "/" +``` + +_Full example: [examples/snippets/servers/streamable_starlette_mount.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_starlette_mount.py)_ + + +For low level server with Streamable HTTP implementations, see: + +- Stateful server: [`examples/servers/simple-streamablehttp/`](examples/servers/simple-streamablehttp/) +- Stateless server: [`examples/servers/simple-streamablehttp-stateless/`](examples/servers/simple-streamablehttp-stateless/) + +The streamable HTTP transport supports: + +- Stateful and stateless operation modes +- Resumability with event stores +- JSON or SSE response formats +- Better scalability for multi-node deployments + +#### CORS Configuration for Browser-Based Clients + +If you'd like your server to be accessible by browser-based MCP clients, you'll need to configure CORS headers. The `Mcp-Session-Id` header must be exposed for browser clients to access it: + +```python +from starlette.applications import Starlette +from starlette.middleware.cors import CORSMiddleware + +# Create your Starlette app first +starlette_app = Starlette(routes=[...]) + +# Then wrap it with CORS middleware +starlette_app = CORSMiddleware( + starlette_app, + allow_origins=["*"], # Configure appropriately for production + allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods + expose_headers=["Mcp-Session-Id"], +) +``` + +This configuration is necessary because: + +- The MCP streamable HTTP transport uses the `Mcp-Session-Id` header for session management +- Browsers restrict access to response headers unless explicitly exposed via CORS +- Without this configuration, browser-based clients won't be able to read the session ID from initialization responses + +### Mounting to an Existing ASGI Server + +By default, SSE servers are mounted at `/sse` and Streamable HTTP servers are mounted at `/mcp`. You can customize these paths using the methods described below. + +For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes). + +#### StreamableHTTP servers + +You can mount the StreamableHTTP server to an existing ASGI server using the `streamable_http_app` method. This allows you to integrate the StreamableHTTP server with other ASGI applications. + +##### Basic mounting + + +```python +""" +Basic example showing how to mount StreamableHTTP server in Starlette. + +Run from the repository root: + uvicorn examples.snippets.servers.streamable_http_basic_mounting:app --reload +""" + +from starlette.applications import Starlette +from starlette.routing import Mount + +from mcp.server.fastmcp import FastMCP + +# Create MCP server +mcp = FastMCP("My App") + + +@mcp.tool() +def hello() -> str: + """A simple hello tool""" + return "Hello from MCP!" + + +# Mount the StreamableHTTP server to the existing ASGI server +app = Starlette( + routes=[ + Mount("/", app=mcp.streamable_http_app()), + ] +) +``` + +_Full example: [examples/snippets/servers/streamable_http_basic_mounting.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_http_basic_mounting.py)_ + + +##### Host-based routing + + +```python +""" +Example showing how to mount StreamableHTTP server using Host-based routing. + +Run from the repository root: + uvicorn examples.snippets.servers.streamable_http_host_mounting:app --reload +""" + +from starlette.applications import Starlette +from starlette.routing import Host + +from mcp.server.fastmcp import FastMCP + +# Create MCP server +mcp = FastMCP("MCP Host App") + + +@mcp.tool() +def domain_info() -> str: + """Get domain-specific information""" + return "This is served from mcp.acme.corp" + + +# Mount using Host-based routing +app = Starlette( + routes=[ + Host("mcp.acme.corp", app=mcp.streamable_http_app()), + ] +) +``` + +_Full example: [examples/snippets/servers/streamable_http_host_mounting.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_http_host_mounting.py)_ + + +##### Multiple servers with path configuration + + +```python +""" +Example showing how to mount multiple StreamableHTTP servers with path configuration. + +Run from the repository root: + uvicorn examples.snippets.servers.streamable_http_multiple_servers:app --reload +""" + +from starlette.applications import Starlette +from starlette.routing import Mount + +from mcp.server.fastmcp import FastMCP + +# Create multiple MCP servers +api_mcp = FastMCP("API Server") +chat_mcp = FastMCP("Chat Server") + + +@api_mcp.tool() +def api_status() -> str: + """Get API status""" + return "API is running" + + +@chat_mcp.tool() +def send_message(message: str) -> str: + """Send a chat message""" + return f"Message sent: {message}" + + +# Configure servers to mount at the root of each path +# This means endpoints will be at /api and /chat instead of /api/mcp and /chat/mcp +api_mcp.settings.streamable_http_path = "/" +chat_mcp.settings.streamable_http_path = "/" + +# Mount the servers +app = Starlette( + routes=[ + Mount("/api", app=api_mcp.streamable_http_app()), + Mount("/chat", app=chat_mcp.streamable_http_app()), + ] +) +``` + +_Full example: [examples/snippets/servers/streamable_http_multiple_servers.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_http_multiple_servers.py)_ + + +##### Path configuration at initialization + + +```python +""" +Example showing path configuration during FastMCP initialization. + +Run from the repository root: + uvicorn examples.snippets.servers.streamable_http_path_config:app --reload +""" + +from starlette.applications import Starlette +from starlette.routing import Mount + +from mcp.server.fastmcp import FastMCP + +# Configure streamable_http_path during initialization +# This server will mount at the root of wherever it's mounted +mcp_at_root = FastMCP("My Server", streamable_http_path="/") + + +@mcp_at_root.tool() +def process_data(data: str) -> str: + """Process some data""" + return f"Processed: {data}" + + +# Mount at /process - endpoints will be at /process instead of /process/mcp +app = Starlette( + routes=[ + Mount("/process", app=mcp_at_root.streamable_http_app()), + ] +) +``` + +_Full example: [examples/snippets/servers/streamable_http_path_config.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_http_path_config.py)_ + + +#### SSE servers + +> **Note**: SSE transport is being superseded by [Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http). + +You can mount the SSE server to an existing ASGI server using the `sse_app` method. This allows you to integrate the SSE server with other ASGI applications. + +```python +from starlette.applications import Starlette +from starlette.routing import Mount, Host +from mcp.server.fastmcp import FastMCP + + +mcp = FastMCP("My App") + +# Mount the SSE server to the existing ASGI server +app = Starlette( + routes=[ + Mount('/', app=mcp.sse_app()), + ] +) + +# or dynamically mount as host +app.router.routes.append(Host('mcp.acme.corp', app=mcp.sse_app())) +``` + +When mounting multiple MCP servers under different paths, you can configure the mount path in several ways: + +```python +from starlette.applications import Starlette +from starlette.routing import Mount +from mcp.server.fastmcp import FastMCP + +# Create multiple MCP servers +github_mcp = FastMCP("GitHub API") +browser_mcp = FastMCP("Browser") +curl_mcp = FastMCP("Curl") +search_mcp = FastMCP("Search") + +# Method 1: Configure mount paths via settings (recommended for persistent configuration) +github_mcp.settings.mount_path = "/github" +browser_mcp.settings.mount_path = "/browser" + +# Method 2: Pass mount path directly to sse_app (preferred for ad-hoc mounting) +# This approach doesn't modify the server's settings permanently + +# Create Starlette app with multiple mounted servers +app = Starlette( + routes=[ + # Using settings-based configuration + Mount("/github", app=github_mcp.sse_app()), + Mount("/browser", app=browser_mcp.sse_app()), + # Using direct mount path parameter + Mount("/curl", app=curl_mcp.sse_app("/curl")), + Mount("/search", app=search_mcp.sse_app("/search")), + ] +) + +# Method 3: For direct execution, you can also pass the mount path to run() +if __name__ == "__main__": + search_mcp.run(transport="sse", mount_path="/search") +``` + +For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes). + +## Advanced Usage + +### Low-Level Server + +For more control, you can use the low-level server implementation directly. This gives you full access to the protocol and allows you to customize every aspect of your server, including lifecycle management through the lifespan API: + + +```python +""" +Run from the repository root: + uv run examples/snippets/servers/lowlevel/lifespan.py +""" + +from collections.abc import AsyncIterator +from contextlib import asynccontextmanager +from typing import Any + +import mcp.server.stdio +import mcp.types as types +from mcp.server.lowlevel import NotificationOptions, Server +from mcp.server.models import InitializationOptions + + +# Mock database class for example +class Database: + """Mock database class for example.""" + + @classmethod + async def connect(cls) -> "Database": + """Connect to database.""" + print("Database connected") + return cls() + + async def disconnect(self) -> None: + """Disconnect from database.""" + print("Database disconnected") + + async def query(self, query_str: str) -> list[dict[str, str]]: + """Execute a query.""" + # Simulate database query + return [{"id": "1", "name": "Example", "query": query_str}] + + +@asynccontextmanager +async def server_lifespan(_server: Server) -> AsyncIterator[dict[str, Any]]: + """Manage server startup and shutdown lifecycle.""" + # Initialize resources on startup + db = await Database.connect() + try: + yield {"db": db} + finally: + # Clean up on shutdown + await db.disconnect() + + +# Pass lifespan to server +server = Server("example-server", lifespan=server_lifespan) + + +@server.list_tools() +async def handle_list_tools() -> list[types.Tool]: + """List available tools.""" + return [ + types.Tool( + name="query_db", + description="Query the database", + inputSchema={ + "type": "object", + "properties": {"query": {"type": "string", "description": "SQL query to execute"}}, + "required": ["query"], + }, + ) + ] + + +@server.call_tool() +async def query_db(name: str, arguments: dict[str, Any]) -> list[types.TextContent]: + """Handle database query tool call.""" + if name != "query_db": + raise ValueError(f"Unknown tool: {name}") + + # Access lifespan context + ctx = server.request_context + db = ctx.lifespan_context["db"] + + # Execute query + results = await db.query(arguments["query"]) + + return [types.TextContent(type="text", text=f"Query results: {results}")] + + +async def run(): + """Run the server with lifespan management.""" + async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): + await server.run( + read_stream, + write_stream, + InitializationOptions( + server_name="example-server", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ), + ), + ) + + +if __name__ == "__main__": + import asyncio + + asyncio.run(run()) +``` + +_Full example: [examples/snippets/servers/lowlevel/lifespan.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/lifespan.py)_ + + +The lifespan API provides: + +- A way to initialize resources when the server starts and clean them up when it stops +- Access to initialized resources through the request context in handlers +- Type-safe context passing between lifespan and request handlers + + +```python +""" +Run from the repository root: +uv run examples/snippets/servers/lowlevel/basic.py +""" + +import asyncio + +import mcp.server.stdio +import mcp.types as types +from mcp.server.lowlevel import NotificationOptions, Server +from mcp.server.models import InitializationOptions + +# Create a server instance +server = Server("example-server") + + +@server.list_prompts() +async def handle_list_prompts() -> list[types.Prompt]: + """List available prompts.""" + return [ + types.Prompt( + name="example-prompt", + description="An example prompt template", + arguments=[types.PromptArgument(name="arg1", description="Example argument", required=True)], + ) + ] + + +@server.get_prompt() +async def handle_get_prompt(name: str, arguments: dict[str, str] | None) -> types.GetPromptResult: + """Get a specific prompt by name.""" + if name != "example-prompt": + raise ValueError(f"Unknown prompt: {name}") + + arg1_value = (arguments or {}).get("arg1", "default") + + return types.GetPromptResult( + description="Example prompt", + messages=[ + types.PromptMessage( + role="user", + content=types.TextContent(type="text", text=f"Example prompt text with argument: {arg1_value}"), + ) + ], + ) + + +async def run(): + """Run the basic low-level server.""" + async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): + await server.run( + read_stream, + write_stream, + InitializationOptions( + server_name="example", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ), + ), + ) + + +if __name__ == "__main__": + asyncio.run(run()) +``` + +_Full example: [examples/snippets/servers/lowlevel/basic.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/basic.py)_ + + +Caution: The `uv run mcp run` and `uv run mcp dev` tool doesn't support low-level server. + +#### Structured Output Support + +The low-level server supports structured output for tools, allowing you to return both human-readable content and machine-readable structured data. Tools can define an `outputSchema` to validate their structured output: + + +```python +""" +Run from the repository root: + uv run examples/snippets/servers/lowlevel/structured_output.py +""" + +import asyncio +from typing import Any + +import mcp.server.stdio +import mcp.types as types +from mcp.server.lowlevel import NotificationOptions, Server +from mcp.server.models import InitializationOptions + +server = Server("example-server") + + +@server.list_tools() +async def list_tools() -> list[types.Tool]: + """List available tools with structured output schemas.""" + return [ + types.Tool( + name="get_weather", + description="Get current weather for a city", + inputSchema={ + "type": "object", + "properties": {"city": {"type": "string", "description": "City name"}}, + "required": ["city"], + }, + outputSchema={ + "type": "object", + "properties": { + "temperature": {"type": "number", "description": "Temperature in Celsius"}, + "condition": {"type": "string", "description": "Weather condition"}, + "humidity": {"type": "number", "description": "Humidity percentage"}, + "city": {"type": "string", "description": "City name"}, + }, + "required": ["temperature", "condition", "humidity", "city"], + }, + ) + ] + + +@server.call_tool() +async def call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]: + """Handle tool calls with structured output.""" + if name == "get_weather": + city = arguments["city"] + + # Simulated weather data - in production, call a weather API + weather_data = { + "temperature": 22.5, + "condition": "partly cloudy", + "humidity": 65, + "city": city, # Include the requested city + } + + # low-level server will validate structured output against the tool's + # output schema, and additionally serialize it into a TextContent block + # for backwards compatibility with pre-2025-06-18 clients. + return weather_data + else: + raise ValueError(f"Unknown tool: {name}") - # Get a prompt - prompt = await session.get_prompt( - "example-prompt", arguments={"arg1": "value"} - ) + +async def run(): + """Run the structured output server.""" + async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): + await server.run( + read_stream, + write_stream, + InitializationOptions( + server_name="structured-output-example", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ), + ), + ) + + +if __name__ == "__main__": + asyncio.run(run()) +``` + +_Full example: [examples/snippets/servers/lowlevel/structured_output.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/structured_output.py)_ + + +Tools can return data in four ways: + +1. **Content only**: Return a list of content blocks (default behavior before spec revision 2025-06-18) +2. **Structured data only**: Return a dictionary that will be serialized to JSON (Introduced in spec revision 2025-06-18) +3. **Both**: Return a tuple of (content, structured_data) preferred option to use for backwards compatibility +4. **Direct CallToolResult**: Return `CallToolResult` directly for full control (including `_meta` field) + +When an `outputSchema` is defined, the server automatically validates the structured output against the schema. This ensures type safety and helps catch errors early. + +##### Returning CallToolResult Directly + +For full control over the response including the `_meta` field (for passing data to client applications without exposing it to the model), return `CallToolResult` directly: + + +```python +""" +Run from the repository root: + uv run examples/snippets/servers/lowlevel/direct_call_tool_result.py +""" + +import asyncio +from typing import Any + +import mcp.server.stdio +import mcp.types as types +from mcp.server.lowlevel import NotificationOptions, Server +from mcp.server.models import InitializationOptions + +server = Server("example-server") + + +@server.list_tools() +async def list_tools() -> list[types.Tool]: + """List available tools.""" + return [ + types.Tool( + name="advanced_tool", + description="Tool with full control including _meta field", + inputSchema={ + "type": "object", + "properties": {"message": {"type": "string"}}, + "required": ["message"], + }, + ) + ] + + +@server.call_tool() +async def handle_call_tool(name: str, arguments: dict[str, Any]) -> types.CallToolResult: + """Handle tool calls by returning CallToolResult directly.""" + if name == "advanced_tool": + message = str(arguments.get("message", "")) + return types.CallToolResult( + content=[types.TextContent(type="text", text=f"Processed: {message}")], + structuredContent={"result": "success", "message": message}, + _meta={"hidden": "data for client applications only"}, + ) + + raise ValueError(f"Unknown tool: {name}") + + +async def run(): + """Run the server.""" + async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): + await server.run( + read_stream, + write_stream, + InitializationOptions( + server_name="example", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ), + ), + ) + + +if __name__ == "__main__": + asyncio.run(run()) +``` + +_Full example: [examples/snippets/servers/lowlevel/direct_call_tool_result.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/direct_call_tool_result.py)_ + + +**Note:** When returning `CallToolResult`, you bypass the automatic content/structured conversion. You must construct the complete response yourself. + +### Pagination (Advanced) + +For servers that need to handle large datasets, the low-level server provides paginated versions of list operations. This is an optional optimization - most servers won't need pagination unless they're dealing with hundreds or thousands of items. + +#### Server-side Implementation + + +```python +""" +Example of implementing pagination with MCP server decorators. +""" + +from pydantic import AnyUrl + +import mcp.types as types +from mcp.server.lowlevel import Server + +# Initialize the server +server = Server("paginated-server") + +# Sample data to paginate +ITEMS = [f"Item {i}" for i in range(1, 101)] # 100 items + + +@server.list_resources() +async def list_resources_paginated(request: types.ListResourcesRequest) -> types.ListResourcesResult: + """List resources with pagination support.""" + page_size = 10 + + # Extract cursor from request params + cursor = request.params.cursor if request.params is not None else None + + # Parse cursor to get offset + start = 0 if cursor is None else int(cursor) + end = start + page_size + + # Get page of resources + page_items = [ + types.Resource(uri=AnyUrl(f"resource://items/{item}"), name=item, description=f"Description for {item}") + for item in ITEMS[start:end] + ] + + # Determine next cursor + next_cursor = str(end) if end < len(ITEMS) else None + + return types.ListResourcesResult(resources=page_items, nextCursor=next_cursor) +``` + +_Full example: [examples/snippets/servers/pagination_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/pagination_example.py)_ + + +#### Client-side Consumption + + +```python +""" +Example of consuming paginated MCP endpoints from a client. +""" + +import asyncio + +from mcp.client.session import ClientSession +from mcp.client.stdio import StdioServerParameters, stdio_client +from mcp.types import PaginatedRequestParams, Resource + + +async def list_all_resources() -> None: + """Fetch all resources using pagination.""" + async with stdio_client(StdioServerParameters(command="uv", args=["run", "mcp-simple-pagination"])) as ( + read, + write, + ): + async with ClientSession(read, write) as session: + await session.initialize() + + all_resources: list[Resource] = [] + cursor = None + + while True: + # Fetch a page of resources + result = await session.list_resources(params=PaginatedRequestParams(cursor=cursor)) + all_resources.extend(result.resources) + + print(f"Fetched {len(result.resources)} resources") + + # Check if there are more pages + if result.nextCursor: + cursor = result.nextCursor + else: + break + + print(f"Total resources: {len(all_resources)}") + + +if __name__ == "__main__": + asyncio.run(list_all_resources()) +``` + +_Full example: [examples/snippets/clients/pagination_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/pagination_client.py)_ + + +#### Key Points + +- **Cursors are opaque strings** - the server defines the format (numeric offsets, timestamps, etc.) +- **Return `nextCursor=None`** when there are no more pages +- **Backward compatible** - clients that don't support pagination will still work (they'll just get the first page) +- **Flexible page sizes** - Each endpoint can define its own page size based on data characteristics + +See the [simple-pagination example](examples/servers/simple-pagination) for a complete implementation. + +### Writing MCP Clients + +The SDK provides a high-level client interface for connecting to MCP servers using various [transports](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports): + + +```python +""" +cd to the `examples/snippets/clients` directory and run: + uv run client +""" + +import asyncio +import os + +from pydantic import AnyUrl + +from mcp import ClientSession, StdioServerParameters, types +from mcp.client.stdio import stdio_client +from mcp.shared.context import RequestContext + +# Create server parameters for stdio connection +server_params = StdioServerParameters( + command="uv", # Using uv to run the server + args=["run", "server", "fastmcp_quickstart", "stdio"], # We're already in snippets dir + env={"UV_INDEX": os.environ.get("UV_INDEX", "")}, +) + + +# Optional: create a sampling callback +async def handle_sampling_message( + context: RequestContext[ClientSession, None], params: types.CreateMessageRequestParams +) -> types.CreateMessageResult: + print(f"Sampling request: {params.messages}") + return types.CreateMessageResult( + role="assistant", + content=types.TextContent( + type="text", + text="Hello, world! from model", + ), + model="gpt-3.5-turbo", + stopReason="endTurn", + ) + + +async def run(): + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write, sampling_callback=handle_sampling_message) as session: + # Initialize the connection + await session.initialize() + + # List available prompts + prompts = await session.list_prompts() + print(f"Available prompts: {[p.name for p in prompts.prompts]}") + + # Get a prompt (greet_user prompt from fastmcp_quickstart) + if prompts.prompts: + prompt = await session.get_prompt("greet_user", arguments={"name": "Alice", "style": "friendly"}) + print(f"Prompt result: {prompt.messages[0].content}") # List available resources resources = await session.list_resources() + print(f"Available resources: {[r.uri for r in resources.resources]}") # List available tools tools = await session.list_tools() + print(f"Available tools: {[t.name for t in tools.tools]}") - # Read a resource - content, mime_type = await session.read_resource("file://some/path") + # Read a resource (greeting resource from fastmcp_quickstart) + resource_content = await session.read_resource(AnyUrl("greeting://World")) + content_block = resource_content.contents[0] + if isinstance(content_block, types.TextContent): + print(f"Resource content: {content_block.text}") - # Call a tool - result = await session.call_tool("tool-name", arguments={"arg1": "value"}) + # Call a tool (add tool from fastmcp_quickstart) + result = await session.call_tool("add", arguments={"a": 5, "b": 3}) + result_unstructured = result.content[0] + if isinstance(result_unstructured, types.TextContent): + print(f"Tool result: {result_unstructured.text}") + result_structured = result.structuredContent + print(f"Structured tool result: {result_structured}") + + +def main(): + """Entry point for the client script.""" + asyncio.run(run()) if __name__ == "__main__": - import asyncio + main() +``` + +_Full example: [examples/snippets/clients/stdio_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/stdio_client.py)_ + + +Clients can also connect using [Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http): + + +```python +""" +Run from the repository root: + uv run examples/snippets/clients/streamable_basic.py +""" + +import asyncio + +from mcp import ClientSession +from mcp.client.streamable_http import streamablehttp_client + + +async def main(): + # Connect to a streamable HTTP server + async with streamablehttp_client("http://localhost:8000/mcp") as ( + read_stream, + write_stream, + _, + ): + # Create a session using the client streams + async with ClientSession(read_stream, write_stream) as session: + # Initialize the connection + await session.initialize() + # List available tools + tools = await session.list_tools() + print(f"Available tools: {[tool.name for tool in tools.tools]}") + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +_Full example: [examples/snippets/clients/streamable_basic.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py)_ + + +### Client Display Utilities + +When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts: + + +```python +""" +cd to the `examples/snippets` directory and run: + uv run display-utilities-client +""" + +import asyncio +import os + +from mcp import ClientSession, StdioServerParameters +from mcp.client.stdio import stdio_client +from mcp.shared.metadata_utils import get_display_name + +# Create server parameters for stdio connection +server_params = StdioServerParameters( + command="uv", # Using uv to run the server + args=["run", "server", "fastmcp_quickstart", "stdio"], + env={"UV_INDEX": os.environ.get("UV_INDEX", "")}, +) + + +async def display_tools(session: ClientSession): + """Display available tools with human-readable names""" + tools_response = await session.list_tools() + + for tool in tools_response.tools: + # get_display_name() returns the title if available, otherwise the name + display_name = get_display_name(tool) + print(f"Tool: {display_name}") + if tool.description: + print(f" {tool.description}") + + +async def display_resources(session: ClientSession): + """Display available resources with human-readable names""" + resources_response = await session.list_resources() + + for resource in resources_response.resources: + display_name = get_display_name(resource) + print(f"Resource: {display_name} ({resource.uri})") + + templates_response = await session.list_resource_templates() + for template in templates_response.resourceTemplates: + display_name = get_display_name(template) + print(f"Resource Template: {display_name}") + + +async def run(): + """Run the display utilities example.""" + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write) as session: + # Initialize the connection + await session.initialize() + + print("=== Available Tools ===") + await display_tools(session) + + print("\n=== Available Resources ===") + await display_resources(session) + +def main(): + """Entry point for the display utilities client.""" asyncio.run(run()) + + +if __name__ == "__main__": + main() +``` + +_Full example: [examples/snippets/clients/display_utilities.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/display_utilities.py)_ + + +The `get_display_name()` function implements the proper precedence rules for displaying names: + +- For tools: `title` > `annotations.title` > `name` +- For other objects: `title` > `name` + +This ensures your client UI shows the most user-friendly names that servers provide. + +### OAuth Authentication for Clients + +The SDK includes [authorization support](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for connecting to protected MCP servers: + + +```python +""" +Before running, specify running MCP RS server URL. +To spin up RS server locally, see + examples/servers/simple-auth/README.md + +cd to the `examples/snippets` directory and run: + uv run oauth-client +""" + +import asyncio +from urllib.parse import parse_qs, urlparse + +from pydantic import AnyUrl + +from mcp import ClientSession +from mcp.client.auth import OAuthClientProvider, TokenStorage +from mcp.client.streamable_http import streamablehttp_client +from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken + + +class InMemoryTokenStorage(TokenStorage): + """Demo In-memory token storage implementation.""" + + def __init__(self): + self.tokens: OAuthToken | None = None + self.client_info: OAuthClientInformationFull | None = None + + async def get_tokens(self) -> OAuthToken | None: + """Get stored tokens.""" + return self.tokens + + async def set_tokens(self, tokens: OAuthToken) -> None: + """Store tokens.""" + self.tokens = tokens + + async def get_client_info(self) -> OAuthClientInformationFull | None: + """Get stored client information.""" + return self.client_info + + async def set_client_info(self, client_info: OAuthClientInformationFull) -> None: + """Store client information.""" + self.client_info = client_info + + +async def handle_redirect(auth_url: str) -> None: + print(f"Visit: {auth_url}") + + +async def handle_callback() -> tuple[str, str | None]: + callback_url = input("Paste callback URL: ") + params = parse_qs(urlparse(callback_url).query) + return params["code"][0], params.get("state", [None])[0] + + +async def main(): + """Run the OAuth client example.""" + oauth_auth = OAuthClientProvider( + server_url="http://localhost:8001", + client_metadata=OAuthClientMetadata( + client_name="Example MCP Client", + redirect_uris=[AnyUrl("http://localhost:3000/callback")], + grant_types=["authorization_code", "refresh_token"], + response_types=["code"], + scope="user", + ), + storage=InMemoryTokenStorage(), + redirect_handler=handle_redirect, + callback_handler=handle_callback, + ) + + async with streamablehttp_client("http://localhost:8001/mcp", auth=oauth_auth) as (read, write, _): + async with ClientSession(read, write) as session: + await session.initialize() + + tools = await session.list_tools() + print(f"Available tools: {[tool.name for tool in tools.tools]}") + + resources = await session.list_resources() + print(f"Available resources: {[r.uri for r in resources.resources]}") + + +def run(): + asyncio.run(main()) + + +if __name__ == "__main__": + run() +``` + +_Full example: [examples/snippets/clients/oauth_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/oauth_client.py)_ + + +For a complete working example, see [`examples/clients/simple-auth-client/`](examples/clients/simple-auth-client/). + +### Parsing Tool Results + +When calling tools through MCP, the `CallToolResult` object contains the tool's response in a structured format. Understanding how to parse this result is essential for properly handling tool outputs. + +```python +"""examples/snippets/clients/parsing_tool_results.py""" + +import asyncio + +from mcp import ClientSession, StdioServerParameters, types +from mcp.client.stdio import stdio_client + + +async def parse_tool_results(): + """Demonstrates how to parse different types of content in CallToolResult.""" + server_params = StdioServerParameters( + command="python", args=["path/to/mcp_server.py"] + ) + + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write) as session: + await session.initialize() + + # Example 1: Parsing text content + result = await session.call_tool("get_data", {"format": "text"}) + for content in result.content: + if isinstance(content, types.TextContent): + print(f"Text: {content.text}") + + # Example 2: Parsing structured content from JSON tools + result = await session.call_tool("get_user", {"id": "123"}) + if hasattr(result, "structuredContent") and result.structuredContent: + # Access structured data directly + user_data = result.structuredContent + print(f"User: {user_data.get('name')}, Age: {user_data.get('age')}") + + # Example 3: Parsing embedded resources + result = await session.call_tool("read_config", {}) + for content in result.content: + if isinstance(content, types.EmbeddedResource): + resource = content.resource + if isinstance(resource, types.TextResourceContents): + print(f"Config from {resource.uri}: {resource.text}") + elif isinstance(resource, types.BlobResourceContents): + print(f"Binary data from {resource.uri}") + + # Example 4: Parsing image content + result = await session.call_tool("generate_chart", {"data": [1, 2, 3]}) + for content in result.content: + if isinstance(content, types.ImageContent): + print(f"Image ({content.mimeType}): {len(content.data)} bytes") + + # Example 5: Handling errors + result = await session.call_tool("failing_tool", {}) + if result.isError: + print("Tool execution failed!") + for content in result.content: + if isinstance(content, types.TextContent): + print(f"Error: {content.text}") + + +async def main(): + await parse_tool_results() + + +if __name__ == "__main__": + asyncio.run(main()) ``` ### MCP Primitives @@ -635,16 +2421,17 @@ The MCP protocol defines three core primitives that servers can implement: MCP servers declare capabilities during initialization: -| Capability | Feature Flag | Description | -|-------------|------------------------------|------------------------------------| -| `prompts` | `listChanged` | Prompt template management | -| `resources` | `subscribe`
`listChanged`| Resource exposure and updates | -| `tools` | `listChanged` | Tool discovery and execution | -| `logging` | - | Server logging configuration | -| `completion`| - | Argument completion suggestions | +| Capability | Feature Flag | Description | +|--------------|------------------------------|------------------------------------| +| `prompts` | `listChanged` | Prompt template management | +| `resources` | `subscribe`
`listChanged`| Resource exposure and updates | +| `tools` | `listChanged` | Tool discovery and execution | +| `logging` | - | Server logging configuration | +| `completions`| - | Argument completion suggestions | ## Documentation +- [API Reference](https://modelcontextprotocol.github.io/python-sdk/api/) - [Model Context Protocol documentation](https://modelcontextprotocol.io) - [Model Context Protocol specification](https://spec.modelcontextprotocol.io) - [Officially supported servers](https://github.com/modelcontextprotocol/servers) @@ -655,4 +2442,4 @@ We are passionate about supporting contributors of all levels of experience and ## License -This project is licensed under the MIT License - see the LICENSE file for details. +This project is licensed under the MIT License - see the LICENSE file for details. \ No newline at end of file diff --git a/context/llms-full.txt b/context/llms-full.txt index 6d3f928..5fda16a 100644 --- a/context/llms-full.txt +++ b/context/llms-full.txt @@ -1,3 +1,101 @@ +# Model Context Protocol +Source: https://modelcontextprotocol.io/about/index + +The open protocol that connects AI applications to the systems where context lives + +
+
+
+ MCP Logo +
+ +
+

Connect your AI applications to the world

+ +

+ AI-enabled tools are powerful, but they're often limited to the + information you manually provide or require bespoke integrations. +

+ +

+ Whether it's reading files from your computer, searching through an + internal or external knowledge base, or updating tasks in an project + management tool, MCP provides a secure, standardized, *simple* way to + give AI systems the context they need. +

+
+
+ +
+

How it works

+ +
+
1
+ +
+

Choose MCP servers

+ +

+ Pick from pre-built servers for popular tools like GitHub, Google + Drive, Slack and hundreds of others. Combine multiple servers for + complete workflows, or easily build your own for custom integrations. +

+
+ +
2
+ +
+

Connect your AI application

+ +

+ Configure your AI application (like Claude, VS Code, or ChatGPT) to + connect to your MCP servers. The application can now see available + tools, resources and prompts from all connected servers. +

+
+ +
3
+ +
+

Work with context

+ +

+ Your AI-powered application can now access real data, execute actions, + and provide more helpful responses based on your actual context. +

+
+
+
+ +
+

Join a growing ecosystem

+ +
+ +
10
+
Official SDKs
+
+ + +
80+
+
Compatible Clients
+
+ + +
1000+
+
Available Servers
+
+
+
+ +
+ + Get Started + +
+
+ + # Example Clients Source: https://modelcontextprotocol.io/clients @@ -7,118 +105,297 @@ This page provides an overview of applications that support the Model Context Pr ## Feature support matrix -| Client | [Resources] | [Prompts] | [Tools] | [Sampling] | Roots | Notes | -| ---------------------------------------- | ----------- | --------- | ------- | ---------- | ----- | ----------------------------------------------------------------------------------------------- | -| [5ire][5ire] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | -| [Apify MCP Tester][Apify MCP Tester] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | -| [BeeAI Framework][BeeAI Framework] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in agentic workflows. | -| [Claude Code][Claude Code] | ❌ | ✅ | ✅ | ❌ | ❌ | Supports prompts and tools | -| [Claude Desktop App][Claude Desktop] | ✅ | ✅ | ✅ | ❌ | ❌ | Supports tools, prompts, and resources. | -| [Cline][Cline] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | -| [Continue][Continue] | ✅ | ✅ | ✅ | ❌ | ❌ | Supports tools, prompts, and resources. | -| [Copilot-MCP][CopilotMCP] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | -| [Cursor][Cursor] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | -| [Daydreams Agents][Daydreams] | ✅ | ✅ | ✅ | ❌ | ❌ | Support for drop in Servers to Daydreams agents | -| [Emacs Mcp][Mcp.el] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in Emacs. | -| [fast-agent][fast-agent] | ✅ | ✅ | ✅ | ✅ | ✅ | Full multimodal MCP support, with end-to-end tests | -| [FLUJO][FLUJO] | ❌ | ❌ | ✅ | ❌ | ❌ | Support for resources, Prompts and Roots are coming soon | -| [Genkit][Genkit] | ⚠️ | ✅ | ✅ | ❌ | ❌ | Supports resource list and lookup through tools. | -| [GenAIScript][GenAIScript] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | -| [Goose][Goose] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | -| [Klavis AI Slack/Discord/Web][Klavis AI] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | -| [LibreChat][LibreChat] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents | -| [mcp-agent][mcp-agent] | ❌ | ❌ | ✅ | ⚠️ | ❌ | Supports tools, server connection management, and agent workflows. | -| [MCPHub][MCPHub] | ✅ | ✅ | ✅ | ❌ | ❌ | Supports tools, resources, and prompts in Neovim | -| [MCPOmni-Connect][MCPOmni-Connect] | ✅ | ✅ | ✅ | ✅ | ❌ | Supports tools with agentic mode, ReAct, and orchestrator capabilities. | -| [Microsoft Copilot Studio] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | -| [OpenSumi][OpenSumi] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in OpenSumi | -| [oterm][oterm] | ❌ | ✅ | ✅ | ✅ | ❌ | Supports tools, prompts and sampling for Ollama. | -| [Roo Code][Roo Code] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | -| [Sourcegraph Cody][Cody] | ✅ | ❌ | ❌ | ❌ | ❌ | Supports resources through OpenCTX | -| [SpinAI][SpinAI] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Typescript AI Agents | -| [Superinterface][Superinterface] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | -| [TheiaAI/TheiaIDE][TheiaAI/TheiaIDE] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents in Theia AI and the AI-powered Theia IDE | -| [TypingMind App][TypingMind App] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools at app-level (appear as plugins) or when assigned to Agents | -| [VS Code GitHub Copilot][VS Code] | ❌ | ❌ | ✅ | ❌ | ✅ | Supports dynamic tool/roots discovery, secure secret configuration, and explicit tool prompting | -| [Windsurf Editor][Windsurf] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools with AI Flow for collaborative development. | -| [Witsy][Witsy] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in Witsy. | -| [Zed][Zed] | ❌ | ✅ | ❌ | ❌ | ❌ | Prompts appear as slash commands | +
+ | Client | [Resources] | [Prompts] | [Tools] | [Discovery] | [Sampling] | [Roots] | [Elicitation] | + | ---------------------------------------------------------- | ----------- | --------- | ------- | ----------- | ---------- | ------- | ------------- | + | [5ire][5ire] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [AgentAI][AgentAI] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [AgenticFlow][AgenticFlow] | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [AIQL TUUI][AIQL TUUI] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | + | [Amazon Q CLI][Amazon Q CLI] | ❌ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Amazon Q IDE][Amazon Q IDE] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Amp][Amp] | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❓ | + | [Apify MCP Tester][Apify MCP Tester] | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [Augment Code][AugmentCode] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [BeeAI Framework][BeeAI Framework] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [BoltAI][BoltAI] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Call Chirp][Call Chirp] | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Chatbox][Chatbox] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [ChatFrame][ChatFrame] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [ChatGPT][ChatGPT] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [ChatWise][ChatWise] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Claude.ai][Claude.ai] | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Claude Code][Claude Code] | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❓ | + | [Claude Desktop App][Claude Desktop] | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Chorus][Chorus] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Cline][Cline] | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [CodeGPT][CodeGPT] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Continue][Continue] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Copilot-MCP][CopilotMCP] | ✅ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Cursor][Cursor] | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | + | [Daydreams Agents][Daydreams] | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [ECA][ECA] | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❓ | + | [Emacs Mcp][Mcp.el] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [fast-agent][fast-agent] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + | [FlowDown][FlowDown] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❌ | + | [FLUJO][FLUJO] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Genkit][Genkit] | ⚠️ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Glama][Glama] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Gemini CLI][Gemini CLI] | ❌ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [GenAIScript][GenAIScript] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [GitHub Copilot coding agent][GitHubCopilotCodingAgent] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [Goose][Goose] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [gptme][gptme] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [HyperAgent][HyperAgent] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Jenova][Jenova] | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [JetBrains AI Assistant][JetBrains AI Assistant] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [JetBrains Junie][JetBrains Junie] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [Kilo Code][Kilo Code] | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [Klavis AI Slack/Discord/Web][Klavis AI] | ✅ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Langflow][Langflow] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [LibreChat][LibreChat] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [LM-Kit.NET][LM-Kit.NET] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [LM Studio][LM Studio] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Lutra][Lutra] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [MCP Bundler for MacOS][mcp-bundler] | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | + | [mcp-agent][mcp-agent] | ✅ | ✅ | ✅ | ❓ | ⚠️ | ✅ | ✅ | + | [mcp-client-chatbot][mcp-client-chatbot] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [MCPJam][MCPJam] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ✅ | + | [mcp-use][mcp-use] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | + | [modelcontextchat.com][modelcontextchat.com] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [MCPHub][MCPHub] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [MCPOmni-Connect][MCPOmni-Connect] | ✅ | ✅ | ✅ | ❓ | ✅ | ❌ | ❓ | + | [Memex][Memex] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Microsoft Copilot Studio] | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [MindPal][MindPal] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Mistral AI: Le Chat][Mistral AI: Le Chat] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [MooPoint][MooPoint] | ❌ | ❌ | ✅ | ❓ | ✅ | ❌ | ❓ | + | [Msty Studio][Msty Studio] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Needle][Needle] | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [NVIDIA Agent Intelligence toolkit][AIQ toolkit] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [OpenSumi][OpenSumi] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [oterm][oterm] | ❌ | ✅ | ✅ | ❓ | ✅ | ❌ | ❓ | + | [Postman][postman] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [RecurseChat][RecurseChat] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Roo Code][Roo Code] | ✅ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Shortwave][Shortwave] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Simtheory][Simtheory] | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [Slack MCP Client][Slack MCP Client] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Smithery Playground][Smithery Playground] | ✅ | ✅ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [SpinAI][SpinAI] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Superinterface][Superinterface] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Superjoin][Superjoin] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Swarms][Swarms] | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [systemprompt][systemprompt] | ✅ | ✅ | ✅ | ❓ | ✅ | ❌ | ❓ | + | [Tambo][Tambo] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Tencent CloudBase AI DevKit][Tencent CloudBase AI DevKit] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [TheiaAI/TheiaIDE][TheiaAI/TheiaIDE] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Tome][Tome] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [TypingMind App][TypingMind App] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [VS Code GitHub Copilot][VS Code] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + | [Warp][Warp] | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [WhatsMCP][WhatsMCP] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Windsurf Editor][Windsurf] | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❓ | + | [Witsy][Witsy] | ❌ | ❌ | ✅ | ❓ | ❌ | ❌ | ❓ | + | [Zed][Zed] | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❓ | + | [Zencoder][Zencoder] | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❓ | + + [Resources]: /docs/concepts/resources + + [Prompts]: /docs/concepts/prompts + + [Tools]: /docs/concepts/tools + + [Discovery]: /docs/concepts/tools#tool-discovery-and-updates + + [Sampling]: /docs/concepts/sampling + + [Roots]: /docs/concepts/roots + + [Elicitation]: /docs/concepts/elicitation + + [5ire]: https://github.com/nanbingxyz/5ire + + [AgentAI]: https://github.com/AdamStrojek/rust-agentai + + [AgenticFlow]: https://agenticflow.ai/mcp + + [AIQ toolkit]: https://github.com/NVIDIA/AIQToolkit + + [AIQL TUUI]: https://github.com/AI-QL/tuui + + [Amazon Q CLI]: https://github.com/aws/amazon-q-developer-cli + + [Amazon Q IDE]: https://aws.amazon.com/q/developer + + [Amp]: https://ampcode.com + + [Apify MCP Tester]: https://apify.com/jiri.spilka/tester-mcp-client + + [AugmentCode]: https://augmentcode.com + + [BeeAI Framework]: https://framework.beeai.dev + + [BoltAI]: https://boltai.com + + [Call Chirp]: https://www.call-chirp.com + + [Chatbox]: https://chatboxai.app + + [ChatFrame]: https://chatframe.co + + [ChatGPT]: https://chatgpt.com + + [ChatWise]: https://chatwise.app + + [Claude.ai]: https://claude.ai + + [Claude Code]: https://claude.com/product/claude-code + + [Claude Desktop]: https://claude.ai/download + + [Chorus]: https://chorus.sh + + [Cline]: https://github.com/cline/cline + + [CodeGPT]: https://codegpt.co + + [Continue]: https://github.com/continuedev/continue + + [CopilotMCP]: https://github.com/VikashLoomba/copilot-mcp + + [Cursor]: https://cursor.com + + [Daydreams]: https://github.com/daydreamsai/daydreams + + [ECA]: https://eca.dev + + [Klavis AI]: https://www.klavis.ai/ + + [Mcp.el]: https://github.com/lizqwerscott/mcp.el + + [fast-agent]: https://github.com/evalstate/fast-agent + + [FlowDown]: https://github.com/Lakr233/FlowDown + + [FLUJO]: https://github.com/mario-andreschak/flujo + + [Glama]: https://glama.ai/chat + + [Gemini CLI]: https://goo.gle/gemini-cli + + [Genkit]: https://github.com/firebase/genkit + + [GenAIScript]: https://microsoft.github.io/genaiscript/reference/scripts/mcp-tools/ + + [GitHubCopilotCodingAgent]: https://docs.github.com/en/enterprise-cloud@latest/copilot/concepts/about-copilot-coding-agent + + [Goose]: https://block.github.io/goose/docs/goose-architecture/#interoperability-with-extensions + + [Jenova]: https://www.jenova.ai + + [JetBrains AI Assistant]: https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant + + [JetBrains Junie]: https://www.jetbrains.com/junie + + [Kilo Code]: https://github.com/Kilo-Org/kilocode + + [Langflow]: https://github.com/langflow-ai/langflow + + [LibreChat]: https://github.com/danny-avila/LibreChat + + [LM-Kit.NET]: https://lm-kit.com/products/lm-kit-net/ + + [LM Studio]: https://lmstudio.ai + + [Lutra]: https://lutra.ai -[5ire]: https://github.com/nanbingxyz/5ire + [mcp-bundler]: https://mcp-bundler.maketry.xyz -[Apify MCP Tester]: https://apify.com/jiri.spilka/tester-mcp-client + [mcp-agent]: https://github.com/lastmile-ai/mcp-agent -[BeeAI Framework]: https://i-am-bee.github.io/beeai-framework + [mcp-client-chatbot]: https://github.com/cgoinglove/mcp-client-chatbot -[Claude Code]: https://claude.ai/code + [MCPJam]: https://github.com/MCPJam/inspector -[Claude Desktop]: https://claude.ai/download + [mcp-use]: https://github.com/pietrozullo/mcp-use -[Cline]: https://github.com/cline/cline + [modelcontextchat.com]: https://modelcontextchat.com -[Continue]: https://github.com/continuedev/continue + [MCPHub]: https://github.com/ravitemer/mcphub.nvim -[CopilotMCP]: https://github.com/VikashLoomba/copilot-mcp + [MCPOmni-Connect]: https://github.com/Abiorh001/mcp_omni_connect -[Cursor]: https://cursor.com + [Memex]: https://memex.tech/ -[Daydreams]: https://github.com/daydreamsai/daydreams + [Microsoft Copilot Studio]: https://learn.microsoft.com/en-us/microsoft-copilot-studio/agent-extend-action-mcp -[Klavis AI]: https://www.klavis.ai/ + [MindPal]: https://mindpal.io -[Mcp.el]: https://github.com/lizqwerscott/mcp.el + [Mistral AI: Le Chat]: https://chat.mistral.ai -[fast-agent]: https://github.com/evalstate/fast-agent + [MooPoint]: https://moopoint.io -[FLUJO]: https://github.com/mario-andreschak/flujo + [Msty Studio]: https://msty.ai -[Genkit]: https://github.com/firebase/genkit + [Needle]: https://needle.app -[GenAIScript]: https://microsoft.github.io/genaiscript/reference/scripts/mcp-tools/ + [OpenSumi]: https://github.com/opensumi/core -[Goose]: https://block.github.io/goose/docs/goose-architecture/#interoperability-with-extensions + [oterm]: https://github.com/ggozad/oterm -[LibreChat]: https://github.com/danny-avila/LibreChat + [Postman]: https://postman.com/downloads -[mcp-agent]: https://github.com/lastmile-ai/mcp-agent + [RecurseChat]: https://recurse.chat/ -[MCPHub]: https://github.com/ravitemer/mcphub.nvim + [Roo Code]: https://roocode.com -[MCPOmni-Connect]: https://github.com/Abiorh001/mcp_omni_connect + [Shortwave]: https://www.shortwave.com -[Microsoft Copilot Studio]: https://learn.microsoft.com/en-us/microsoft-copilot-studio/agent-extend-action-mcp + [Simtheory]: https://simtheory.ai -[OpenSumi]: https://github.com/opensumi/core + [Slack MCP Client]: https://github.com/tuannvm/slack-mcp-client -[oterm]: https://github.com/ggozad/oterm + [Smithery Playground]: https://smithery.ai/playground -[Roo Code]: https://roocode.com + [SpinAI]: https://docs.spinai.dev -[Cody]: https://sourcegraph.com/cody + [Superinterface]: https://superinterface.ai -[SpinAI]: https://spinai.dev + [Superjoin]: https://superjoin.ai -[Superinterface]: https://superinterface.ai + [Swarms]: https://github.com/kyegomez/swarms -[TheiaAI/TheiaIDE]: https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/ + [systemprompt]: https://systemprompt.io -[TypingMind App]: https://www.typingmind.com + [Tambo]: https://tambo.co -[VS Code]: https://code.visualstudio.com/ + [Tencent CloudBase AI DevKit]: https://docs.cloudbase.net/ai/agent/mcp -[Windsurf]: https://codeium.com/windsurf + [TheiaAI/TheiaIDE]: https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/ -[Witsy]: https://github.com/nbonamy/witsy + [Tome]: https://github.com/runebookai/tome -[Zed]: https://zed.dev + [TypingMind App]: https://www.typingmind.com -[Resources]: https://modelcontextprotocol.io/docs/concepts/resources + [VS Code]: https://code.visualstudio.com/ -[Prompts]: https://modelcontextprotocol.io/docs/concepts/prompts + [Windsurf]: https://codeium.com/windsurf -[Tools]: https://modelcontextprotocol.io/docs/concepts/tools + [gptme]: https://github.com/gptme/gptme -[Sampling]: https://modelcontextprotocol.io/docs/concepts/sampling + [Warp]: https://www.warp.dev/ + + [WhatsMCP]: https://wassist.app/mcp/ + + [Witsy]: https://github.com/nbonamy/witsy + + [Zed]: https://zed.dev + + [Zencoder]: https://zencoder.ai + + [HyperAgent]: https://github.com/hyperbrowserai/HyperAgent +
## Client details @@ -133,6 +410,79 @@ This page provides an overview of applications that support the Model Context Pr * It is open-source and user-friendly, suitable for beginners. * Future support for MCP will be continuously improved. +### AgentAI + +[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. + +[Example of MCP Server integration](https://github.com/AdamStrojek/rust-agentai/blob/master/examples/tools_mcp.rs) + +**Key features:** + +* Multi-LLM – We support most LLM APIs (OpenAI, Anthropic, Gemini, Ollama, and all OpenAI API Compatible). +* Built-in support for MCP Servers. +* Create agentic flows in a type- and memory-safe language like Rust. + +### AgenticFlow + +[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. + +**Key features:** + +* No-code AI agent creation and workflow building. +* Access a vast library of 10,000+ tools and 2,500+ APIs through MCP. +* Simple 3-step process to connect MCP servers. +* Securely manage connections and revoke access anytime. + +**Learn more:** + +* [AgenticFlow MCP Integration](https://agenticflow.ai/mcp) + +### AIQL TUUI + +[AIQL TUUI] is a native, cross-platform desktop AI chat application with MCP support. It supports multiple AI providers (e.g., Anthropic, Cloudflare, Deepseek, OpenAI, Qwen), local AI models (via vLLM, Ray, etc.), and aggregated API platforms (such as Deepinfra, Openrouter, and more). + +**Key features:** + +* **Dynamic LLM API & Agent Switching**: Seamlessly toggle between different LLM APIs and agents on the fly. +* **Comprehensive Capabilities Support**: Built-in support for tools, prompts, resources, and sampling methods. +* **Configurable Agents**: Enhanced flexibility with selectable and customizable tools via agent settings. +* **Advanced Sampling Control**: Modify sampling parameters and leverage multi-round sampling for optimal results. +* **Cross-Platform Compatibility**: Fully compatible with macOS, Windows, and Linux. +* **Free & Open-Source (FOSS)**: Permissive licensing allows modifications and custom app bundling. + +**Learn more:** + +* [TUUI document](https://www.tuui.com/) +* [AIQL GitHub repository](https://github.com/AI-QL) + +### Amazon Q CLI + +[Amazon Q CLI](https://github.com/aws/amazon-q-developer-cli) is an open-source, agentic coding assistant for terminals. + +**Key features:** + +* Full support for MCP servers. +* Edit prompts using your preferred text editor. +* Access saved prompts instantly with `@`. +* Control and organize AWS resources directly from your terminal. +* Tools, profiles, context management, auto-compact, and so much more! + +**Get Started** + +```bash theme={null} +brew install amazon-q +``` + +### Amazon Q IDE + +[Amazon Q IDE](https://aws.amazon.com/q/developer) is an open-source, agentic coding assistant for IDEs. + +**Key features:** + +* Support for the VSCode, JetBrains, Visual Studio, and Eclipse IDEs. +* Control and organize AWS resources directly from your IDE. +* Manage permissions for each MCP tool via the IDE user interface. + ### Apify MCP Tester [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). @@ -145,9 +495,29 @@ It uses plain JavaScript (old-school style) and is hosted on Apify, allowing you * 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). * Dynamically utilizes tools based on context and user queries (if supported by the server). +### Amp + +[Amp](https://ampcode.com) is an agentic coding tool built by Sourcegraph. It runs in VS Code (and compatible forks like Cursor, Windsurf, and VSCodium), JetBrains IDEs, Neovim, and as a command-line tool. It’s also multiplayer — you can share threads and collaborate with your team. + +**Key features:** + +* Granular control over enabled tools and permissions +* Support for MCP servers defined in VS Code `mcp.json` + +### Augment Code + +[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. + +**Key features:** + +* Full MCP support in local and remote agents. +* Add additional context through MCP servers. +* Automate your development workflows with MCP tools. +* Works in VS Code and JetBrains IDEs. + ### BeeAI Framework -[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. +[BeeAI Framework](https://framework.beeai.dev) 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. **Key features:** @@ -159,15 +529,92 @@ It uses plain JavaScript (old-school style) and is hosted on Apify, allowing you * [Example of using MCP tools in agentic workflow](https://i-am-bee.github.io/beeai-framework/#/typescript/tools?id=using-the-mcptool-class) +### BoltAI + +[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) + +**Key features:** + +* MCP Tool integrations: once configured, user can enable individual MCP server in each chat +* MCP quick setup: import configuration from Claude Desktop app or Cursor editor +* Invoke MCP tools inside any app with AI Command feature +* Integrate with remote MCP servers in the mobile app + +**Learn more:** + +* [BoltAI docs](https://boltai.com/docs/plugins/mcp-servers) +* [BoltAI website](https://boltai.com) + +### Call Chirp + +[Call Chirp] [https://www.call-chirp.com](https://www.call-chirp.com) uses AI to capture every critical detail from your business conversations, automatically syncing insights to your CRM and project tools so you never miss another deal-closing moment. + +**Key features:** + +* Save transcriptions from Zoom, Google Meet, and more +* MCP Tools for voice AI agents +* Remote MCP servers support + +### Chatbox + +Chatbox is a better UI and desktop app for ChatGPT, Claude, and other LLMs, available on Windows, Mac, Linux, and the web. It's open-source and has garnered 37K stars⭐ on GitHub. + +**Key features:** + +* Tools support for MCP servers +* Support both local and remote MCP servers +* Built-in MCP servers marketplace + +### ChatFrame + +A cross-platform desktop chatbot that unifies access to multiple AI language models, supports custom tool integration via MCP servers, and enables RAG conversations with your local files—all in a single, polished app for macOS and Windows. + +**Key features:** + +* Unified access to top LLM providers (OpenAI, Anthropic, DeepSeek, xAI, and more) in one interface +* Built-in retrieval-augmented generation (RAG) for instant, private search across your PDFs, text, and code files +* Plug-in system for custom tools via Model Context Protocol (MCP) servers +* Multimodal chat: supports images, text, and live interactive artifacts + +### ChatGPT + +ChatGPT is OpenAI's AI assistant that provides MCP support for remote servers to conduct deep research. + +**Key features:** + +* Support for MCP via connections UI in settings +* Access to search tools from configured MCP servers for deep research +* Enterprise-grade security and compliance features + +### ChatWise + +ChatWise is a desktop-optimized, high-performance chat application that lets you bring your own API keys. It supports a wide range of LLMs and integrates with MCP to enable tool workflows. + +**Key features:** + +* Tools support for MCP servers +* Offer built-in tools like web search, artifacts and image generation. + ### Claude Code -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. +Claude Code is an interactive agentic coding tool from Anthropic that helps you code faster through natural language commands. It supports MCP integration for resources, prompts, tools, and roots, and also functions as an MCP server to integrate with other clients. **Key features:** -* Tool and prompt support for MCP servers +* Full support for resources, prompts, tools, and roots from MCP servers * Offers its own tools through an MCP server for integrating with other MCP clients +### Claude.ai + +[Claude.ai](https://claude.ai) is Anthropic's web-based AI assistant that provides MCP support for remote servers. + +**Key features:** + +* Support for remote MCP servers via integrations UI in settings +* Access to tools, prompts, and resources from configured MCP servers +* Seamless integration with Claude's conversational interface +* Enterprise-grade security and compliance features + ### Claude Desktop App The Claude desktop application provides comprehensive support for MCP, enabling deep integration with local tools and data sources. @@ -179,7 +626,17 @@ The Claude desktop application provides comprehensive support for MCP, enabling * Tool integration for executing commands and scripts * Local server connections for enhanced privacy and security -> ⓘ Note: The Claude.ai web application does not currently support MCP. MCP features are only available in the desktop application. +### Chorus + +[Chorus](https://chorus.sh) is a native Mac app for chatting with AIs. Chat with multiple models at once, run tools and MCPs, create projects, quick chat, bring your own key, all in a blazing fast, keyboard shortcut friendly app. + +**Key features:** + +* MCP support with one-click install +* Built in tools, like web search, terminal, and image generation +* Chat with multiple models at once (cloud or local) +* Create projects with scoped memory +* Quick chat with an AI that can see your screen ### Cline @@ -191,11 +648,25 @@ The Claude desktop application provides comprehensive support for MCP, enabling * Share custom MCP servers Cline creates with others via the `~/Documents/Cline/MCP` directory * Displays configured MCP servers along with their tools, resources, and any error logs +### CodeGPT + +[CodeGPT](https://codegpt.co) is a popular VS Code and Jetbrains extension that brings AI-powered coding assistance to your editor. It supports integration with MCP servers for tools, allowing users to leverage external AI capabilities directly within their development workflow. + +**Key features:** + +* Use MCP tools from any configured MCP server +* Seamless integration with VS Code and Jetbrains UI +* Supports multiple LLM providers and custom endpoints + +**Learn more:** + +* [CodeGPT Documentation](https://docs.codegpt.co/) + ### Continue [Continue](https://github.com/continuedev/continue) is an open-source AI code assistant, with built-in support for all MCP features. -**Key features** +**Key features:** * Type "@" to mention MCP resources * Prompt templates surface as slash commands @@ -214,11 +685,14 @@ The Claude desktop application provides comprehensive support for MCP, enabling ### Cursor -[Cursor](https://docs.cursor.com/advanced/model-context-protocol) is an AI code editor. +[Cursor](https://docs.cursor.com/context/mcp#protocol-support) is an AI code editor. -**Key Features**: +**Key features:** * Support for MCP tools in Cursor Composer +* Support for roots +* Support for prompts +* Support for elicitation * Support for both STDIO and SSE ### Daydreams @@ -230,6 +704,25 @@ The Claude desktop application provides comprehensive support for MCP, enabling * Supports MCP Servers in config * Exposes MCP Client +### ECA - Editor Code Assistant + +[ECA](https://eca.dev) is a Free and open-source editor-agnostic tool that aims to easily link LLMs and Editors, giving the best UX possible for AI pair programming using a well-defined protocol + +**Key features:** + +* **Editor-agnostic**: protocol for any editor to integrate. +* **Single configuration**: Configure eca making it work the same in any editor via global or local configs. +* **Chat** interface: ask questions, review code, work together to code. +* **Agentic**: let LLM work as an agent with its native tools and MCPs you can configure. +* **Context**: support: giving more details about your code to the LLM, including MCP resources and prompts. +* **Multi models**: Login to OpenAI, Anthropic, Copilot, Ollama local models and many more. +* **OpenTelemetry**: Export metrics of tools, prompts, server usage. + +**Learn more:** + +* [ECA website](https://eca.dev) +* [ECA source code](https://github.com/editor-code-assistant/eca) + ### Emacs Mcp [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. @@ -249,6 +742,23 @@ The Claude desktop application provides comprehensive support for MCP, enabling * Built in support for "Building Effective Agents" workflows. * Deploy Agents as MCP Servers +### FlowDown + +[FlowDown](https://github.com/Lakr233/FlowDown) is a blazing fast and smooth client app for using AI/LLM, with a strong emphasis on privacy and user experience. It supports MCP servers to extend its capabilities with external tools, allowing users to build powerful, customized workflows. + +**Key features:** + +* **Seamless MCP Integration**: Easily connect to MCP servers to utilize a wide range of external tools. +* **Privacy-First Design**: Your data stays on your device. We don't collect any user data, ensuring complete privacy. +* **Lightweight & Efficient**: A compact and optimized design ensures a smooth and responsive experience with any AI model. +* **Broad Compatibility**: Works with all OpenAI-compatible service providers and supports local offline models through MLX. +* **Rich User Experience**: Features beautifully formatted Markdown, blazing-fast text rendering, and intelligent, automated chat titling. + +**Learn more:** + +* [FlowDown website](https://flowdown.ai/) +* [FlowDown documentation](https://apps.qaq.wiki/docs/flowdown/) + ### FLUJO 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. @@ -272,6 +782,19 @@ Think n8n + ChatGPT. FLUJO is an desktop application that integrates with MCP to * Seamless interoperability with Genkit's existing tools and prompts * Works across a wide variety of GenAI models from top providers +### Glama + +[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. + +**Key features:** + +* Integrated [MCP Server Directory](https://glama.ai/mcp/servers) +* Integrated [MCP Tool Directory](https://glama.ai/mcp/tools) +* Host MCP servers and access them via the Chat or SSE endpoints + – Ability to chat with multiple LLMs and MCP servers at once +* Upload and analyze local files and data +* Full-text search across all your chats and data + ### GenAIScript Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft.github.io/genaiscript/) (in JavaScript). Orchestrate LLMs, tools, and data in JavaScript. @@ -293,3756 +816,2671 @@ Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft * Goose allows you to extend its functionality by [building your own MCP servers](https://block.github.io/goose/docs/tutorials/custom-extensions). * Includes built-in tools for development, web scraping, automation, memory, and integrations with JetBrains and Google Drive. -### Klavis AI Slack/Discord/Web +### GitHub Copilot coding agent -[Klavis AI](https://www.klavis.ai/) is an Open-Source Infra to Use, Build & Scale MCPs with ease. +Delegate tasks to [GitHub Copilot coding agent](https://docs.github.com/en/copilot/concepts/about-copilot-coding-agent) and let it work in the background while you stay focused on the highest-impact and most interesting work **Key features:** -* Slack/Discord/Web MCP clients for using MCPs directly -* Simple web UI dashboard for easy MCP configuration -* Direct OAuth integration with Slack & Discord Clients and MCP Servers for secure user authentication -* SSE transport support -* Open-source infrastructure ([GitHub repository](https://github.com/Klavis-AI/klavis)) - -**Learn more:** - -* [Demo video showing MCP usage in Slack/Discord](https://youtu.be/9-QQAhrQWw8) +* Delegate tasks to Copilot from GitHub Issues, Visual Studio Code, GitHub Copilot Chat or from your favorite MCP host using the GitHub MCP Server +* Tailor Copilot to your project by [customizing the agent's development environment](https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/agents/copilot-coding-agent/customizing-the-development-environment-for-copilot-coding-agent#preinstalling-tools-or-dependencies-in-copilots-environment) or [writing custom instructions](https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/agents/copilot-coding-agent/best-practices-for-using-copilot-to-work-on-tasks#adding-custom-instructions-to-your-repository) +* [Augment Copilot's context and capabilities with MCP tools](https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp), with support for both local and remote MCP servers -### LibreChat +### gptme -[LibreChat](https://github.com/danny-avila/LibreChat) is an open-source, customizable AI chat UI that supports multiple AI providers, now including MCP integration. +[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. **Key features:** -* Extend current tool ecosystem, including [Code Interpreter](https://www.librechat.ai/docs/features/code_interpreter) and Image generation tools, through MCP servers -* Add tools to customizable [Agents](https://www.librechat.ai/docs/features/agents), using a variety of LLMs from top providers -* Open-source and self-hostable, with secure multi-user support -* Future roadmap includes expanded MCP feature support +* CLI-first design with a focus on simplicity and ease of use +* Rich set of built-in tools for shell commands, Python execution, file operations, and web browsing +* Local-first approach with support for multiple LLM providers +* Open-source, built to be extensible and easy to modify -### mcp-agent +### HyperAgent -[mcp-agent] is a simple, composable framework to build agents using Model Context Protocol. +[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. **Key features:** -* Automatic connection management of MCP servers. -* Expose tools from multiple servers to an LLM. -* Implements every pattern defined in [Building Effective Agents](https://www.anthropic.com/research/building-effective-agents). -* Supports workflow pause/resume signals, such as waiting for human feedback. +* AI Commands: Simple APIs like page.ai(), page.extract() and executeTask() for any AI automation +* Fallback to Regular Playwright: Use regular Playwright when AI isn't needed +* Stealth Mode – Avoid detection with built-in anti-bot patches +* Cloud Ready – Instantly scale to hundreds of sessions via [Hyperbrowser](https://www.hyperbrowser.ai/) +* MCP Client – Connect to tools like Composio for full workflows (e.g. writing web data to Google Sheets) -### MCPHub +### Jenova -[MCPHub] is a powerful Neovim plugin that integrates MCP (Model Context Protocol) servers into your workflow. +[Jenova](https://jenova.ai) is the best MCP client for non-technical users, especially on mobile. -**Key features** +**Key features:** -* Install, configure and manage MCP servers with an intuitive UI. -* Built-in Neovim MCP server with support for file operations (read, write, search, replace), command execution, terminal integration, LSP integration, buffers, and diagnostics. -* Create Lua-based MCP servers directly in Neovim. -* Inegrates with popular Neovim chat plugins Avante.nvim and CodeCompanion.nvim +* 30+ pre-integrated MCP servers with one-click integration of custom servers +* MCP recommendation capability that suggests the best servers for specific tasks +* Multi-agent architecture with leading tool use reliability and scalability, supporting unlimited concurrent MCP server connections through RAG-powered server metadata +* Model agnostic platform supporting any leading LLMs (OpenAI, Anthropic, Google, etc.) +* Unlimited chat history and global persistent memory powered by RAG +* Easy creation of custom agents with custom models, instructions, knowledge bases, and MCP servers +* Local MCP server (STDIO) support coming soon with desktop apps -### MCPOmni-Connect +### JetBrains AI Assistant -[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. +[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. **Key features:** -* Support for resources, prompts, tools, and sampling -* Agentic mode with ReAct and orchestrator capabilities -* Seamless integration with OpenAI models and other LLMs -* Dynamic tool and resource management across multiple servers -* Support for both stdio and SSE transport protocols -* Comprehensive tool orchestration and resource analysis capabilities +* Unlimited code completion powered by Mellum, JetBrains’ proprietary AI model. +* Context-aware AI chat that understands your code and helps you in real time. +* Access to top-tier models from OpenAI, Anthropic, and Google. +* Offline mode with connected local LLMs via Ollama or LM Studio. +* Deep integration into IDE workflows, including code suggestions in the editor, VCS assistance, runtime error explanation, and more. -### Microsoft Copilot Studio +### JetBrains Junie -[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. +[Junie](https://www.jetbrains.com/junie) is JetBrains’ AI coding agent for JetBrains IDEs and Android Studio. **Key features:** -* Support for MCP tools -* Extend Copilot Studio agents with MCP servers -* Leveraging Microsoft unified, governed, and secure API management solutions +* Connects to MCP servers over **stdio** to use external tools and data sources. +* Per-command approval with an optional allowlist. +* Config via `mcp.json` (global `~/.junie/mcp.json` or project `.junie/mcp/`). -### OpenSumi +### Kilo Code -[OpenSumi](https://github.com/opensumi/core) is a framework helps you quickly build AI Native IDE products. +[Kilo Code](https://github.com/Kilo-Org/kilocode) is an autonomous coding AI dev team in VS Code that edits files, runs commands, uses a browser, and more. **Key features:** -* Supports MCP tools in OpenSumi -* Supports built-in IDE MCP servers and custom MCP servers +* Create and add tools through natural language (e.g. "add a tool that searches the web") +* Discover MCP servers via the MCP Marketplace +* One click MCP server installs via MCP Marketplace +* Displays configured MCP servers along with their tools, resources, and any error logs -### oterm +### Klavis AI Slack/Discord/Web -[oterm] is a terminal client for Ollama allowing users to create chats/agents. +[Klavis AI](https://www.klavis.ai/) is an Open-Source Infra to Use, Build & Scale MCPs with ease. **Key features:** -* Support for multiple fully customizable chat sessions with Ollama connected with tools. -* Support for MCP tools. - -### Roo Code - -[Roo Code](https://roocode.com) enables AI coding assistance via MCP. +* Slack/Discord/Web MCP clients for using MCPs directly +* Simple web UI dashboard for easy MCP configuration +* Direct OAuth integration with Slack & Discord Clients and MCP Servers for secure user authentication +* SSE transport support +* Open-source infrastructure ([GitHub repository](https://github.com/Klavis-AI/klavis)) -**Key features:** +**Learn more:** -* Support for MCP tools and resources -* Integration with development workflows -* Extensible AI capabilities +* [Demo video showing MCP usage in Slack/Discord](https://youtu.be/9-QQAhrQWw8) -### Sourcegraph Cody +### Langflow -[Cody](https://openctx.org/docs/providers/modelcontextprotocol) is Sourcegraph's AI coding assistant, which implements MCP through OpenCTX. +Langflow is an open-source visual builder that lets developers rapidly prototype and build AI applications, it integrates with the Model Context Protocol (MCP) as both an MCP server and an MCP client. **Key features:** -* Support for MCP resources -* Integration with Sourcegraph's code intelligence -* Uses OpenCTX as an abstraction layer -* Future support planned for additional MCP features +* Full support for using MCP server tools to build agents and flows. +* Export agents and flows as MCP server +* Local & remote server connections for enhanced privacy and security -### SpinAI +**Learn more:** + +* [Demo video showing how to use Langflow as both an MCP client & server](https://www.youtube.com/watch?v=pEjsaVVPjdI) + +### LibreChat -[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. +[LibreChat](https://github.com/danny-avila/LibreChat) is an open-source, customizable AI chat UI that supports multiple AI providers, now including MCP integration. **Key features:** -* Built-in MCP compatibility for AI agents -* Open-source TypeScript framework -* Observable agent architecture -* Native support for MCP tools integration +* Extend current tool ecosystem, including [Code Interpreter](https://www.librechat.ai/docs/features/code_interpreter) and Image generation tools, through MCP servers +* Add tools to customizable [Agents](https://www.librechat.ai/docs/features/agents), using a variety of LLMs from top providers +* Open-source and self-hostable, with secure multi-user support +* Future roadmap includes expanded MCP feature support -### Superinterface +### LM-Kit.NET -[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. +[LM-Kit.NET] is a local-first Generative AI SDK for .NET (C# / VB.NET) that can act as an **MCP client**. Current MCP support: **Tools only**. **Key features:** -* Use tools from MCP servers in assistants embedded via React components or script tags -* SSE transport support -* Use any AI model from any AI provider (OpenAI, Anthropic, Ollama, others) +* Consume MCP server tools over HTTP/JSON-RPC 2.0 (initialize, list tools, call tools). +* Programmatic tool discovery and invocation via `McpClient`. +* Easy integration in .NET agents and applications. -### TheiaAI/TheiaIDE +**Learn more:** -[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. +* [Docs: Using MCP in LM-Kit.NET](https://docs.lm-kit.com/lm-kit-net/api/LMKit.Mcp.Client.McpClient.html) +* [Creating AI agents](https://lm-kit.com/solutions/ai-agents) +* Product page: [LM-Kit.NET] -**Key features:** +### LM Studio -* **Tool Integration**: Theia AI enables AI agents, including those in the Theia IDE, to utilize MCP servers for seamless tool interaction. -* **Customizable Prompts**: The Theia IDE allows users to define and adapt prompts, dynamically integrating MCP servers for tailored workflows. -* **Custom agents**: The Theia IDE supports creating custom agents that leverage MCP capabilities, enabling users to design dedicated workflows on the fly. +[LM Studio](https://lmstudio.ai) is a cross-platform desktop app for discovering, downloading, and running open-source LLMs locally. You can now connect local models to tools via Model Context Protocol (MCP). -Theia AI and Theia IDE's MCP integration provide users with flexibility, making them powerful platforms for exploring and adapting MCP. +**Key features:** + +* Use MCP servers with local models on your computer. Add entries to `mcp.json` and save to get started. +* Tool confirmation UI: when a model calls a tool, you can confirm the call in the LM Studio app. +* Cross-platform: runs on macOS, Windows, and Linux, one-click installer with no need to fiddle in the command line +* Supports GGUF (llama.cpp) or MLX models with GPU acceleration +* GUI & terminal mode: use the LM Studio app or CLI (lms) for scripting and automation **Learn more:** -* [Theia IDE and Theia AI MCP Announcement](https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/) -* [Download the AI-powered Theia IDE](https://theia-ide.org/) +* [Docs: Using MCP in LM Studio](https://lmstudio.ai/docs/app/plugins/mcp) +* [Create a 'Add to LM Studio' button for your server](https://lmstudio.ai/docs/app/plugins/mcp/deeplink) +* [Announcement blog: LM Studio + MCP](https://lmstudio.ai/blog/mcp) -### TypingMind App +### Lutra -[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. +[Lutra](https://lutra.ai) is an AI agent that transforms conversations into actionable, automated workflows. **Key features:** -* **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. -* **Assign MCP Tools to Agents**: TypingMind allows users to create AI agents that have a set of MCP servers assigned. -* **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. +* Easy MCP Integration: Connecting Lutra to MCP servers is as simple as providing the server URL; Lutra handles the rest behind the scenes. +* Chat to Take Action: Lutra understands your conversational context and goals, automatically integrating with your existing apps to perform tasks. +* Reusable Playbooks: After completing a task, save the steps as reusable, automated workflows—simplifying repeatable processes and reducing manual effort. +* Shareable Automations: Easily share your saved playbooks with teammates to standardize best practices and accelerate collaborative workflows. **Learn more:** -* [TypingMind MCP Document](https://www.typingmind.com/mcp) -* [Download TypingMind (PWA)](https://www.typingmind.com/) +* [Lutra AI agent explained](https://www.youtube.com/watch?v=W5ZpN0cMY70) -### VS Code GitHub Copilot +### MCP Bundler for MacOS -[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. +[MCP Bundler](https://mcp-bundler.maketry.xyz) is perfect local proxy for your MCP workflow. The app centralizes all your MCP servers — toggle, group, turn off capabilities instantly. Switch bundles on the fly inside the MCP Bundler. **Key features:** -* Support for stdio and server-sent events (SSE) transport -* Per-session selection of tools per agent session for optimal performance -* Easy server debugging with restart commands and output logging -* Tool calls with editable inputs and always-allow toggle -* Integration with existing VS Code extension system to register MCP servers from extensions +* Unified Control Panel: Manage all your MCP servers — both Local STDIO and Remote HTTP/SSE — from one clear macOS window. Start, stop, or edit them instantly without touching configs. +* One Click, All Connected: Launch or disable entire MCP setups with one toggle. Switch bundles per project or workspace and keep your AI tools synced automatically. +* Per-Tool Control: Enable or hide individual tools inside each server. Keep your bundles clean, lightweight, and tailored for every AI workflow. +* Instant Health & Logs: Real-time health indicators and request logs show exactly what’s running. Diagnose and fix connection issues without leaving the app. +* Auto-Generate MCP Config: Copy a ready-made JSON snippet for any client in seconds. No manual wiring — connect your Bundler as a single MCP endpoint. -### Windsurf Editor +**Learn more:** -[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. +* [MCP Bundler in action](https://www.youtube.com/watch?v=CEHVSShw_NU) + +### mcp-agent + +[mcp-agent] is a simple, composable framework to build agents using Model Context Protocol. **Key features:** -* Revolutionary AI Flow paradigm for human-AI collaboration -* Intelligent code generation and understanding -* Rich development tools with multi-model support +* Automatic connection management of MCP servers. +* Expose tools from multiple servers to an LLM. +* Implements every pattern defined in [Building Effective Agents](https://www.anthropic.com/research/building-effective-agents). +* Supports workflow pause/resume signals, such as waiting for human feedback. -### Witsy +### mcp-client-chatbot -[Witsy](https://github.com/nbonamy/witsy) is an AI desktop assistant, supoorting Anthropic models and MCP servers as LLM tools. +[mcp-client-chatbot](https://github.com/cgoinglove/mcp-client-chatbot) is a local-first chatbot built with Vercel's Next.js, AI SDK, and Shadcn UI. **Key features:** -* Multiple MCP servers support -* Tool integration for executing commands and scripts -* Local server connections for enhanced privacy and security -* Easy-install from Smithery.ai -* Open-source, available for macOS, Windows and Linux +* It supports standard MCP tool calling and includes both a custom MCP server and a standalone UI for testing MCP tools outside the chat flow. +* All MCP tools are provided to the LLM by default, but the project also includes an optional `@toolname` mention feature to make tool invocation more explicit—particularly useful when connecting to multiple MCP servers with many tools. +* Visual workflow builder that lets you create custom tools by chaining LLM nodes and MCP tools together. Published workflows become callable as `@workflow_name` tools in chat, enabling complex multi-step automation sequences. -### Zed +### MCPJam -[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. +[MCPJam] is an open source testing and debugging tool for MCP servers - Postman for MCP servers. **Key features:** -* Prompt templates surface as slash commands in the editor -* Tool integration for enhanced coding workflows -* Tight integration with editor features and workspace context -* Does not support MCP resources +* Test your MCP server's tools, resources, prompts, and OAuth. MCP spec compliant. +* LLM playground to test your server against different LLMs. +* Tracing and logging error messages. +* Connect and test multiple MCP servers simultaneously. +* Supports all transports - STDIO, SSE, and Streamable HTTP. -## Adding MCP support to your application +### mcp-use -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. +[mcp-use] is an open source python library to very easily connect any LLM to any MCP server both locally and remotely. -Benefits of adding MCP support: +**Key features:** -* Enable users to bring their own context and tools -* Join a growing ecosystem of interoperable AI applications -* Provide users with flexible integration options -* Support local-first AI workflows +* Very simple interface to connect any LLM to any MCP. +* Support the creation of custom agents, workflows. +* Supports connection to multiple MCP servers simultaneously. +* Supports all langchain supported models, also locally. +* Offers efficient tool orchestration and search functionalities. -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) +### modelcontextchat.com -## Updates and corrections +[modelcontextchat.com](https://modelcontextchat.com) is a web-based MCP client designed for working with remote MCP servers, featuring comprehensive authentication support and integration with OpenRouter. -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). +**Key features:** +* Web-based interface for remote MCP server connections +* Header-based Authorization support for secure server access +* OAuth authentication integration +* OpenRouter API Key support for accessing various LLM providers +* No installation required - accessible from any web browser -# Contributing -Source: https://modelcontextprotocol.io/development/contributing +### MCPHub -How to participate in Model Context Protocol development +[MCPHub] is a powerful Neovim plugin that integrates MCP (Model Context Protocol) servers into your workflow. -We welcome contributions from the community! Please review our [contributing guidelines](https://github.com/modelcontextprotocol/.github/blob/main/CONTRIBUTING.md) for details on how to submit changes. +**Key features:** -All contributors must adhere to our [Code of Conduct](https://github.com/modelcontextprotocol/.github/blob/main/CODE_OF_CONDUCT.md). +* Install, configure and manage MCP servers with an intuitive UI. +* Built-in Neovim MCP server with support for file operations (read, write, search, replace), command execution, terminal integration, LSP integration, buffers, and diagnostics. +* Create Lua-based MCP servers directly in Neovim. +* Inegrates with popular Neovim chat plugins Avante.nvim and CodeCompanion.nvim -For questions and discussions, please use [GitHub Discussions](https://github.com/orgs/modelcontextprotocol/discussions). +### MCPOmni-Connect +[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. -# Roadmap -Source: https://modelcontextprotocol.io/development/roadmap +**Key features:** -Our plans for evolving Model Context Protocol +* Support for resources, prompts, tools, and sampling +* Agentic mode with ReAct and orchestrator capabilities +* Seamless integration with OpenAI models and other LLMs +* Dynamic tool and resource management across multiple servers +* Support for both stdio and SSE transport protocols +* Comprehensive tool orchestration and resource analysis capabilities -Last updated: **2025-03-27** +### Memex -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-03-26/changelog/)**. +[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. -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. +**Key features:** -We value community participation! Each section links to relevant discussions where you can learn more and contribute your thoughts. +* **Prompt-to-MCP Server**: Generate fully functional MCP servers from natural language descriptions +* **Self-Testing & Debugging**: Autonomously test, debug, and improve created MCP servers +* **Universal MCP Client**: Works with any MCP server through intuitive, natural language integration +* **Curated MCP Directory**: Access to tested, one-click installable MCP servers (Neon, Netlify, GitHub, Context7, and more) +* **Multi-Server Orchestration**: Leverage multiple MCP servers simultaneously for complex workflows -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). +**Learn more:** -## Validation +* [Memex Launch 2: MCP Teams and Agent API](https://memex.tech/blog/memex-launch-2-mcp-teams-and-agent-api-private-preview-125f) -To foster a robust developer ecosystem, we plan to invest in: +### Microsoft Copilot Studio -* **Reference Client Implementations**: demonstrating protocol features with high-quality AI applications -* **Compliance Test Suites**: automated verification that clients, servers, and SDKs properly implement the specification +[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. -These tools will help developers confidently implement MCP while ensuring consistent behavior across the ecosystem. +**Key features:** -## Registry +* Support for MCP tools +* Extend Copilot Studio agents with MCP servers +* Leveraging Microsoft unified, governed, and secure API management solutions -For MCP to reach its full potential, we need streamlined ways to distribute and discover MCP servers. +### MindPal -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. +[MindPal](https://mindpal.io) is a no-code platform for building and running AI agents and multi-agent workflows for business processes. -## Agents +**Key features:** -As MCP increasingly becomes part of agentic workflows, we're exploring [improvements](https://github.com/modelcontextprotocol/specification/discussions/111) such as: +* Build custom AI agents with no-code +* Connect any SSE MCP server to extend agent tools +* Create multi-agent workflows for complex business processes +* User-friendly for both technical and non-technical professionals +* Ongoing development with continuous improvement of MCP support -* **[Agent Graphs](https://github.com/modelcontextprotocol/specification/discussions/94)**: enabling complex agent topologies through namespacing and graph-aware communication patterns -* **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 +**Learn more:** -## Multimodality +* [MindPal MCP Documentation](https://docs.mindpal.io/agent/mcp) -Supporting the full spectrum of AI capabilities in MCP, including: +### MooPoint -* **Additional Modalities**: video and other media types -* **[Streaming](https://github.com/modelcontextprotocol/specification/issues/117)**: multipart, chunked messages, and bidirectional communication for interactive experiences +[MooPoint](https://moopoint.io) -## Governance +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. -We're implementing governance structures that prioritize: +**Key features:** -* **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 -* **Transparent Standardization**: establishing clear processes for contributing to the specification, while exploring formal standardization via industry bodies +* Accessible from any PC or smartphone—no installation required +* Choose your preferred LLM provider +* Supports `SSE`, `Streamable HTTP`, `npx`, and `uvx` MCP servers +* OAuth and sampling support +* New features added daily -## Get Involved +### Mistral AI: Le Chat -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. +[Mistral AI: Le Chat](https://mistral.ai) is Mistral AI assistant with MCP support for remote servers and enterprise workflows. +**Key features:** -# What's New -Source: https://modelcontextprotocol.io/development/updates - -The latest updates and improvements to MCP - - - * Version [0.9.0](https://github.com/modelcontextprotocol/java-sdk/releases/tag/v0.9.0) of the MCP Java SDK has been released. - * Refactored logging system to use exchange mechanism - * Custom Context Paths - * Server Instructions - * CallToolResult Enhancement - - - - * Fix issues and cleanup API - * Added binary compatibility tracking to avoid breaking changes - * Drop jdk requirements to JDK8 - * Added Claude Desktop integration with sample - * The full changelog can be found here: [https://github.com/modelcontextprotocol/kotlin-sdk/releases/tag/0.4.0](https://github.com/modelcontextprotocol/kotlin-sdk/releases/tag/0.4.0) - - - - * Version [0.8.1](https://github.com/modelcontextprotocol/java-sdk/releases/tag/v0.8.1) of the MCP Java SDK has been released, - providing important bug fixes. - - - - * We are exited to announce the availability of the MCP - [C# SDK](https://github.com/modelcontextprotocol/csharp-sdk/) developed by - [Peder Holdgaard Pedersen](http://github.com/PederHP) and Microsoft. This joins our growing - list of supported languages. The C# SDK is also available as - [NuGet package](https://www.nuget.org/packages/ModelContextProtocol) - * Python SDK 1.5.0 was released with multiple fixes and improvements. - - - - * Version [0.8.0](https://github.com/modelcontextprotocol/java-sdk/releases/tag/v0.8.0) of the MCP Java SDK has been released, - delivering important session management improvements and bug fixes. - - - - * Typescript SDK 1.7.0 was released with multiple fixes and improvements. - - - - * We're excited to announce that the Java SDK developed by Spring AI at VMware Tanzu is now - the official [Java SDK](https://github.com/modelcontextprotocol/java-sdk) for MCP. - This joins our existing Kotlin SDK in our growing list of supported languages. - The Spring AI team will maintain the SDK as an integral part of the Model Context Protocol - organization. We're thrilled to welcome them to the MCP community! - - - - * Version [1.2.1](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.2.1) of the MCP Python SDK has been released, - delivering important stability improvements and bug fixes. - - - - * Simplified, express-like API in the [TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - * Added 8 new clients to the [clients page](https://modelcontextprotocol.io/clients) - - - - * FastMCP API in the [Python SDK](https://github.com/modelcontextprotocol/python-sdk) - * Dockerized MCP servers in the [servers repo](https://github.com/modelcontextprotocol/servers) - - - - * Jetbrains released a Kotlin SDK for MCP! - * For a sample MCP Kotlin server, check out [this repository](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/kotlin-mcp-server) - - - -# Core architecture -Source: https://modelcontextprotocol.io/docs/concepts/architecture - -Understand how MCP connects clients, servers, and LLMs - -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. +* Remote MCP server integration +* Enterprise-grade security +* Low-latency, high-throughput interactions with structured data -## Overview +**Learn more:** -MCP follows a client-server architecture where: +* [Mistral MCP Documentation](https://help.mistral.ai/en/collections/911943-connectors) -* **Hosts** are LLM applications (like Claude Desktop or IDEs) that initiate connections -* **Clients** maintain 1:1 connections with servers, inside the host application -* **Servers** provide context, tools, and prompts to clients +### Msty Studio -```mermaid -flowchart LR - subgraph "Host" - client1[MCP Client] - client2[MCP Client] - end - subgraph "Server Process" - server1[MCP Server] - end - subgraph "Server Process" - server2[MCP Server] - end +[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. - client1 <-->|Transport Layer| server1 - client2 <-->|Transport Layer| server2 -``` +**Key features:** -## Core components +* **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. +* **Turnstiles**: Create automated, multi-step AI interactions, allowing for complex data processing and decision-making flows. +* **Real-Time Data Integration**: Enhance AI responses with up-to-date information by integrating real-time web search capabilities. +* **Split Chats & Branching**: Engage in parallel conversations with multiple models simultaneously, enabling comparative analysis and diverse perspectives. -### Protocol layer +**Learn more:** -The protocol layer handles message framing, request/response linking, and high-level communication patterns. +* [Msty Studio Documentation](https://docs.msty.studio/features/toolbox/tools) - - - ```typescript - class Protocol { - // Handle incoming requests - setRequestHandler(schema: T, handler: (request: T, extra: RequestHandlerExtra) => Promise): void +### Needle - // Handle incoming notifications - setNotificationHandler(schema: T, handler: (notification: T) => Promise): void +[Needle](https://needle.app) is a RAG workflow platform that also works as an MCP client, letting you connect and use MCP servers in seconds. - // Send requests and await responses - request(request: Request, schema: T, options?: RequestOptions): Promise +**Key features:** - // Send one-way notifications - notification(notification: Notification): Promise - } - ``` - +* **Instant MCP integration:** Connect any remote MCP server to your collection in seconds +* **Built-in RAG:** Automatically get retrieval-augmented generation out of the box +* **Secure OAuth:** Safe, token-based authorization when connecting to servers +* **Smart previews:** See what each MCP server can do and selectively enable the tools you need - - ```python - class Session(BaseSession[RequestT, NotificationT, ResultT]): - async def send_request( - self, - request: RequestT, - result_type: type[Result] - ) -> Result: - """Send request and wait for response. Raises McpError if response contains error.""" - # Request handling implementation +**Learn more:** - async def send_notification( - self, - notification: NotificationT - ) -> None: - """Send one-way notification that doesn't expect response.""" - # Notification handling implementation +* [Getting Started](https://docs.needle.app/docs/guides/hello-needle/getting-started/) +* [Needle MCP Client](https://docs.needle.app/docs/guides/mcp/getting-started/) - async def _received_request( - self, - responder: RequestResponder[ReceiveRequestT, ResultT] - ) -> None: - """Handle incoming request from other side.""" - # Request handling implementation +### NVIDIA Agent Intelligence (AIQ) toolkit - async def _received_notification( - self, - notification: ReceiveNotificationT - ) -> None: - """Handle incoming notification from other side.""" - # Notification handling implementation - ``` - - +[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. -Key classes include: +**Key features:** -* `Protocol` -* `Client` -* `Server` +* Acts as an MCP **client** to consume remote tools +* Acts as an MCP **server** to expose tools +* Framework agnostic and compatible with LangChain, CrewAI, Semantic Kernel, and custom agents +* Includes built-in observability and evaluation tools -### Transport layer +**Learn more:** -The transport layer handles the actual communication between clients and servers. MCP supports multiple transport mechanisms: +* [AIQ toolkit GitHub repository](https://github.com/NVIDIA/AIQToolkit) +* [AIQ toolkit MCP documentation](https://docs.nvidia.com/aiqtoolkit/latest/workflows/mcp/index.html) -1. **Stdio transport** - * Uses standard input/output for communication - * Ideal for local processes +### OpenSumi -2. **HTTP with SSE transport** - * Uses Server-Sent Events for server-to-client messages - * HTTP POST for client-to-server messages +[OpenSumi](https://github.com/opensumi/core) is a framework helps you quickly build AI Native IDE products. -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. +**Key features:** -### Message types +* Supports MCP tools in OpenSumi +* Supports built-in IDE MCP servers and custom MCP servers -MCP has these main types of messages: +### oterm -1. **Requests** expect a response from the other side: - ```typescript - interface Request { - method: string; - params?: { ... }; - } - ``` +[oterm] is a terminal client for Ollama allowing users to create chats/agents. -2. **Results** are successful responses to requests: - ```typescript - interface Result { - [key: string]: unknown; - } - ``` +**Key features:** -3. **Errors** indicate that a request failed: - ```typescript - interface Error { - code: number; - message: string; - data?: unknown; - } - ``` +* Support for multiple fully customizable chat sessions with Ollama connected with tools. +* Support for MCP tools. -4. **Notifications** are one-way messages that don't expect a response: - ```typescript - interface Notification { - method: string; - params?: { ... }; - } - ``` +### Roo Code -## Connection lifecycle +[Roo Code](https://roocode.com) enables AI coding assistance via MCP. -### 1. Initialization +**Key features:** -```mermaid -sequenceDiagram - participant Client - participant Server +* Support for MCP tools and resources +* Integration with development workflows +* Extensible AI capabilities - Client->>Server: initialize request - Server->>Client: initialize response - Client->>Server: initialized notification +### Postman - Note over Client,Server: Connection ready for use -``` +[Postman](https://postman.com/downloads) is the most popular API client and now supports MCP server testing and debugging. -1. Client sends `initialize` request with protocol version and capabilities -2. Server responds with its protocol version and capabilities -3. Client sends `initialized` notification as acknowledgment -4. Normal message exchange begins +**Key features:** -### 2. Message exchange +* Full support of all major MCP features (tools, prompts, resources, and subscriptions) +* Fast, seamless UI for debugging MCP capabilities +* MCP config integration (Claude, VSCode, etc.) for fast first-time experience in testing MCPs +* Integration with history, variables, and collections for reuse and collaboration -After initialization, the following patterns are supported: +### RecurseChat -* **Request-Response**: Client or server sends requests, the other responds -* **Notifications**: Either party sends one-way messages +[RecurseChat](https://recurse.chat) is a powerful, fast, local-first chat client with MCP support. RecurseChat supports multiple AI providers including LLaMA.cpp, Ollama, and OpenAI, Anthropic. -### 3. Termination +**Key features:** -Either party can terminate the connection: +* Local AI: Support MCP with Ollama models. +* MCP Tools: Individual MCP server management. Easily visualize the connection states of MCP servers. +* MCP Import: Import configuration from Claude Desktop app or JSON -* Clean shutdown via `close()` -* Transport disconnection -* Error conditions +**Learn more:** -## Error handling +* [RecurseChat docs](https://recurse.chat/docs/features/mcp/) -MCP defines these standard error codes: +### Shortwave -```typescript -enum ErrorCode { - // Standard JSON-RPC error codes - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603 -} -``` +[Shortwave](https://www.shortwave.com) is an AI-powered email client that supports MCP tools to enhance email productivity and workflow automation. -SDKs and applications can define their own error codes above -32000. +**Key features:** -Errors are propagated through: +* MCP tool integration for enhanced email workflows +* Rich UI for adding, managing and interacting with a wide range of MCP servers +* Support for both remote (Streamable HTTP and SSE) and local (Stdio) MCP servers +* AI assistance for managing your emails, calendar, tasks and other third-party services -* Error responses to requests -* Error events on transports -* Protocol-level error handlers +### Simtheory -## Implementation example +Simtheory is an agentic AI workspace that unifies multiple AI models, tools, and capabilities under a single subscription. It provides comprehensive MCP support through its MCP Store, allowing users to extend their workspace with productivity tools and integrations. -Here's a basic example of implementing an MCP server: +**Key features:** - - - ```typescript - import { Server } from "@modelcontextprotocol/sdk/server/index.js"; - import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +* **MCP Store**: Marketplace for productivity tools and MCP server integrations +* **Parallel Tasking**: Run multiple AI tasks simultaneously with MCP tool support +* **Model Catalogue**: Access to frontier models with MCP tool integration +* **Hosted MCP Servers**: Plug-and-play MCP integrations with no technical setup +* **Advanced MCPs**: Specialized tools like Tripo3D (3D creation), Podcast Maker, and Video Maker +* **Enterprise Ready**: Flexible workspaces with granular access control for MCP tools - const server = new Server({ - name: "example-server", - version: "1.0.0" - }, { - capabilities: { - resources: {} - } - }); +**Learn more:** - // Handle requests - server.setRequestHandler(ListResourcesRequestSchema, async () => { - return { - resources: [ - { - uri: "example://resource", - name: "Example Resource" - } - ] - }; - }); +* [Simtheory website](https://simtheory.ai) - // Connect transport - const transport = new StdioServerTransport(); - await server.connect(transport); - ``` - +### Slack MCP Client - - ```python - import asyncio - import mcp.types as types - from mcp.server import Server - from mcp.server.stdio import stdio_server - - app = Server("example-server") - - @app.list_resources() - async def list_resources() -> list[types.Resource]: - return [ - types.Resource( - uri="example://resource", - name="Example Resource" - ) - ] +[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. - async def main(): - async with stdio_server() as streams: - await app.run( - streams[0], - streams[1], - app.create_initialization_options() - ) +**Key features:** - if __name__ == "__main__": - asyncio.run(main()) - ``` - - +* **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. +* **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. +* **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. -## Best practices +### Smithery Playground -### Transport selection - -1. **Local communication** - * Use stdio transport for local processes - * Efficient for same-machine communication - * Simple process management - -2. **Remote communication** - * Use SSE for scenarios requiring HTTP compatibility - * Consider security implications including authentication and authorization - -### Message handling - -1. **Request processing** - * Validate inputs thoroughly - * Use type-safe schemas - * Handle errors gracefully - * Implement timeouts - -2. **Progress reporting** - * Use progress tokens for long operations - * Report progress incrementally - * Include total progress when known - -3. **Error management** - * Use appropriate error codes - * Include helpful error messages - * Clean up resources on errors - -## Security considerations - -1. **Transport security** - * Use TLS for remote connections - * Validate connection origins - * Implement authentication when needed - -2. **Message validation** - * Validate all incoming messages - * Sanitize inputs - * Check message size limits - * Verify JSON-RPC format - -3. **Resource protection** - * Implement access controls - * Validate resource paths - * Monitor resource usage - * Rate limit requests - -4. **Error handling** - * Don't leak sensitive information - * Log security-relevant errors - * Implement proper cleanup - * Handle DoS scenarios - -## Debugging and monitoring - -1. **Logging** - * Log protocol events - * Track message flow - * Monitor performance - * Record errors - -2. **Diagnostics** - * Implement health checks - * Monitor connection state - * Track resource usage - * Profile performance - -3. **Testing** - * Test different transports - * Verify error handling - * Check edge cases - * Load test servers +Smithery Playground is a developer-first MCP client for exploring, testing and debugging MCP servers against LLMs. It provides detailed traces of MCP RPCs to help troubleshoot implementation issues. +**Key features:** -# Prompts -Source: https://modelcontextprotocol.io/docs/concepts/prompts +* One-click connect to MCP servers via URL or from Smithery's registry +* Develop MCP servers that are running on localhost +* Inspect tools, prompts, resources, and sampling configurations with live previews +* Run conversational or raw tool calls to verify MCP behavior before shipping +* Full OAuth MCP-spec support -Create reusable prompt templates and workflows +### SpinAI -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. +[SpinAI](https://docs.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. - - 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. - +**Key features:** -## Overview +* Built-in MCP compatibility for AI agents +* Open-source TypeScript framework +* Observable agent architecture +* Native support for MCP tools integration -Prompts in MCP are predefined templates that can: +### Superinterface -* Accept dynamic arguments -* Include context from resources -* Chain multiple interactions -* Guide specific workflows -* Surface as UI elements (like slash commands) +[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. -## Prompt structure +**Key features:** -Each prompt is defined with: +* Use tools from MCP servers in assistants embedded via React components or script tags +* SSE transport support +* Use any AI model from any AI provider (OpenAI, Anthropic, Ollama, others) -```typescript -{ - name: string; // Unique identifier for the prompt - description?: string; // Human-readable description - arguments?: [ // Optional list of arguments - { - name: string; // Argument identifier - description?: string; // Argument description - required?: boolean; // Whether argument is required - } - ] -} -``` +### Superjoin -## Discovering prompts +[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. -Clients can discover available prompts through the `prompts/list` endpoint: +**Key features:** -```typescript -// Request -{ - method: "prompts/list" -} +* Native Google Sheets add-on providing effortless access to MCP capabilities +* Supports OAuth 2.1 and header-based authentication for secure and flexible connections +* Compatible with both SSE and Streamable HTTP transport for efficient, real-time streaming communication +* Fully web-based, cross-platform client requiring no additional software installation -// Response -{ - prompts: [ - { - name: "analyze-code", - description: "Analyze code for potential improvements", - arguments: [ - { - name: "language", - description: "Programming language", - required: true - } - ] - } - ] -} -``` +### Swarms -## Using prompts +[Swarms](https://github.com/kyegomez/swarms) is a production-grade multi-agent orchestration framework that supports MCP integration for dynamic tool discovery and execution. -To use a prompt, clients make a `prompts/get` request: +**Key features:** -````typescript -// Request -{ - method: "prompts/get", - params: { - name: "analyze-code", - arguments: { - language: "python" - } - } -} +* Connects to MCP servers via SSE transport for real-time tool integration +* Automatic tool discovery and loading from MCP servers +* Support for distributed tool functionality across multiple agents +* Enterprise-ready with high availability and observability features +* Modular architecture supporting multiple AI model providers -// Response -{ - description: "Analyze Python code for potential improvements", - messages: [ - { - role: "user", - content: { - type: "text", - 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```" - } - } - ] -} -```` +**Learn more:** -## Dynamic prompts +* [Swarms MCP Integration Documentation](https://docs.swarms.world/en/latest/swarms/tools/tools_examples/) +* [GitHub Repository](https://github.com/kyegomez/swarms) -Prompts can be dynamic and include: +### systemprompt -### Embedded resource context +[systemprompt](https://systemprompt.io) is a voice-controlled mobile app that manages your MCP servers. Securely leverage MCP agents from your pocket. Available on iOS and Android. -```json -{ - "name": "analyze-project", - "description": "Analyze project logs and code", - "arguments": [ - { - "name": "timeframe", - "description": "Time period to analyze logs", - "required": true - }, - { - "name": "fileUri", - "description": "URI of code file to review", - "required": true - } - ] -} -``` +**Key features:** -When handling the `prompts/get` request: +* **Native Mobile Experience**: Access and manage your MCP servers anytime, anywhere on both Android and iOS devices +* **Advanced AI-Powered Voice Recognition**: Sophisticated voice recognition engine enhanced with cutting-edge AI and Natural Language Processing (NLP), specifically tuned to understand complex developer terminology and command structures +* **Unified Multi-MCP Server Management**: Effortlessly manage and interact with multiple Model Context Protocol (MCP) servers from a single, centralized mobile application -```json -{ - "messages": [ - { - "role": "user", - "content": { - "type": "text", - "text": "Analyze these system logs and the code file for any issues:" - } - }, - { - "role": "user", - "content": { - "type": "resource", - "resource": { - "uri": "logs://recent?timeframe=1h", - "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", - "mimeType": "text/plain" - } - } - }, - { - "role": "user", - "content": { - "type": "resource", - "resource": { - "uri": "file:///path/to/code.py", - "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", - "mimeType": "text/x-python" - } - } - } - ] -} -``` +### Tambo -### Multi-step workflows +[Tambo](https://tambo.co) is a platform for building custom chat experiences in React, with integrated custom user interface components. -```typescript -const debugWorkflow = { - name: "debug-error", - async getMessages(error: string) { - return [ - { - role: "user", - content: { - type: "text", - text: `Here's an error I'm seeing: ${error}` - } - }, - { - role: "assistant", - content: { - type: "text", - text: "I'll help analyze this error. What have you tried so far?" - } - }, - { - role: "user", - content: { - type: "text", - text: "I've tried restarting the service, but the error persists." - } - } - ]; - } -}; -``` +**Key features:** -## Example implementation +* Hosted platform with React SDK for integrating chat or other LLM-based experiences into your own app. +* Support for selection of arbitrary React components in the chat experience, with state management and tool calling. +* Support for MCP servers, from Tambo's servers or directly from the browser. +* Supports OAuth 2.1 and custom header-based authentication. +* Support for MCP tools, with additional MCP features coming soon. -Here's a complete example of implementing prompts in an MCP server: +### Tencent CloudBase AI DevKit - - - ```typescript - import { Server } from "@modelcontextprotocol/sdk/server"; - import { - ListPromptsRequestSchema, - GetPromptRequestSchema - } from "@modelcontextprotocol/sdk/types"; - - const PROMPTS = { - "git-commit": { - name: "git-commit", - description: "Generate a Git commit message", - arguments: [ - { - name: "changes", - description: "Git diff or description of changes", - required: true - } - ] - }, - "explain-code": { - name: "explain-code", - description: "Explain how code works", - arguments: [ - { - name: "code", - description: "Code to explain", - required: true - }, - { - name: "language", - description: "Programming language", - required: false - } - ] - } - }; +[Tencent CloudBase AI DevKit](https://docs.cloudbase.net/ai/agent/mcp) is a tool for building AI agents in minutes, featuring zero-code tools, secure data integration, and extensible plugins via MCP. - const server = new Server({ - name: "example-prompts-server", - version: "1.0.0" - }, { - capabilities: { - prompts: {} - } - }); +**Key features:** - // List available prompts - server.setRequestHandler(ListPromptsRequestSchema, async () => { - return { - prompts: Object.values(PROMPTS) - }; - }); +* Support for MCP tools +* Extend agents with MCP servers +* MCP servers hosting: serverless hosting and authentication support - // Get specific prompt - server.setRequestHandler(GetPromptRequestSchema, async (request) => { - const prompt = PROMPTS[request.params.name]; - if (!prompt) { - throw new Error(`Prompt not found: ${request.params.name}`); - } +### TheiaAI/TheiaIDE - if (request.params.name === "git-commit") { - return { - messages: [ - { - role: "user", - content: { - type: "text", - text: `Generate a concise but descriptive commit message for these changes:\n\n${request.params.arguments?.changes}` - } - } - ] - }; - } +[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. - if (request.params.name === "explain-code") { - const language = request.params.arguments?.language || "Unknown"; - return { - messages: [ - { - role: "user", - content: { - type: "text", - text: `Explain how this ${language} code works:\n\n${request.params.arguments?.code}` - } - } - ] - }; - } +**Key features:** - throw new Error("Prompt implementation not found"); - }); - ``` - +* **Tool Integration**: Theia AI enables AI agents, including those in the Theia IDE, to utilize MCP servers for seamless tool interaction. +* **Customizable Prompts**: The Theia IDE allows users to define and adapt prompts, dynamically integrating MCP servers for tailored workflows. +* **Custom agents**: The Theia IDE supports creating custom agents that leverage MCP capabilities, enabling users to design dedicated workflows on the fly. - - ```python - from mcp.server import Server - import mcp.types as types - - # Define available prompts - PROMPTS = { - "git-commit": types.Prompt( - name="git-commit", - description="Generate a Git commit message", - arguments=[ - types.PromptArgument( - name="changes", - description="Git diff or description of changes", - required=True - ) - ], - ), - "explain-code": types.Prompt( - name="explain-code", - description="Explain how code works", - arguments=[ - types.PromptArgument( - name="code", - description="Code to explain", - required=True - ), - types.PromptArgument( - name="language", - description="Programming language", - required=False - ) - ], - ) - } +Theia AI and Theia IDE's MCP integration provide users with flexibility, making them powerful platforms for exploring and adapting MCP. - # Initialize server - app = Server("example-prompts-server") - - @app.list_prompts() - async def list_prompts() -> list[types.Prompt]: - return list(PROMPTS.values()) - - @app.get_prompt() - async def get_prompt( - name: str, arguments: dict[str, str] | None = None - ) -> types.GetPromptResult: - if name not in PROMPTS: - raise ValueError(f"Prompt not found: {name}") - - if name == "git-commit": - changes = arguments.get("changes") if arguments else "" - return types.GetPromptResult( - messages=[ - types.PromptMessage( - role="user", - content=types.TextContent( - type="text", - text=f"Generate a concise but descriptive commit message " - f"for these changes:\n\n{changes}" - ) - ) - ] - ) +**Learn more:** - if name == "explain-code": - code = arguments.get("code") if arguments else "" - language = arguments.get("language", "Unknown") if arguments else "Unknown" - return types.GetPromptResult( - messages=[ - types.PromptMessage( - role="user", - content=types.TextContent( - type="text", - text=f"Explain how this {language} code works:\n\n{code}" - ) - ) - ] - ) +* [Theia IDE and Theia AI MCP Announcement](https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/) +* [Download the AI-powered Theia IDE](https://theia-ide.org/) - raise ValueError("Prompt implementation not found") - ``` - - +### Tome -## Best practices +[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. -When implementing prompts: +**Key features:** -1. Use clear, descriptive prompt names -2. Provide detailed descriptions for prompts and arguments -3. Validate all required arguments -4. Handle missing arguments gracefully -5. Consider versioning for prompt templates -6. Cache dynamic content when appropriate -7. Implement error handling -8. Document expected argument formats -9. Consider prompt composability -10. Test prompts with various inputs +* MCP servers are managed by Tome so there is no need to install uv or npm or configure JSON +* Users can quickly add or remove MCP servers via UI +* Any tool-supported local model on Ollama is compatible -## UI integration +### TypingMind App -Prompts can be surfaced in client UIs as: +[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. -* Slash commands -* Quick actions -* Context menu items -* Command palette entries -* Guided workflows -* Interactive forms +**Key features:** -## Updates and changes +* **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. +* **Assign MCP Tools to Agents**: TypingMind allows users to create AI agents that have a set of MCP servers assigned. +* **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. -Servers can notify clients about prompt changes: +**Learn more:** -1. Server capability: `prompts.listChanged` -2. Notification: `notifications/prompts/list_changed` -3. Client re-fetches prompt list +* [TypingMind MCP Document](https://www.typingmind.com/mcp) +* [Download TypingMind (PWA)](https://www.typingmind.com/) -## Security considerations +### VS Code GitHub Copilot -When implementing prompts: +[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. -* Validate all arguments -* Sanitize user input -* Consider rate limiting -* Implement access controls -* Audit prompt usage -* Handle sensitive data appropriately -* Validate generated content -* Implement timeouts -* Consider prompt injection risks -* Document security requirements +**Key features:** +* Support for stdio and server-sent events (SSE) transport +* Per-session selection of tools per agent session for optimal performance +* Easy server debugging with restart commands and output logging +* Tool calls with editable inputs and always-allow toggle +* Integration with existing VS Code extension system to register MCP servers from extensions -# Resources -Source: https://modelcontextprotocol.io/docs/concepts/resources +### Warp -Expose data and content from your servers to LLMs +[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. -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. +**Key features:** - - Resources are designed to be **application-controlled**, meaning that the client application can decide how and when they should be used. - Different MCP clients may handle resources differently. For example: +* **Agent Mode with MCP support**: invoke tools and access data from MCP servers using natural language prompts +* **Flexible server management**: add and manage CLI or SSE-based MCP servers via Warp's built-in UI +* **Live tool/resource discovery**: view tools and resources from each running MCP server +* **Configurable startup**: set MCP servers to start automatically with Warp or launch them manually as needed - * Claude Desktop currently requires users to explicitly select resources before they can be used - * Other clients might automatically select resources based on heuristics - * Some implementations may even allow the AI model itself to determine which resources to use +### WhatsMCP - 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). - +[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. -## Overview +**Key features:** -Resources represent any kind of data that an MCP server wants to make available to clients. This can include: +* Supports MCP tools +* SSE transport, full OAuth2 support +* Chat flow management for WhatsApp messages +* One click setup for connecting to your MCP servers +* In chat management of MCP servers +* Oauth flow natively supported in WhatsApp -* File contents -* Database records -* API responses -* Live system data -* Screenshots and images -* Log files -* And more +### Windsurf Editor -Each resource is identified by a unique URI and can contain either text or binary data. +[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. -## Resource URIs +**Key features:** -Resources are identified using URIs that follow this format: +* Revolutionary AI Flow paradigm for human-AI collaboration +* Intelligent code generation and understanding +* Rich development tools with multi-model support -``` -[protocol]://[host]/[path] -``` +### Witsy -For example: +[Witsy](https://github.com/nbonamy/witsy) is an AI desktop assistant, supporting Anthropic models and MCP servers as LLM tools. -* `file:///home/user/documents/report.pdf` -* `postgres://database/customers/schema` -* `screen://localhost/display1` +**Key features:** -The protocol and path structure is defined by the MCP server implementation. Servers can define their own custom URI schemes. +* Multiple MCP servers support +* Tool integration for executing commands and scripts +* Local server connections for enhanced privacy and security +* Easy-install from Smithery.ai +* Open-source, available for macOS, Windows and Linux -## Resource types +### Zed -Resources can contain two types of content: +[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. -### Text resources +**Key features:** -Text resources contain UTF-8 encoded text data. These are suitable for: +* Prompt templates surface as slash commands in the editor +* Tool integration for enhanced coding workflows +* Tight integration with editor features and workspace context +* Does not support MCP resources -* Source code -* Configuration files -* Log files -* JSON/XML data -* Plain text +### Zencoder -### Binary resources +[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. -Binary resources contain raw binary data encoded in base64. These are suitable for: +**Key features:** -* Images -* PDFs -* Audio files -* Video files -* Other non-text formats +* RepoGrokking - deep contextual understanding of codebases +* Agentic pipeline - runs, tests, and executes code before outputting it +* Zen Agents platform - ability to build and create custom agents and share with the team +* Integrated MCP tool library with one-click installations +* Specialized agents for Unit and E2E Testing -## Resource discovery +**Learn more:** -Clients can discover available resources through two main methods: +* [Zencoder Documentation](https://docs.zencoder.ai) -### Direct resources +## Adding MCP support to your application -Servers expose a list of concrete resources via the `resources/list` endpoint. Each resource includes: +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. -```typescript -{ - uri: string; // Unique identifier for the resource - name: string; // Human-readable name - description?: string; // Optional description - mimeType?: string; // Optional MIME type -} -``` +Benefits of adding MCP support: -### Resource templates +* Enable users to bring their own context and tools +* Join a growing ecosystem of interoperable AI applications +* Provide users with flexible integration options +* Support local-first AI workflows -For dynamic resources, servers can expose [URI templates](https://datatracker.ietf.org/doc/html/rfc6570) that clients can use to construct valid resource URIs: +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) -```typescript -{ - uriTemplate: string; // URI template following RFC 6570 - name: string; // Human-readable name for this type - description?: string; // Optional description - mimeType?: string; // Optional MIME type for all matching resources -} -``` +## Updates and corrections -## Reading resources +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). -To read a resource, clients make a `resources/read` request with the resource URI. -The server responds with a list of resource contents: +# Antitrust Policy +Source: https://modelcontextprotocol.io/community/antitrust -```typescript -{ - contents: [ - { - uri: string; // The URI of the resource - mimeType?: string; // Optional MIME type +MCP Project Antitrust Policy for participants and contributors - // One of: - text?: string; // For text resources - blob?: string; // For binary resources (base64 encoded) - } - ] -} -``` +**Effective: September 29, 2025** - - 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. - +## Introduction -## Resource updates +The goal of the Model Context Protocol open source project (the "Project") is to develop a universal standard for model-to-world interactions, including enabling LLMs and agents to seamlessly connect with and utilize external data sources and tools. The purpose of this Antitrust Policy (the "Policy") is to avoid antitrust risks in carrying out this pro-competitive mission. -MCP supports real-time updates for resources through two mechanisms: +Participants in and contributors to the Project (collectively, "participants") will use their best reasonable efforts to comply in all respects with all applicable state and federal antitrust and trade regulation laws, and applicable antitrust/competition laws of other countries (collectively, the "Antitrust Laws"). -### List changes +The goal of Antitrust Laws is to encourage vigorous competition. Nothing in this Policy prohibits or limits the ability of participants to make, sell or use any product, or otherwise to compete in the marketplace. This Policy provides general guidance on compliance with Antitrust Law. Participants should contact their respective legal counsel to address specific questions. -Servers can notify clients when their list of available resources changes via the `notifications/resources/list_changed` notification. +This Policy is conservative and is intended to promote compliance with the Antitrust Laws, not to create duties or obligations beyond what the Antitrust Laws actually require. In the event of any inconsistency between this Policy and the Antitrust Laws, the Antitrust Laws preempt and control. -### Content changes +## Participation -Clients can subscribe to updates for specific resources: +Technical participation in the Project shall be open to all, subject only to compliance with the provisions of the Project's charter and other governance documents. -1. Client sends `resources/subscribe` with resource URI -2. Server sends `notifications/resources/updated` when the resource changes -3. Client can fetch latest content with `resources/read` -4. Client can unsubscribe with `resources/unsubscribe` +## Conduct of Meetings -## Example implementation +At meetings among actual or potential competitors, there is a risk that participants in those meetings may improperly disclose or discuss information in violation of the Antitrust Laws or otherwise act in an anti-competitive manner. To avoid this risk, participants must adhere to the following policies when participating in Project-related or sponsored meetings, conference calls, or other forums (collectively, "Project Meetings"). -Here's a simple example of implementing resource support in an MCP server: +Participants must not, in fact or appearance, discuss or exchange information regarding: - - - ```typescript - const server = new Server({ - name: "example-server", - version: "1.0.0" - }, { - capabilities: { - resources: {} - } - }); +* An individual company's current or projected prices, price changes, price differentials, markups, discounts, allowances, terms and conditions of sale, including credit terms, etc., or data that bear on prices, including profits, margins or cost. +* Industry-wide pricing policies, price levels, price changes, differentials, or the like. +* Actual or projected changes in industry production, capacity or inventories. +* Matters relating to bids or intentions to bid for particular products, procedures for responding to bid invitations or specific contractual arrangements. +* Plans of individual companies concerning the design, characteristics, production, distribution, marketing or introduction dates of particular products, including proposed territories or customers. +* Matters relating to actual or potential individual suppliers that might have the effect of excluding them from any market or of influencing the business conduct of firms toward such suppliers. +* Matters relating to actual or potential customers that might have the effect of influencing the business conduct of firms toward such customers. +* Individual company current or projected cost of procurement, development or manufacture of any product. +* Individual company market shares for any product or for all products. +* Confidential or otherwise sensitive business plans or strategy. - // List available resources - server.setRequestHandler(ListResourcesRequestSchema, async () => { - return { - resources: [ - { - uri: "file:///logs/app.log", - name: "Application Logs", - mimeType: "text/plain" - } - ] - }; - }); +In connection with all Project Meetings, participants must do the following: - // Read resource contents - server.setRequestHandler(ReadResourceRequestSchema, async (request) => { - const uri = request.params.uri; +* Adhere to prepared agendas. +* Insist that meeting minutes be prepared and distributed to all participants, and that meeting minutes accurately reflect the matters that transpired. +* Consult with their respective counsel on all antitrust questions related to Project Meetings. +* Protest against any discussions that appear to violate these policies or the Antitrust Laws, leave any meeting in which such discussions continue, and either insist that such protest be noted in the minutes. - if (uri === "file:///logs/app.log") { - const logContents = await readLogFile(); - return { - contents: [ - { - uri, - mimeType: "text/plain", - text: logContents - } - ] - }; - } +## Requirements/Standard Setting - throw new Error("Resource not found"); - }); - ``` - +The Project may establish standards, technical requirements and/or specifications for use (collectively, "requirements"). Participants shall not enter into agreements that prohibit or restrict any participant from establishing or adopting any other requirements. Participants shall not undertake any efforts, directly or indirectly, to prevent any firm from manufacturing, selling, or supplying any product not conforming to a requirement. - - ```python - app = Server("example-server") - - @app.list_resources() - async def list_resources() -> list[types.Resource]: - return [ - types.Resource( - uri="file:///logs/app.log", - name="Application Logs", - mimeType="text/plain" - ) - ] +The Project shall not promote standardization of commercial terms, such as terms for license and sale. - @app.read_resource() - async def read_resource(uri: AnyUrl) -> str: - if str(uri) == "file:///logs/app.log": - log_contents = await read_log_file() - return log_contents +## Contact Information - raise ValueError("Resource not found") +To contact the Project regarding matters addressed by this Antitrust Policy, please send an email to [antitrust@modelcontextprotocol.io](mailto:antitrust@modelcontextprotocol.io), and reference "Antitrust Policy" in the subject line. - # Start server - async with stdio_server() as streams: - await app.run( - streams[0], - streams[1], - app.create_initialization_options() - ) - ``` - - -## Best practices +# Contributor Communication +Source: https://modelcontextprotocol.io/community/communication -When implementing resource support: +Communication strategy and framework for the Model Context Protocol community -1. Use clear, descriptive resource names and URIs -2. Include helpful descriptions to guide LLM understanding -3. Set appropriate MIME types when known -4. Implement resource templates for dynamic content -5. Use subscriptions for frequently changing resources -6. Handle errors gracefully with clear error messages -7. Consider pagination for large resource lists -8. Cache resource contents when appropriate -9. Validate URIs before processing -10. Document your custom URI schemes +This document explains how to communicate and collaborate within the Model Context Protocol (MCP) project. -## Security considerations +## Communication Channels -When exposing resources: +In short: -* Validate all resource URIs -* Implement appropriate access controls -* Sanitize file paths to prevent directory traversal -* Be cautious with binary data handling -* Consider rate limiting for resource reads -* Audit resource access -* Encrypt sensitive data in transit -* Validate MIME types -* Implement timeouts for long-running reads -* Handle resource cleanup appropriately +* **[Discord][discord-join]**: For real-time or ad-hoc discussions. +* **[GitHub Discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions)**: For structured, longer-form discussions. +* **[GitHub Issues](https://github.com/modelcontextprotocol/modelcontextprotocol/issues)**: For actionable tasks, bug reports, and feature requests. +* **For security-sensitive issues**: Follow the process in [SECURITY.md](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/SECURITY.md). +All communication is governed by our [Code of Conduct](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/CODE_OF_CONDUCT.md). We expect all participants to maintain respectful, professional, and inclusive interactions across all channels. -# Roots -Source: https://modelcontextprotocol.io/docs/concepts/roots +### Discord -Understanding roots in MCP +For real-time contributor discussion and collaboration. The server is designed around **MCP contributors** and is not intended +to be a place for general MCP support. -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. +The Discord server will have both public and private channels. -## What are Roots? +[Join the Discord server here][discord-join]. -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. +#### Public Channels (Default) -For example, roots could be: +* **Purpose**: Open community engagement, collaborative development, and transparent project coordination. +* Primary use cases: + * **Public SDK and tooling development**: All development, from ideation to release planning, happens in public channels (e.g., `#typescript-sdk-dev`, `#inspector-dev`). + * **[Working and Interest Group](/community/working-interest-groups) discussions** + * **Community onboarding** and contribution guidance. + * **Community feedback** and collaborative brainstorming. + * Public **office hours** and **maintainer availability**. +* Avoid: + * MCP user support: participants are expected to read official documentation and start new GitHub Discussions for questions or support. + * Service or product marketing: interactions on this Discord are expected to be vendor-neutral and not used for brand-building or sales. Mentions of brands or products are discouraged outside of being used as examples or responses to conversations that start off focused on the specification. -``` -file:///home/user/projects/myapp -https://api.example.com/v1 -``` +#### Private channels (Exceptions) -## Why Use Roots? +* **Purpose**: Confidential coordination and sensitive matters that cannot be discussed publicly. Access will be restricted to designated maintainers. +* **Strict criteria for private use**: + * **Security incidents** (CVEs, protocol vulnerabilities). + * **People matters** (maintainer-related discussions, code of conduct policies). + * Select channels will be configured to be **read-only**. This can be good for example for maintainer decision making. + * Coordination requiring **immediate** or otherwise **focused response** with a limited audience. +* **Transparency**: + * **All technical and governance decisions** affecting the community **must be documented** in GitHub Discussions and/or Issues, and will be labeled with `notes`. + * **Some matters related to individual contributors** may remain private when appropriate (e.g., personal circumstances, disciplinary actions, or other sensitive individual matters). + * Private channels are to be used as **temporary "incident rooms,"** not for routine development. -Roots serve several important purposes: +Any significant discussion on Discord that leads to a potential decision or proposal must be moved to a GitHub Discussion or GitHub Issue to create a persistent, searchable record. Proposals will then be promoted to full-fledged PRs with associated work items (GitHub Issues) as needed. -1. **Guidance**: They inform servers about relevant resources and locations -2. **Clarity**: Roots make it clear which resources are part of your workspace -3. **Organization**: Multiple roots let you work with different resources simultaneously +### GitHub Discussions -## How Roots Work +For structured, long-form discussion and debate on project direction, features, improvements, and community topics. -When a client supports roots, it: +When to use: -1. Declares the `roots` capability during connection -2. Provides a list of suggested roots to the server -3. Notifies the server when roots change (if supported) +* Project roadmap planning and milestone discussions +* Announcements and release communications +* Community polls and consensus-building processes +* Feature requests with context and rationale + * If a particular repository does not have GitHub Discussions enabled, feel free to open a GitHub Issue instead. -While roots are informational and not strictly enforcing, servers should: +### GitHub Issues -1. Respect the provided roots -2. Use root URIs to locate and access resources -3. Prioritize operations within root boundaries +For bug reports, feature tracking, and actionable development tasks. -## Common Use Cases +When to use: -Roots are commonly used to define: +* Submit SEP proposals (following the [SEP guidelines](./sep-guidelines)) +* Bug reports with reproducible steps +* Documentation improvements with specific scope +* CI/CD problems and infrastructure issues +* Release tasks and milestone tracking -* Project directories -* Repository locations -* API endpoints -* Configuration locations -* Resource boundaries +### Security Issues -## Best Practices +**Do not post security issues publicly.** Instead: -When working with roots: +1. Use the private security reporting process. For protocol-level security issues, follow the process in [SECURITY.md in the modelcontextprotocol GitHub repository](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/SECURITY.md). +2. Contact lead and/or [core maintainers](./governance#current-core-maintainers) directly. +3. Follow responsible disclosure guidelines. -1. Only suggest necessary resources -2. Use clear, descriptive names for roots -3. Monitor root accessibility -4. Handle root changes gracefully +## Decision Records -## Example +All MCP decisions are documented and captured in public channels. -Here's how a typical MCP client might expose roots: +* **Technical decisions**: [GitHub Issues](https://github.com/modelcontextprotocol/modelcontextprotocol/issues) and SEPs. +* **Specification changes**: [On the Model Context Protocol website](https://modelcontextprotocol.io/specification/draft/changelog). +* **Process changes**: [Community documentation](https://modelcontextprotocol.io/community/governance). +* **Governance decisions and updates**: [GitHub Issues](https://github.com/modelcontextprotocol/modelcontextprotocol/issues) and SEPs. -```json -{ - "roots": [ - { - "uri": "file:///home/user/projects/frontend", - "name": "Frontend Repository" - }, - { - "uri": "https://api.example.com/v1", - "name": "API Endpoint" - } - ] -} -``` +When documenting decisions, we will retain as much context as possible: -This configuration suggests the server focus on both a local repository and an API endpoint while keeping them logically separated. +* Decision makers +* Background context and motivation +* Options that were considered +* Rationale for the chosen approach +* Implementation steps +[discord-join]: https://discord.gg/6CSzBmMkjX -# Sampling -Source: https://modelcontextprotocol.io/docs/concepts/sampling -Let your servers request completions from LLMs +# Governance and Stewardship +Source: https://modelcontextprotocol.io/community/governance -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. +Learn about the Model Context Protocol's governance structure and how to participate in the community - - This feature of MCP is not yet supported in the Claude Desktop client. - +The Model Context Protocol (MCP) follows a formal governance model to ensure transparent decision-making and community participation. This document outlines how the project is organized and how decisions are made. -## How sampling works +## Technical Governance -The sampling flow follows these steps: +The MCP project adopts a hierarchical structure, similar to Python, PyTorch and other open source projects: -1. Server sends a `sampling/createMessage` request to the client -2. Client reviews the request and can modify it -3. Client samples from an LLM -4. Client reviews the completion -5. Client returns the result to the server +* A community of **contributors** who file issues, make pull requests, and contribute to the project. +* A small set of **maintainers** drive components within the MCP project, such as SDKs, documentation, and others. +* Contributors and maintainers are overseen by **core maintainers**, who drive the overall project direction. +* The core maintainers have two **lead core maintainers** who are the catch-all decision makers. +* Maintainers, core maintainers, and lead core maintainers form the **MCP steering group**. -This human-in-the-loop design ensures users maintain control over what the LLM sees and generates. +All maintainers are expected to have a strong bias towards MCP's design philosophy. Membership in the technical governance process is for individuals, not companies. That is, there are no seats reserved for specific companies, and membership is associated with the person rather than the company employing that person. This ensures that maintainers act in the best interests of the protocol itself and the open source community. -## Message format +### Channels -Sampling requests use a standardized message format: +Technical Governance is facilitated through a shared [Discord server](/community/communication#discord) of all **maintainers, core maintainers** and **lead maintainers**. Each maintainer group can choose additional communication channels, but all decisions and their supporting discussions must be recorded and made transparently available on the Discord server. -```typescript -{ - messages: [ - { - role: "user" | "assistant", - content: { - type: "text" | "image", +### Maintainers - // For text: - text?: string, +Maintainers are responsible for [Working or Interest Groups](/community/working-interest-groups) within the MCP project. These generally are independent repositories such as language-specific SDKs, but can also extend to subdirectories of a repository, such as the MCP documentation. Maintainers may adopt their own rules and procedures for making decisions. Maintainers are expected to make decisions for their respective projects independently, but can defer or escalate to the core maintainers when needed. - // For images: - data?: string, // base64 encoded - mimeType?: string - } - } - ], - modelPreferences?: { - hints?: [{ - name?: string // Suggested model name/family - }], - costPriority?: number, // 0-1, importance of minimizing cost - speedPriority?: number, // 0-1, importance of low latency - intelligencePriority?: number // 0-1, importance of capabilities - }, - systemPrompt?: string, - includeContext?: "none" | "thisServer" | "allServers", - temperature?: number, - maxTokens: number, - stopSequences?: string[], - metadata?: Record -} -``` +Maintainers are responsible for the: -## Request parameters +* Thoughtful and productive engagement with community contributors, +* Maintaining and improving their respective area of the MCP project, +* Supporting documentation, roadmaps and other adjacent parts of the MCP project, +* Present ideas from community to core. -### Messages +Maintainers are encouraged to propose additional maintainers when needed. Maintainers can only be appointed and removed by core maintainers or lead core maintainers at any time and without reason. -The `messages` array contains the conversation history to send to the LLM. Each message has: +Maintainers have write and/or admin access to their respective repositories. -* `role`: Either "user" or "assistant" -* `content`: The message content, which can be: - * Text content with a `text` field - * Image content with `data` (base64) and `mimeType` fields +### Core Maintainers -### Model preferences +The core maintainers are expected to have a deep understanding of the Model Context Protocol and its specification. Their responsibilities include: -The `modelPreferences` object allows servers to specify their model selection preferences: +* Designing, reviewing and steering the evolution of the MCP specification, as well as all other parts of the MCP project, such as documentation, +* Articulating a cohesive long-term vision for the project, +* Mediating and resolving contentious issues with fairness and transparency, seeking consensus where possible while making decisive choices when necessary, +* Appoint or remove maintainers, +* Stewardship of the MCP project in the best interest of MCP. -* `hints`: Array of model name suggestions that clients can use to select an appropriate model: - * `name`: String that can match full or partial model names (e.g. "claude-3", "sonnet") - * Clients may map hints to equivalent models from different providers - * Multiple hints are evaluated in preference order +The core maintainers as a group have the power to veto any decisions made by maintainers by majority vote. The core maintainers have power to resolve disputes as they see fit. The core maintainers should publicly articulate their decision-making. The core group is responsible for adopting their own procedures for making decisions. -* Priority values (0-1 normalized): - * `costPriority`: Importance of minimizing costs - * `speedPriority`: Importance of low latency response - * `intelligencePriority`: Importance of advanced model capabilities +Core maintainers generally have write and admin access to all MCP repositories, but should use the same contribution (usually pull-requests) mechanism as outside contributors. Exceptions can be made based on security considerations. -Clients make the final model selection based on these preferences and their available models. +### Lead Maintainers (BDFL) -### System prompt +MCP has two lead maintainers: Justin Spahr-Summers and David Soria Parra. Lead Maintainers can veto any decision by core maintainers or maintainers. This model is also commonly known as Benevolent Dictator for Life (BDFL) in the open source community. The Lead Maintainers should publicly articulate their decision-making and give clear reasoning for their decisions. Lead maintainers are part of the core maintainer group. -An optional `systemPrompt` field allows servers to request a specific system prompt. The client may modify or ignore this. +The Lead Maintainers are responsible for confirming or removing core maintainers. -### Context inclusion +Lead Maintainers are administrators on all infrastructure for the MCP project where possible. This includes but is not restricted to all communication channels, GitHub organizations and repositories. -The `includeContext` parameter specifies what MCP context to include: +### Decision Process -* `"none"`: No additional context -* `"thisServer"`: Include context from the requesting server -* `"allServers"`: Include context from all connected MCP servers +The core maintainer group meets every two weeks to discuss and vote on proposals, as well as discuss any topics needed. The shared Discord server can be used to discuss and vote on smaller proposals if needed. -The client controls what context is actually included. +The lead maintainer, core maintainer, and maintainer group should attempt to meet in person every three to six months. -### Sampling parameters +## Processes -Fine-tune the LLM sampling with: +Core and lead maintainers are responsible for all aspects of Model Context Protocol, including documentation, issues, suggestions for content, and all other parts under the [MCP project](https://github.com/modelcontextprotocol). Maintainers are responsible for documentation, issues, and suggestions of content for their area of the MCP project, but are encouraged to partake in general maintenance of the MCP projects. Maintainers, core maintainers, and lead maintainers should use the same contribution process as external contributors, rather than making direct changes to repos. This provides insight into intent and opportunity for discussion. -* `temperature`: Controls randomness (0.0 to 1.0) -* `maxTokens`: Maximum tokens to generate -* `stopSequences`: Array of sequences that stop generation -* `metadata`: Additional provider-specific parameters +### Working and Interest Groups -## Response format +MCP collaboration and contributions are organized around two structures: [Working Groups and Interest Groups](/community/working-interest-groups). -The client returns a completion result: +Interest Groups are responsible for identifying and articulating problems that MCP should address, primarily by facilitating open discussions within the community. In contrast, Working Groups focus on developing concrete solutions by collaboratively producing deliverables, such as SEPs or community-owned implementations of the specification. While input from Interest Groups can help justify the formation of a Working Group, it is not a strict requirement. Similarly, contributions from either Interest Groups or Working Groups are encouraged, but not mandatory, when submitting SEPs or other community proposals. -```typescript -{ - model: string, // Name of the model used - stopReason?: "endTurn" | "stopSequence" | "maxTokens" | string, - role: "user" | "assistant", - content: { - type: "text" | "image", - text?: string, - data?: string, - mimeType?: string - } -} -``` +We strongly encourage all contributors interested in working on a specific SEP to first collaborate within an Interest Group. This collaborative process helps ensure that the proposed SEP aligns with protocol needs and is the right direction for its adopters. -## Example request +#### Governance Principles -Here's an example of requesting sampling from a client: +All groups are self-governed while adhering to these core principles: -```json -{ - "method": "sampling/createMessage", - "params": { - "messages": [ - { - "role": "user", - "content": { - "type": "text", - "text": "What files are in the current directory?" - } - } - ], - "systemPrompt": "You are a helpful file system assistant.", - "includeContext": "thisServer", - "maxTokens": 100 - } -} -``` +1. Clear contribution and decision-making processes +2. Open communication and transparent decisions -## Best practices +Both must: -When implementing sampling: +* Document their contribution process +* Maintain transparent communication +* Make decisions publicly (groups must publish meeting notes and proposals) -1. Always provide clear, well-structured prompts -2. Handle both text and image content appropriately -3. Set reasonable token limits -4. Include relevant context through `includeContext` -5. Validate responses before using them -6. Handle errors gracefully -7. Consider rate limiting sampling requests -8. Document expected sampling behavior -9. Test with various model parameters -10. Monitor sampling costs +Projects and working groups without specified processes default to: -## Human in the loop controls +* GitHub pull requests and issues for contributions +* A public channel in the official [MCP Contributor Discord](/community/communication#discord) -Sampling is designed with human oversight in mind: +#### Maintenance Responsibilities -### For prompts +Components without dedicated maintainers (such as documentation) fall under core maintainer responsibility. These follow standard contribution guidelines through pull requests, with maintainers handling reviews and escalating to core maintainer review for any significant changes. -* Clients should show users the proposed prompt -* Users should be able to modify or reject prompts -* System prompts can be filtered or modified -* Context inclusion is controlled by the client +Core maintainers and maintainers are encouraged to improve any part of the MCP project, regardless of formal maintenance assignments. -### For completions +### Specification Project -* Clients should show users the completion -* Users should be able to modify or reject completions -* Clients can filter or modify completions -* Users control which model is used +#### Specification Enhancement Proposal (SEP) -## Security considerations +Proposed changes to the specification must come in the form of a written version, starting with a summary of the proposal, outlining the **problem** it tries to solve, propose **solution**, **alternatives**, **considerations, outcomes** and **risks**. The [SEP Guidelines](/community/sep-guidelines) outline information on the expected structure of SEPs. SEP's should be created as issues in the [specification repository](https://github.com/modelcontextprotocol/specification) and tagged with the labels `proposal, sep`. -When implementing sampling: +All proposals must have a **sponsor** from the MCP steering group (maintainer, core maintainer or lead core maintainer). The sponsor is responsible for ensuring that the proposal is actively developed, meets the quality standard for proposals and is responsible for presenting and discussing it in meetings of core maintainers. Maintainer and Core Maintainer groups should review open proposals without sponsors in regular intervals. Proposals that do not find a sponsor within six months are automatically rejected. -* Validate all message content -* Sanitize sensitive information -* Implement appropriate rate limits -* Monitor sampling usage -* Encrypt data in transit -* Handle user data privacy -* Audit sampling requests -* Control cost exposure -* Implement timeouts -* Handle model errors gracefully +Once proposals have a sponsor, they are assigned to the sponsor and are tagged `draft`. -## Common patterns +## Communication -### Agentic workflows +### Core Maintainer Meetings -Sampling enables agentic patterns like: +The core maintainer group meets on a bi-weekly basis to discuss proposals and the project. Notes on proposals should be made public. The core maintainer group will strive to meet in person every 3-6 months. -* Reading and analyzing resources -* Making decisions based on context -* Generating structured data -* Handling multi-step tasks -* Providing interactive assistance +### Public Chat -### Context management +The MCP project maintains a [public Discord server](/community/communication#discord) with open chats for interest groups. The MCP project may have private channels for certain communications. -Best practices for context: +## Nominating, Confirming and Removing Maintainers -* Request minimal necessary context -* Structure context clearly -* Handle context size limits -* Update context as needed -* Clean up stale context +### The Principles -### Error handling +* Membership in module maintainer groups is given to **individuals** on merit basis after they demonstrated strong expertise of their area of work through contributions, reviews, and discussions and are aligned with the overall MCP direction. +* For membership in the **maintainer** group the individual has to demonstrate strong and continued alignment with the overall MCP principles. +* No term limits for module maintainers or core maintainers +* Light criteria of moving working-group or sub-project maintenance to 'emeritus' status if they don't actively participate over long periods of time. Each maintainer group may define the inactive period that's appropriate for their area. +* The membership is for an individual, not a company. -Robust error handling should: +### Nomination and Removal -* Catch sampling failures -* Handle timeout errors -* Manage rate limits -* Validate responses -* Provide fallback behaviors -* Log errors appropriately +* Core Maintainers are responsible for adding and removing maintainers. They will take the consideration of existing maintainers into account. +* The lead maintainers are responsible for adding and removing core maintainers. -## Limitations +#### Nomination Process -Be aware of these limitations: +If a Maintainer (or Core / Lead Maintainer) wishes to propose a nomination for the Core / Lead Maintainers’ consideration, they should follow the following process: -* Sampling depends on client capabilities -* Users control sampling behavior -* Context size has limits -* Rate limits may apply -* Costs should be considered -* Model availability varies -* Response times vary -* Not all content types supported +1. Collect evidence for the nomination. This will generally come in the form of a history of merged PRs on the repositories for which maintainership is being considered. +2. Discuss among maintainers of the relevant group(s) as to whether they would be supportive of approving the nomination. +3. DM a Community Moderator or Core Maintainer to create a private channel in Discord, in the format `nomination-{name}-{group}`. Add all core maintainers, lead maintainers, and co-maintainers on the relevant group. +4. Provide context for the individual under nomination. See below for suggestions on what to include here. +5. Create a Discord Poll and ask Core / Lead Maintainers to vote Yes / No on the nomination. Reaching consensus is encouraged though not required. +6. After Core / Lead Maintainers discuss and/or vote, if the nomination is favorable, relevant members with permissions to update GitHub an Discord roles will add the nominee to the appropriate groups. The nominator should announce the new maintainership in the relevant Discord channel. +7. The temporary Discord channel will be deleted a week later. +Suggestions for the kind of information to share with core maintainers when nominating someone: -# Tools -Source: https://modelcontextprotocol.io/docs/concepts/tools +* GitHub profile link, LinkedIn profile link, Discord username +* For what group(s) are you nominating the individual for maintainership +* Whether the group(s) agree that this person should be elevated to maintainership +* Description of their contributions to date (including links to most substantial contributions) +* Description of expected contributions moving forward (e.g. Are they eager to be a maintainer? Will they have capacity to do so?) +* Other context about the individual (e.g. current employer, motivations behind MCP involvement) +* Anything else you think may be relevant to consider for the nomination -Enable LLMs to perform actions through your server +## Current Core Maintainers -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. +* Inna Harper +* Basil Hosmer +* Paul Carleton +* Nick Cooper +* Nick Aldridge +* Che Liu +* Den Delimarsky - - 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). - +## Current Maintainers and Working Groups -## Overview +Refer to [the maintainer list](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/MAINTAINERS.md). -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: -* **Discovery**: Clients can list available tools through the `tools/list` endpoint -* **Invocation**: Tools are called using the `tools/call` endpoint, where servers perform the requested operation and return results -* **Flexibility**: Tools can range from simple calculations to complex API interactions +# SEP Guidelines +Source: https://modelcontextprotocol.io/community/sep-guidelines -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. +Specification Enhancement Proposal (SEP) guidelines for proposing changes to the Model Context Protocol -## Tool definition structure +## What is a SEP? -Each tool is defined with the following structure: +SEP stands for Specification Enhancement Proposal. A SEP is a design document providing information to the MCP community, or describing a new feature for the Model Context Protocol or its processes or environment. The SEP should provide a concise technical specification of the feature and a rationale for the feature. -```typescript -{ - name: string; // Unique identifier for the tool - description?: string; // Human-readable description - inputSchema: { // JSON Schema for the tool's parameters - type: "object", - properties: { ... } // Tool-specific parameters - }, - annotations?: { // Optional hints about tool behavior - title?: string; // Human-readable title for the tool - readOnlyHint?: boolean; // If true, the tool does not modify its environment - destructiveHint?: boolean; // If true, the tool may perform destructive updates - idempotentHint?: boolean; // If true, repeated calls with same args have no additional effect - openWorldHint?: boolean; // If true, tool interacts with external entities - } -} -``` +We intend SEPs to be the primary mechanisms for proposing major new features, for collecting community input on an issue, and for documenting the design decisions that have gone into MCP. The SEP author is responsible for building consensus within the community and documenting dissenting opinions. -## Implementing tools +Because the SEPs are maintained as text files in a versioned repository (GitHub Issues), their revision history is the historical record of the feature proposal. -Here's an example of implementing a basic tool in an MCP server: +## What qualifies a SEP? - - - ```typescript - const server = new Server({ - name: "example-server", - version: "1.0.0" - }, { - capabilities: { - tools: {} - } - }); +The goal is to reserve the SEP process for changes that are substantial enough to require broad community discussion, a formal design document, and a historical record of the decision-making process. A regular GitHub issue or pull request is often more appropriate for smaller, more direct changes. - // Define available tools - server.setRequestHandler(ListToolsRequestSchema, async () => { - return { - tools: [{ - name: "calculate_sum", - description: "Add two numbers together", - inputSchema: { - type: "object", - properties: { - a: { type: "number" }, - b: { type: "number" } - }, - required: ["a", "b"] - } - }] - }; - }); +Consider proposing a SEP if your change involves any of the following: - // Handle tool execution - server.setRequestHandler(CallToolRequestSchema, async (request) => { - if (request.params.name === "calculate_sum") { - const { a, b } = request.params.arguments; - return { - content: [ - { - type: "text", - text: String(a + b) - } - ] - }; - } - throw new Error("Tool not found"); - }); - ``` - +* **A New Feature or Protocol Change**: Any change that adds, modifies, or removes features in the Model Context Protocol. This includes: + * Adding new API endpoints or methods. + * Changing the syntax or semantics of existing data structures or messages. + * Introducing a new standard for interoperability between different MCP-compatible tools. + * Significant changes to how the specification itself is defined, presented, or validated. +* **A Breaking Change**: Any change that is not backwards-compatible. +* **A Change to Governance or Process**: Any proposal that alters the project's decision-making, contribution guidelines (like this document itself). +* **A Complex or Controversial Topic**: If a change is likely to have multiple valid solutions or generate significant debate, the SEP process provides the necessary framework to explore alternatives, document the rationale, and build community consensus before implementation begins. - - ```python - app = Server("example-server") - - @app.list_tools() - async def list_tools() -> list[types.Tool]: - return [ - types.Tool( - name="calculate_sum", - description="Add two numbers together", - inputSchema={ - "type": "object", - "properties": { - "a": {"type": "number"}, - "b": {"type": "number"} - }, - "required": ["a", "b"] - } - ) - ] +## SEP Types - @app.call_tool() - async def call_tool( - name: str, - arguments: dict - ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: - if name == "calculate_sum": - a = arguments["a"] - b = arguments["b"] - result = a + b - return [types.TextContent(type="text", text=str(result))] - raise ValueError(f"Tool not found: {name}") - ``` - - +There are three kinds of SEP: -## Example tool patterns +1. **Standards Track** SEP describes a new feature or implementation for the Model Context Protocol. It may also describe an interoperability standard that will be supported outside the core protocol specification. +2. **Informational** SEP describes a Model Context Protocol design issue, or provides general guidelines or information to the MCP community, but does not propose a new feature. Informational SEPs do not necessarily represent an MCP community consensus or recommendation. +3. **Process** SEP describes a process surrounding MCP, or proposes a change to (or an event in) a process. Process SEPs are like Standards Track SEPs but apply to areas other than the MCP protocol itself. -Here are some examples of types of tools that a server could provide: +## Submitting a SEP -### System operations +The SEP process begins with a new idea for the Model Context Protocol. It is highly recommended that a single SEP contain a single key proposal or new idea. Small enhancements or patches often don't need a SEP and can be injected into the MCP development workflow with a pull request to the MCP repo. The more focused the SEP, the more successful it tends to be. -Tools that interact with the local system: +Each SEP must have an **SEP author** -- someone who writes the SEP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The SEP author should first attempt to ascertain whether the idea is SEP-able. Posting to the MCP community forums (Discord, GitHub Discussions) is the best way to go about this. -```typescript -{ - name: "execute_command", - description: "Run a shell command", - inputSchema: { - type: "object", - properties: { - command: { type: "string" }, - args: { type: "array", items: { type: "string" } } - } - } -} -``` +### SEP Workflow -### API integrations +SEPs should be submitted as a GitHub Issue in the [specification repository](https://github.com/modelcontextprotocol/modelcontextprotocol). The standard SEP workflow is: -Tools that wrap external APIs: +1. You, the SEP author, create a [well-formatted](#sep-format) GitHub Issue with the `SEP` and `proposal` tags. The SEP number is the same as the GitHub Issue number, the two can be used interchangeably. +2. Find a Core Maintainer or Maintainer to sponsor your proposal. Core Maintainers and Maintainers will regularly go over the list of open proposals to determine which proposals to sponsor. You can tag relevant maintainers from [the maintainer list](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/MAINTAINERS.md) in your proposal. +3. Once a sponsor is found, the GitHub Issue is assigned to the sponsor. The sponsor will add the `draft` tag, ensure the SEP number is in the title, and assign a milestone. +4. The sponsor will informally review the proposal and may request changes based on community feedback. When ready for formal review, the sponsor will add the `in-review` tag. +5. After the `in-review` tag is added, the SEP enters formal review by the Core Maintainers team. The SEP may be accepted, rejected, or returned for revision. +6. If the SEP has not found a sponsor within three months, Core Maintainers may close the SEP as `dormant`. -```typescript -{ - name: "github_create_issue", - description: "Create a GitHub issue", - inputSchema: { - type: "object", - properties: { - title: { type: "string" }, - body: { type: "string" }, - labels: { type: "array", items: { type: "string" } } - } - } -} -``` +### SEP Format -### Data processing +Each SEP should have the following parts: -Tools that transform or analyze data: +1. **Preamble** -- A short descriptive title, the names and contact info for each author, the current status. +2. **Abstract** -- A short (\~200 word) description of the technical issue being addressed. +3. **Motivation** -- The motivation should clearly explain why the existing protocol specification is inadequate to address the problem that the SEP solves. The motivation is critical for SEPs that want to change the Model Context Protocol. SEP submissions without sufficient motivation may be rejected outright. +4. **Specification** -- The technical specification should describe the syntax and semantics of any new protocol feature. The specification should be detailed enough to allow competing, interoperable implementations. A PR with the changes to the specification should be provided. +5. **Rationale** -- The rationale explains why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion. +6. **Backward Compatibility** -- All SEPs that introduce backward incompatibilities must include a section describing these incompatibilities and their severity. The SEP must explain how the author proposes to deal with these incompatibilities. +7. **Reference Implementation** -- The reference implementation must be completed before any SEP is given status "Final", but it need not be completed before the SEP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of protocol details. +8. **Security Implications** -- If there are security concerns in relation to the SEP, those concerns should be explicitly written out to make sure reviewers of the SEP are aware of them. -```typescript -{ - name: "analyze_csv", - description: "Analyze a CSV file", - inputSchema: { - type: "object", - properties: { - filepath: { type: "string" }, - operations: { - type: "array", - items: { - enum: ["sum", "average", "count"] - } - } - } - } -} -``` +### SEP States -## Best practices +SEPs can be one one of the following states -When implementing tools: +* `proposal`: SEP proposal without a sponsor. +* `draft`: SEP proposal with a sponsor. +* `in-review`: SEP proposal ready for review. +* `accepted`: SEP accepted by Core Maintainers, but still requires final wording and reference implementation. +* `rejected`: SEP rejected by Core Maintainers. +* `withdrawn`: SEP withdrawn. +* `final`: SEP finalized. +* `superseded`: SEP has been replaced by a newer SEP. +* `dormant`: SEP that has not found sponsors and was subsequently closed. -1. Provide clear, descriptive names and descriptions -2. Use detailed JSON Schema definitions for parameters -3. Include examples in tool descriptions to demonstrate how the model should use them -4. Implement proper error handling and validation -5. Use progress reporting for long operations -6. Keep tool operations focused and atomic -7. Document expected return value structures -8. Implement proper timeouts -9. Consider rate limiting for resource-intensive operations -10. Log tool usage for debugging and monitoring +### SEP Review & Resolution -## Security considerations +SEPs are reviewed by the MCP Core Maintainers team on a bi-weekly basis. -When exposing tools: +For a SEP to be accepted it must meet certain minimum criteria: -### Input validation +* A prototype implementation demonstrating the proposal +* Clear benefit to the MCP ecosystem +* Community support and consensus -* Validate all parameters against the schema -* Sanitize file paths and system commands -* Validate URLs and external identifiers -* Check parameter sizes and ranges -* Prevent command injection +Once a SEP has been accepted, the reference implementation must be completed. When the reference implementation is complete and incorporated into the main source code repository, the status will be changed to "Final". -### Access control +A SEP can also be "Rejected" or "Withdrawn". A SEP that is "Withdrawn" may be re-submitted at a later date. -* Implement authentication where needed -* Use appropriate authorization checks -* Audit tool usage -* Rate limit requests -* Monitor for abuse +## Reporting SEP Bugs, or Submitting SEP Updates -### Error handling +How you report a bug, or submit a SEP update depends on several factors, such as the maturity of the SEP, the preferences of the SEP author, and the nature of your comments. For SEPs not yet reaching `final` state, it's probably best to send your comments and changes directly to the SEP author. Once SEP is finalized, you may want to submit corrections as a GitHub comment on the issue or pull request to the reference implementation. -* Don't expose internal errors to clients -* Log security-relevant errors -* Handle timeouts appropriately -* Clean up resources after errors -* Validate return values +## Transferring SEP Ownership -## Tool discovery and updates +It occasionally becomes necessary to transfer ownership of SEPs to a new SEP author. In general, we'd like to retain the original author as a co-author of the transferred SEP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the SEP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the SEP. We try to build consensus around a SEP, but if that's not possible, you can always submit a competing SEP. -MCP supports dynamic tool discovery: +## Copyright -1. Clients can list available tools at any time -2. Servers can notify clients when tools change using `notifications/tools/list_changed` -3. Tools can be added or removed during runtime -4. Tool definitions can be updated (though this should be done carefully) +This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive. -## Error handling -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: +# Working and Interest Groups +Source: https://modelcontextprotocol.io/community/working-interest-groups -1. Set `isError` to `true` in the result -2. Include error details in the `content` array +Learn about the two forms of collaborative groups within the Model Context Protocol's governance structure - Working Groups and Interest Groups. -Here's an example of proper error handling for tools: +Within the MCP contributor community we maintain two types of collaboration formats - **Interest** and **Working** groups. - - - ```typescript - try { - // Tool operation - const result = performOperation(); - return { - content: [ - { - type: "text", - text: `Operation successful: ${result}` - } - ] - }; - } catch (error) { - return { - isError: true, - content: [ - { - type: "text", - text: `Error: ${error.message}` - } - ] - }; - } - ``` - +**Interest Groups** are responsible for identifying and articulating problems that MCP should address, primarily by facilitating open discussions within the community. In contrast, **Working Groups** focus on developing concrete solutions by collaboratively producing deliverables, such as SEPs or community-owned implementations of the specification. - - ```python - try: - # Tool operation - result = perform_operation() - return types.CallToolResult( - content=[ - types.TextContent( - type="text", - text=f"Operation successful: {result}" - ) - ] - ) - except Exception as error: - return types.CallToolResult( - isError=True, - content=[ - types.TextContent( - type="text", - text=f"Error: {str(error)}" - ) - ] - ) - ``` - - +While input from Interest Groups can help justify the formation of a Working Group, it is not a strict requirement. Similarly, contributions from either Interest Groups or Working Groups are encouraged, but not mandatory, when submitting SEPs or other community proposals. -This approach allows the LLM to see that an error occurred and potentially take corrective action or request human intervention. +We strongly encourage all contributors interested in working on a specific SEP to first collaborate within an Interest Group. This collaborative process helps ensure that the proposed SEP aligns with community needs and is the right direction for the protocol. -## Tool annotations +Long-term projects in the MCP ecosystem, such as SDKs, Inspector, or Registry are maintained by dedicated Working Groups. -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. +## Purpose -### Purpose of tool annotations +These groups exist to: -Tool annotations serve several key purposes: +* **Facilitate high-signal spaces for focused discussions** - contributors who opt into notifications, expertise sharing, and regular meetings can engage with topics that are highly relevant to them, enabling meaningful contributions and opportunities to learn from others. +* **Establish clear expectations and leadership roles** - guide collaborative efforts and ensure steady progress toward concrete deliverables that advance MCP evolution and adoption. -1. Provide UX-specific information without affecting model context -2. Help clients categorize and present tools appropriately -3. Convey information about a tool's potential side effects -4. Assist in developing intuitive interfaces for tool approval +## Mechanisms -### Available tool annotations +## Meeting Calendar -The MCP specification defines the following annotations for tools: +All Interest Group and Working Group meetings are published on the public MCP community calendar at [meet.modelcontextprotocol.io](https://meet.modelcontextprotocol.io/). -| Annotation | Type | Default | Description | -| ----------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| `title` | string | - | A human-readable title for the tool, useful for UI display | -| `readOnlyHint` | boolean | false | If true, indicates the tool does not modify its environment | -| `destructiveHint` | boolean | true | If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false) | -| `idempotentHint` | boolean | false | If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false) | -| `openWorldHint` | boolean | true | If true, the tool may interact with an "open world" of external entities | +Facilitators are responsible for posting their meeting schedules to this calendar in advance to ensure discoverability and enable broader community participation. -### Example usage +### Interest Groups (IGs) -Here's how to define tools with annotations for different scenarios: +**Goal:** Facilitate discussion and knowledge-sharing among MCP contributors who share interests in a specific MCP sub-topic or context. The primary focus is on identifying and gathering problems that may be worth addressing through SEPs or other community artifacts, while encouraging open exploration of protocol issues and opportunities. -```typescript -// A read-only search tool -{ - name: "web_search", - description: "Search the web for information", - inputSchema: { - type: "object", - properties: { - query: { type: "string" } - }, - required: ["query"] - }, - annotations: { - title: "Web Search", - readOnlyHint: true, - openWorldHint: true - } -} +**Expectations**: -// A destructive file deletion tool -{ - name: "delete_file", - description: "Delete a file from the filesystem", - inputSchema: { - type: "object", - properties: { - path: { type: "string" } - }, - required: ["path"] - }, - annotations: { - title: "Delete File", - readOnlyHint: false, - destructiveHint: true, - idempotentHint: true, - openWorldHint: false - } -} +* Regular conversations in the Interest Group Discord channel +* **AND/OR** a recurring live meeting regularly attended by Interest Group members +* Meeting dates and times published in advance on the [MCP community calendar](https://meet.modelcontextprotocol.io/) when applicable, and tagged with their primary topic and interest group Discord channel name (e.g. `auth-ig`) +* Notes publicly shared after meetings, as a GitHub issue ([example](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1629)) and/or public Google Doc -// A non-destructive database record creation tool -{ - name: "create_record", - description: "Create a new record in the database", - inputSchema: { - type: "object", - properties: { - table: { type: "string" }, - data: { type: "object" } - }, - required: ["table", "data"] - }, - annotations: { - title: "Create Database Record", - readOnlyHint: false, - destructiveHint: false, - idempotentHint: false, - openWorldHint: false - } -} -``` +**Examples**: -### Integrating annotations in server implementation +* Security in MCP +* Auth in MCP +* Using MCP in enterprise settings +* Tooling and practices surrounding hosting MCP servers +* Tooling and practices surrounding implementing MCP clients - - - ```typescript - server.setRequestHandler(ListToolsRequestSchema, async () => { - return { - tools: [{ - name: "calculate_sum", - description: "Add two numbers together", - inputSchema: { - type: "object", - properties: { - a: { type: "number" }, - b: { type: "number" } - }, - required: ["a", "b"] - }, - annotations: { - title: "Calculate Sum", - readOnlyHint: true, - openWorldHint: false - } - }] - }; - }); - ``` - +**Lifecycle**: - - ```python - from mcp.server.fastmcp import FastMCP +* Creation begins by filling out a template in the #wg-ig-group-creation [Discord](/community/communication#discord) channel +* A community moderator will review and call for a vote in the (private) #community-moderators Discord channel. Majority positive vote by members over a 72h period approves creation of the group. + * The creation of the group can be reversed at any time (e.g., after new information surfaces). Core and lead maintainers can veto. +* Facilitator(s) and Maintainer(s) responsible for organizing IG into meeting expectations + * Facilitator is an informal role responsible for shepherding or speaking for a group + * Maintainer is an official representative from the MCP steering group. A maintainer is not required for every group, but can help advocate for specific changes or initiatives. +* IG is retired only when community moderators or Core or Lead Maintainers determine it's no longer active and/or needed + * Successful IGs do not have a time limit or expiration date - as long as they are active and maintained, they will remain available - mcp = FastMCP("example-server") +**Creation Template**: - @mcp.tool( - annotations={ - "title": "Calculate Sum", - "readOnlyHint": True, - "openWorldHint": False - } - ) - async def calculate_sum(a: float, b: float) -> str: - """Add two numbers together. - - Args: - a: First number to add - b: Second number to add - """ - result = a + b - return str(result) - ``` - - +* Facilitator(s) +* Maintainer(s) (optional) +* IGs with potentially similar goals/discussions +* How this IG differentiates itself from the related IGs +* First topic you to discuss within the IG -### Best practices for tool annotations +Participation in an Interest Group (IG) is not required to start a Working Group (WG) or to create a SEP. However, building consensus within IGs can be valuable when justifying the formation of a WG. Likewise, referencing support from IGs or WGs can strengthen a SEP and its chances of success. -1. **Be accurate about side effects**: Clearly indicate whether a tool modifies its environment and whether those modifications are destructive. +### Working Groups (WG) -2. **Use descriptive titles**: Provide human-friendly titles that clearly describe the tool's purpose. +**Goal:** Facilitate collaboration within the MCP community on a SEP, a themed series of SEPs, or an otherwise officially endorsed project. -3. **Indicate idempotency properly**: Mark tools as idempotent only if repeated calls with the same arguments truly have no additional effect. +**Expectations**: -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). +* Meaningful progress towards at least one SEP or spec-related implementation **OR** hold maintenance responsibilities for a project (e.g., Inspector, Registry, SDKs) +* Facilitators are responsible for keeping track of progress and communicating status when appropriate +* Meeting dates and times published in advance on the [MCP community calendar](https://meet.modelcontextprotocol.io/) when applicable, and tagged with their primary topic and working group Discord channel name (e.g. `agents-wg`) +* Notes publicly shared after meetings, as a GitHub issue ([example](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1629)) and/or public Google Doc -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. +**Examples**: -## Testing tools +* Registry +* Inspector +* Tool Filtering +* Server Identity -A comprehensive testing strategy for MCP tools should cover: +**Lifecycle**: -* **Functional testing**: Verify tools execute correctly with valid inputs and handle invalid inputs appropriately -* **Integration testing**: Test tool interaction with external systems using both real and mocked dependencies -* **Security testing**: Validate authentication, authorization, input sanitization, and rate limiting -* **Performance testing**: Check behavior under load, timeout handling, and resource cleanup -* **Error handling**: Ensure tools properly report errors through the MCP protocol and clean up resources +* Creation begins by filling out a template in #wg-ig-group-creation Discord channel +* A community moderator will review and call for a vote in the (private) #community-moderators Discord channel. Majority positive vote by members over a 72h period approves creation of the group. + * The creation of the group can be reversed at any time (e.g., after new information surfaces). Core and lead maintainers can veto. +* Facilitator(s) and Maintainer(s) responsible for organizing WG into meeting expectations + * Facilitator is an informal role responsible for shepherding or speaking for a group + * Maintainer is an official representative from the MCP steering group. A maintainer is not required for every group, but can help advocate for specific changes or initiatives +* WG is retired when either: + * Community moderators or Core and Lead Maintainers decide it is no longer active and/or needed + * The WG no longer has an active Issue/PR for a month or more, or has completed all Issues/PRs it intended to pursue. +**Creation Template**: -# Transports -Source: https://modelcontextprotocol.io/docs/concepts/transports +* Facilitator(s) +* Maintainer(s) (optional) +* Explanation of interest/use cases, ideally originating from an IG discussion; however that is not a requirement +* First Issue/PR/SEP that the WG will work on -Learn about MCP's communication mechanisms +## WG/IG Facilitators -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. +A **Facilitator** role in a WG or IG does *not* result in a [maintainership role](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/MAINTAINERS.md) across the MCP organization. It is an informal role into which anyone can self-nominate. -## Message Format +A Facilitator is responsible for helping shepherd discussions and collaboration within an Interest or Working Group. -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. +Lead and Core Maintainers reserve the right to modify the list of Facilitators and Maintainers for any WG/IG at any time. -There are three types of JSON-RPC messages used: +## FAQ -### Requests +### How do I get involved contributing to MCP? -```typescript -{ - jsonrpc: "2.0", - id: number | string, - method: string, - params?: object -} -``` +These IG and WG abstractions help provide an elegant on-ramp: -### Responses +1. [Join the Discord](/community/communication#discord) and follow conversations in IGs relevant to you. Attend [live calls](https://meet.modelcontextprotocol.io/). Participate. +2. Offer to facilitate calls. Contribute your use cases in SEP proposals and other work. +3. When you're comfortable contributing to deliverables, jump in to contribute to WG work. +4. Active and valuable contributors will be nominated by WG maintainers as new maintainers. -```typescript -{ - jsonrpc: "2.0", - id: number | string, - result?: object, - error?: { - code: number, - message: string, - data?: unknown - } -} -``` +### Where can I find a list of all current WGs and IGs? -### Notifications +On the [MCP Contributor Discord](/community/communication#discord) there is a section of channels for each Working and Interest Group. -```typescript -{ - jsonrpc: "2.0", - method: string, - params?: object -} -``` -## Built-in Transport Types +# Roadmap +Source: https://modelcontextprotocol.io/development/roadmap -MCP includes two standard transport implementations: +Our plans for evolving Model Context Protocol -### Standard Input/Output (stdio) +Last updated: **2025-07-22** -The stdio transport enables communication through standard input and output streams. This is particularly useful for local integrations and command-line tools. +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/)**. -Use stdio when: + + 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. + -* Building command-line tools -* Implementing local integrations -* Needing simple process communication -* Working with shell scripts +We value community participation! Each section links to relevant discussions where you can learn more and contribute your thoughts. - - - ```typescript - const server = new Server({ - name: "example-server", - version: "1.0.0" - }, { - capabilities: {} - }); +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). - const transport = new StdioServerTransport(); - await server.connect(transport); - ``` - +## Agents - - ```typescript - const client = new Client({ - name: "example-client", - version: "1.0.0" - }, { - capabilities: {} - }); +As MCP increasingly becomes part of agentic workflows, we're focusing on key improvements: - const transport = new StdioClientTransport({ - command: "./server", - args: ["--option", "value"] - }); - await client.connect(transport); - ``` - +* **Asynchronous Operations**: supporting long-running operations that may take extended periods, with resilient handling of disconnections and reconnections - - ```python - app = Server("example-server") +## Authentication and Security - async with stdio_server() as streams: - await app.run( - streams[0], - streams[1], - app.create_initialization_options() - ) - ``` - +We're evolving our authorization and security resources to improve user safety and provide a better developer experience: - - ```python - params = StdioServerParameters( - command="./server", - args=["--option", "value"] - ) +* **Guides and Best Practices**: documenting specifics about deploying MCP securely in the form of guides and best practices to help developers avoid common pitfalls. +* **Alternatives to Dynamic Client Registration (DCR)**: exploring alternatives to DCR, attempting to address operational challenges while preserving a smooth user experience. +* **Fine-grained Authorization**: developing mechanisms and guidelines for primitive authorization for sensitive actions +* **Enterprise Managed Authorization**: adding the capability for enterprises to simplify MCP server authorization with the help of Single Sign-On (SSO) +* **Secure Authorization Elicitation**: enable developers to integrate secure authorization flows for downstream APIs outside the main MCP server authorization - async with stdio_client(params) as streams: - async with ClientSession(streams[0], streams[1]) as session: - await session.initialize() - ``` - - +## Validation -### Server-Sent Events (SSE) +To foster a robust developer ecosystem, we plan to invest in: -SSE transport enables server-to-client streaming with HTTP POST requests for client-to-server communication. +* **Reference Client Implementations**: demonstrating protocol features with high-quality AI applications +* **Reference Server Implementation**: showcasing authentication patterns and remote deployment best practices +* **Compliance Test Suites**: automated verification that clients, servers, and SDKs properly implement the specification -Use SSE when: +These tools will help developers confidently implement MCP while ensuring consistent behavior across the ecosystem. -* Only server-to-client streaming is needed -* Working with restricted networks -* Implementing simple updates +## Registry -#### Security Warning: DNS Rebinding Attacks +For MCP to reach its full potential, we need streamlined ways to distribute and discover MCP servers. -SSE transports can be vulnerable to DNS rebinding attacks if not properly secured. To prevent this: +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. -1. **Always validate Origin headers** on incoming SSE connections to ensure they come from expected sources -2. **Avoid binding servers to all network interfaces** (0.0.0.0) when running locally - bind only to localhost (127.0.0.1) instead -3. **Implement proper authentication** for all SSE connections +## Multimodality -Without these protections, attackers could use DNS rebinding to interact with local MCP servers from remote websites. +Supporting the full spectrum of AI capabilities in MCP, including: - - - ```typescript - import express from "express"; +* **Additional Modalities**: video and other media types +* **[Streaming](https://github.com/modelcontextprotocol/specification/issues/117)**: multipart, chunked messages, and bidirectional communication for interactive experiences - const app = express(); +## Get Involved - const server = new Server({ - name: "example-server", - version: "1.0.0" - }, { - capabilities: {} - }); +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. - let transport: SSEServerTransport | null = null; - app.get("/sse", (req, res) => { - transport = new SSEServerTransport("/messages", res); - server.connect(transport); - }); +# Build an MCP client +Source: https://modelcontextprotocol.io/docs/develop/build-client - app.post("/messages", (req, res) => { - if (transport) { - transport.handlePostMessage(req, res); - } - }); +Get started building your own client that can integrate with all MCP servers. - app.listen(3000); - ``` - +In this tutorial, you'll learn how to build an LLM-powered chatbot client that connects to MCP servers. - - ```typescript - const client = new Client({ - name: "example-client", - version: "1.0.0" - }, { - capabilities: {} - }); +Before you begin, it helps to have gone through our [Build an MCP Server](/docs/develop/build-server) tutorial so you can understand how clients and servers communicate. - const transport = new SSEClientTransport( - new URL("http://localhost:3000/sse") - ); - await client.connect(transport); - ``` - + + + [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-python) - - ```python - from mcp.server.sse import SseServerTransport - from starlette.applications import Starlette - from starlette.routing import Route + ## System Requirements - app = Server("example-server") - sse = SseServerTransport("/messages") + Before starting, ensure your system meets these requirements: - async def handle_sse(scope, receive, send): - async with sse.connect_sse(scope, receive, send) as streams: - await app.run(streams[0], streams[1], app.create_initialization_options()) + * Mac or Windows computer + * Latest Python version installed + * Latest version of `uv` installed - async def handle_messages(scope, receive, send): - await sse.handle_post_message(scope, receive, send) + ## Setting Up Your Environment - starlette_app = Starlette( - routes=[ - Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]), - ] - ) - ``` - + First, create a new Python project with `uv`: - - ```python - async with sse_client("http://localhost:8000/sse") as streams: - async with ClientSession(streams[0], streams[1]) as session: - await session.initialize() - ``` - - + + ```bash macOS/Linux theme={null} + # Create project directory + uv init mcp-client + cd mcp-client -## Custom Transports + # Create virtual environment + uv venv -MCP makes it easy to implement custom transports for specific needs. Any transport implementation just needs to conform to the Transport interface: + # Activate virtual environment + source .venv/bin/activate -You can implement custom transports for: + # Install required packages + uv add mcp anthropic python-dotenv -* Custom network protocols -* Specialized communication channels -* Integration with existing systems -* Performance optimization + # Remove boilerplate files + rm main.py - - - ```typescript - interface Transport { - // Start processing messages - start(): Promise; + # Create our main file + touch client.py + ``` - // Send a JSON-RPC message - send(message: JSONRPCMessage): Promise; + ```powershell Windows theme={null} + # Create project directory + uv init mcp-client + cd mcp-client - // Close the connection - close(): Promise; + # Create virtual environment + uv venv - // Callbacks - onclose?: () => void; - onerror?: (error: Error) => void; - onmessage?: (message: JSONRPCMessage) => void; - } - ``` - + # Activate virtual environment + .venv\Scripts\activate - - Note that while MCP Servers are often implemented with asyncio, we recommend - implementing low-level interfaces like transports with `anyio` for wider compatibility. - - ```python - @contextmanager - async def create_transport( - read_stream: MemoryObjectReceiveStream[JSONRPCMessage | Exception], - write_stream: MemoryObjectSendStream[JSONRPCMessage] - ): - """ - Transport interface for MCP. + # Install required packages + uv add mcp anthropic python-dotenv - Args: - read_stream: Stream to read incoming messages from - write_stream: Stream to write outgoing messages to - """ - async with anyio.create_task_group() as tg: - try: - # Start processing messages - tg.start_soon(lambda: process_messages(read_stream)) - - # Send messages - async with write_stream: - yield write_stream - - except Exception as exc: - # Handle errors - raise exc - finally: - # Clean up - tg.cancel_scope.cancel() - await write_stream.aclose() - await read_stream.aclose() - ``` - - + # Remove boilerplate files + del main.py -## Error Handling + # Create our main file + new-item client.py + ``` + -Transport implementations should handle various error scenarios: - -1. Connection errors -2. Message parsing errors -3. Protocol errors -4. Network timeouts -5. Resource cleanup + ## Setting Up Your API Key -Example error handling: + You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys). - - - ```typescript - class ExampleTransport implements Transport { - async start() { - try { - // Connection logic - } catch (error) { - this.onerror?.(new Error(`Failed to connect: ${error}`)); - throw error; - } - } + Create a `.env` file to store it: - async send(message: JSONRPCMessage) { - try { - // Sending logic - } catch (error) { - this.onerror?.(new Error(`Failed to send message: ${error}`)); - throw error; - } - } - } + ```bash theme={null} + echo "ANTHROPIC_API_KEY=your-api-key-goes-here" > .env ``` - - - - Note that while MCP Servers are often implemented with asyncio, we recommend - implementing low-level interfaces like transports with `anyio` for wider compatibility. - ```python - @contextmanager - async def example_transport(scope: Scope, receive: Receive, send: Send): - try: - # Create streams for bidirectional communication - read_stream_writer, read_stream = anyio.create_memory_object_stream(0) - write_stream, write_stream_reader = anyio.create_memory_object_stream(0) + Add `.env` to your `.gitignore`: - async def message_handler(): - try: - async with read_stream_writer: - # Message handling logic - pass - except Exception as exc: - logger.error(f"Failed to handle message: {exc}") - raise exc - - async with anyio.create_task_group() as tg: - tg.start_soon(message_handler) - try: - # Yield streams for communication - yield read_stream, write_stream - except Exception as exc: - logger.error(f"Transport error: {exc}") - raise exc - finally: - tg.cancel_scope.cancel() - await write_stream.aclose() - await read_stream.aclose() - except Exception as exc: - logger.error(f"Failed to initialize transport: {exc}") - raise exc + ```bash theme={null} + echo ".env" >> .gitignore ``` - - - -## Best Practices -When implementing or using MCP transport: + + Make sure you keep your `ANTHROPIC_API_KEY` secure! + -1. Handle connection lifecycle properly -2. Implement proper error handling -3. Clean up resources on connection close -4. Use appropriate timeouts -5. Validate messages before sending -6. Log transport events for debugging -7. Implement reconnection logic when appropriate -8. Handle backpressure in message queues -9. Monitor connection health -10. Implement proper security measures + ## Creating the Client -## Security Considerations + ### Basic Client Structure -When implementing transport: + First, let's set up our imports and create the basic client class: -### Authentication and Authorization + ```python theme={null} + import asyncio + from typing import Optional + from contextlib import AsyncExitStack -* Implement proper authentication mechanisms -* Validate client credentials -* Use secure token handling -* Implement authorization checks + from mcp import ClientSession, StdioServerParameters + from mcp.client.stdio import stdio_client -### Data Security + from anthropic import Anthropic + from dotenv import load_dotenv -* Use TLS for network transport -* Encrypt sensitive data -* Validate message integrity -* Implement message size limits -* Sanitize input data + load_dotenv() # load environment variables from .env -### Network Security + class MCPClient: + def __init__(self): + # Initialize session and client objects + self.session: Optional[ClientSession] = None + self.exit_stack = AsyncExitStack() + self.anthropic = Anthropic() + # methods will go here + ``` -* Implement rate limiting -* Use appropriate timeouts -* Handle denial of service scenarios -* Monitor for unusual patterns -* Implement proper firewall rules -* For SSE transports, validate Origin headers to prevent DNS rebinding attacks -* For local SSE servers, bind only to localhost (127.0.0.1) instead of all interfaces (0.0.0.0) + ### Server Connection Management -## Debugging Transport + Next, we'll implement the method to connect to an MCP server: -Tips for debugging transport issues: + ```python theme={null} + async def connect_to_server(self, server_script_path: str): + """Connect to an MCP server -1. Enable debug logging -2. Monitor message flow -3. Check connection states -4. Validate message formats -5. Test error scenarios -6. Use network analysis tools -7. Implement health checks -8. Monitor resource usage -9. Test edge cases -10. Use proper error tracking + Args: + server_script_path: Path to the server script (.py or .js) + """ + is_python = server_script_path.endswith('.py') + is_js = server_script_path.endswith('.js') + if not (is_python or is_js): + raise ValueError("Server script must be a .py or .js file") + command = "python" if is_python else "node" + server_params = StdioServerParameters( + command=command, + args=[server_script_path], + env=None + ) -# Debugging -Source: https://modelcontextprotocol.io/docs/tools/debugging + stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params)) + self.stdio, self.write = stdio_transport + self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write)) -A comprehensive guide to debugging Model Context Protocol (MCP) integrations + await self.session.initialize() -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. + # List available tools + response = await self.session.list_tools() + tools = response.tools + print("\nConnected to server with tools:", [tool.name for tool in tools]) + ``` - - This guide is for macOS. Guides for other platforms are coming soon. - + ### Query Processing Logic -## Debugging tools overview + Now let's add the core functionality for processing queries and handling tool calls: -MCP provides several tools for debugging at different levels: + ```python theme={null} + async def process_query(self, query: str) -> str: + """Process a query using Claude and available tools""" + messages = [ + { + "role": "user", + "content": query + } + ] -1. **MCP Inspector** - * Interactive debugging interface - * Direct server testing - * See the [Inspector guide](/docs/tools/inspector) for details + response = await self.session.list_tools() + available_tools = [{ + "name": tool.name, + "description": tool.description, + "input_schema": tool.inputSchema + } for tool in response.tools] -2. **Claude Desktop Developer Tools** - * Integration testing - * Log collection - * Chrome DevTools integration + # Initial Claude API call + response = self.anthropic.messages.create( + model="claude-3-5-sonnet-20241022", + max_tokens=1000, + messages=messages, + tools=available_tools + ) -3. **Server Logging** - * Custom logging implementations - * Error tracking - * Performance monitoring + # Process response and handle tool calls + final_text = [] -## Debugging in Claude Desktop + assistant_message_content = [] + for content in response.content: + if content.type == 'text': + final_text.append(content.text) + assistant_message_content.append(content) + elif content.type == 'tool_use': + tool_name = content.name + tool_args = content.input -### Checking server status + # Execute tool call + result = await self.session.call_tool(tool_name, tool_args) + final_text.append(f"[Calling tool {tool_name} with args {tool_args}]") -The Claude.app interface provides basic server status information: + assistant_message_content.append(content) + messages.append({ + "role": "assistant", + "content": assistant_message_content + }) + messages.append({ + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": content.id, + "content": result.content + } + ] + }) -1. Click the icon to view: - * Connected servers - * Available prompts and resources + # Get next response from Claude + response = self.anthropic.messages.create( + model="claude-3-5-sonnet-20241022", + max_tokens=1000, + messages=messages, + tools=available_tools + ) -2. Click the icon to view: - * Tools made available to the model + final_text.append(response.content[0].text) -### Viewing logs + return "\n".join(final_text) + ``` -Review detailed MCP logs from Claude Desktop: + ### Interactive Chat Interface -```bash -# Follow logs in real-time -tail -n 20 -F ~/Library/Logs/Claude/mcp*.log -``` + Now we'll add the chat loop and cleanup functionality: -The logs capture: + ```python theme={null} + async def chat_loop(self): + """Run an interactive chat loop""" + print("\nMCP Client Started!") + print("Type your queries or 'quit' to exit.") -* Server connection events -* Configuration issues -* Runtime errors -* Message exchanges + while True: + try: + query = input("\nQuery: ").strip() -### Using Chrome DevTools + if query.lower() == 'quit': + break -Access Chrome's developer tools inside Claude Desktop to investigate client-side errors: + response = await self.process_query(query) + print("\n" + response) -1. Create a `developer_settings.json` file with `allowDevTools` set to true: + except Exception as e: + print(f"\nError: {str(e)}") -```bash -echo '{"allowDevTools": true}' > ~/Library/Application\ Support/Claude/developer_settings.json -``` + async def cleanup(self): + """Clean up resources""" + await self.exit_stack.aclose() + ``` -2. Open DevTools: `Command-Option-Shift-i` + ### Main Entry Point -Note: You'll see two DevTools windows: + Finally, we'll add the main execution logic: -* Main content window -* App title bar window + ```python theme={null} + async def main(): + if len(sys.argv) < 2: + print("Usage: python client.py ") + sys.exit(1) -Use the Console panel to inspect client-side errors. + client = MCPClient() + try: + await client.connect_to_server(sys.argv[1]) + await client.chat_loop() + finally: + await client.cleanup() -Use the Network panel to inspect: + if __name__ == "__main__": + import sys + asyncio.run(main()) + ``` -* Message payloads -* Connection timing + You can find the complete `client.py` file [here](https://github.com/modelcontextprotocol/quickstart-resources/blob/main/mcp-client-python/client.py). -## Common issues + ## Key Components Explained -### Working directory + ### 1. Client Initialization -When using MCP servers with Claude Desktop: + * The `MCPClient` class initializes with session management and API clients + * Uses `AsyncExitStack` for proper resource management + * Configures the Anthropic client for Claude interactions -* 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 -* Always use absolute paths in your configuration and `.env` files to ensure reliable operation -* For testing servers directly via command line, the working directory will be where you run the command + ### 2. Server Connection -For example in `claude_desktop_config.json`, use: + * Supports both Python and Node.js servers + * Validates server script type + * Sets up proper communication channels + * Initializes the session and lists available tools -```json -{ - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/username/data"] -} -``` + ### 3. Query Processing -Instead of relative paths like `./data` + * Maintains conversation context + * Handles Claude's responses and tool calls + * Manages the message flow between Claude and tools + * Combines results into a coherent response -### Environment variables + ### 4. Interactive Interface -MCP servers inherit only a subset of environment variables automatically, like `USER`, `HOME`, and `PATH`. + * Provides a simple command-line interface + * Handles user input and displays responses + * Includes basic error handling + * Allows graceful exit -To override the default variables or provide your own, you can specify an `env` key in `claude_desktop_config.json`: + ### 5. Resource Management -```json -{ - "myserver": { - "command": "mcp-server-myapp", - "env": { - "MYAPP_API_KEY": "some_key", - } - } -} -``` + * Proper cleanup of resources + * Error handling for connection issues + * Graceful shutdown procedures -### Server initialization + ## Common Customization Points -Common initialization problems: + 1. **Tool Handling** + * Modify `process_query()` to handle specific tool types + * Add custom error handling for tool calls + * Implement tool-specific response formatting -1. **Path Issues** - * Incorrect server executable path - * Missing required files - * Permission problems - * Try using an absolute path for `command` + 2. **Response Processing** + * Customize how tool results are formatted + * Add response filtering or transformation + * Implement custom logging -2. **Configuration Errors** - * Invalid JSON syntax - * Missing required fields - * Type mismatches + 3. **User Interface** + * Add a GUI or web interface + * Implement rich console output + * Add command history or auto-completion -3. **Environment Problems** - * Missing environment variables - * Incorrect variable values - * Permission restrictions + ## Running the Client -### Connection problems + To run your client with any MCP server: -When servers fail to connect: + ```bash theme={null} + uv run client.py path/to/server.py # python server + uv run client.py path/to/build/index.js # node server + ``` -1. Check Claude Desktop logs -2. Verify server process is running -3. Test standalone with [Inspector](/docs/tools/inspector) -4. Verify protocol compatibility + + If you're continuing [the weather tutorial from the server quickstart](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-python), your command might look something like this: `python client.py .../quickstart-resources/weather-server-python/weather.py` + -## Implementing logging + The client will: -### Server-side logging + 1. Connect to the specified server + 2. List available tools + 3. Start an interactive chat session where you can: + * Enter queries + * See tool executions + * Get responses from Claude -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. + Here's an example of what it should look like if connected to the weather server from the server quickstart: - - Local MCP servers should not log messages to stdout (standard out), as this will interfere with protocol operation. - + + + -For all [transports](/docs/concepts/transports), you can also provide logging to the client by sending a log message notification: + ## How It Works - - - ```python - server.request_context.session.send_log_message( - level="info", - data="Server started successfully", - ) - ``` - + When you submit a query: - - ```typescript - server.sendLoggingMessage({ - level: "info", - data: "Server started successfully", - }); - ``` - - + 1. The client gets the list of available tools from the server + 2. Your query is sent to Claude along with tool descriptions + 3. Claude decides which tools (if any) to use + 4. The client executes any requested tool calls through the server + 5. Results are sent back to Claude + 6. Claude provides a natural language response + 7. The response is displayed to you -Important events to log: + ## Best practices -* Initialization steps -* Resource access -* Tool execution -* Error conditions -* Performance metrics - -### Client-side logging - -In client applications: - -1. Enable debug logging -2. Monitor network traffic -3. Track message exchanges -4. Record error states + 1. **Error Handling** + * Always wrap tool calls in try-catch blocks + * Provide meaningful error messages + * Gracefully handle connection issues -## Debugging workflow + 2. **Resource Management** + * Use `AsyncExitStack` for proper cleanup + * Close connections when done + * Handle server disconnections -### Development cycle + 3. **Security** + * Store API keys securely in `.env` + * Validate server responses + * Be cautious with tool permissions -1. Initial Development - * Use [Inspector](/docs/tools/inspector) for basic testing - * Implement core functionality - * Add logging points + 4. **Tool Names** + * Tool names can be validated according to the format specified [here](/specification/draft/server/tools#tool-names) + * If a tool name conforms to the specified format, it should not fail validation by an MCP client -2. Integration Testing - * Test in Claude Desktop - * Monitor logs - * Check error handling + ## Troubleshooting -### Testing changes + ### Server Path Issues -To test changes efficiently: + * Double-check the path to your server script is correct + * Use the absolute path if the relative path isn't working + * For Windows users, make sure to use forward slashes (/) or escaped backslashes (\\) in the path + * Verify the server file has the correct extension (.py for Python or .js for Node.js) -* **Configuration changes**: Restart Claude Desktop -* **Server code changes**: Use Command-R to reload -* **Quick iteration**: Use [Inspector](/docs/tools/inspector) during development + Example of correct path usage: -## Best practices + ```bash theme={null} + # Relative path + uv run client.py ./server/weather.py -### Logging strategy + # Absolute path + uv run client.py /Users/username/projects/mcp-server/weather.py -1. **Structured Logging** - * Use consistent formats - * Include context - * Add timestamps - * Track request IDs + # Windows path (either format works) + uv run client.py C:/projects/mcp-server/weather.py + uv run client.py C:\\projects\\mcp-server\\weather.py + ``` -2. **Error Handling** - * Log stack traces - * Include error context - * Track error patterns - * Monitor recovery + ### Response Timing -3. **Performance Tracking** - * Log operation timing - * Monitor resource usage - * Track message sizes - * Measure latency + * The first response might take up to 30 seconds to return + * This is normal and happens while: + * The server initializes + * Claude processes the query + * Tools are being executed + * Subsequent responses are typically faster + * Don't interrupt the process during this initial waiting period -### Security considerations + ### Common Error Messages -When debugging: + If you see: -1. **Sensitive Data** - * Sanitize logs - * Protect credentials - * Mask personal information + * `FileNotFoundError`: Check your server path + * `Connection refused`: Ensure the server is running and the path is correct + * `Tool execution failed`: Verify the tool's required environment variables are set + * `Timeout error`: Consider increasing the timeout in your client configuration + -2. **Access Control** - * Verify permissions - * Check authentication - * Monitor access patterns + + [You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-typescript) -## Getting help + ## System Requirements -When encountering issues: + Before starting, ensure your system meets these requirements: -1. **First Steps** - * Check server logs - * Test with [Inspector](/docs/tools/inspector) - * Review configuration - * Verify environment + * Mac or Windows computer + * Node.js 17 or higher installed + * Latest version of `npm` installed + * Anthropic API key (Claude) -2. **Support Channels** - * GitHub issues - * GitHub discussions + ## Setting Up Your Environment -3. **Providing Information** - * Log excerpts - * Configuration files - * Steps to reproduce - * Environment details + First, let's create and set up our project: -## Next steps + + ```bash macOS/Linux theme={null} + # Create project directory + mkdir mcp-client-typescript + cd mcp-client-typescript - - - Learn to use the MCP Inspector - - + # Initialize npm project + npm init -y + # Install dependencies + npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv -# Inspector -Source: https://modelcontextprotocol.io/docs/tools/inspector + # Install dev dependencies + npm install -D @types/node typescript -In-depth guide to using the MCP Inspector for testing and debugging Model Context Protocol servers + # Create source file + touch index.ts + ``` -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. + ```powershell Windows theme={null} + # Create project directory + md mcp-client-typescript + cd mcp-client-typescript -## Getting started + # Initialize npm project + npm init -y -### Installation and basic usage + # Install dependencies + npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv -The Inspector runs directly through `npx` without requiring installation: + # Install dev dependencies + npm install -D @types/node typescript -```bash -npx @modelcontextprotocol/inspector -``` + # Create source file + new-item index.ts + ``` + -```bash -npx @modelcontextprotocol/inspector -``` + Update your `package.json` to set `type: "module"` and a build script: -#### Inspecting servers from NPM or PyPi + ```json package.json theme={null} + { + "type": "module", + "scripts": { + "build": "tsc && chmod 755 build/index.js" + } + } + ``` -A common way to start server packages from [NPM](https://npmjs.com) or [PyPi](https://pypi.com). + Create a `tsconfig.json` in the root of your project: - - - ```bash - npx -y @modelcontextprotocol/inspector npx - # For example - npx -y @modelcontextprotocol/inspector npx server-postgres postgres://127.0.0.1/testdb + ```json tsconfig.json theme={null} + { + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "outDir": "./build", + "rootDir": "./", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["index.ts"], + "exclude": ["node_modules"] + } ``` - - - ```bash - npx @modelcontextprotocol/inspector uvx - # For example - npx @modelcontextprotocol/inspector uvx mcp-server-git --repository ~/code/mcp/servers.git - ``` - - + ## Setting Up Your API Key -#### Inspecting locally developed servers + You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys). -To inspect servers locally developed or downloaded as a repository, the most common -way is: + Create a `.env` file to store it: - - - ```bash - npx @modelcontextprotocol/inspector node path/to/server/index.js args... + ```bash theme={null} + echo "ANTHROPIC_API_KEY=" > .env ``` - - - ```bash - npx @modelcontextprotocol/inspector \ - uv \ - --directory path/to/server \ - run \ - package-name \ - args... + Add `.env` to your `.gitignore`: + + ```bash theme={null} + echo ".env" >> .gitignore ``` - - -Please carefully read any attached README for the most accurate instructions. + + Make sure you keep your `ANTHROPIC_API_KEY` secure! + -## Feature overview + ## Creating the Client - - - + ### Basic Client Structure -The Inspector provides several features for interacting with your MCP server: + First, let's set up our imports and create the basic client class in `index.ts`: -### Server connection pane + ```typescript theme={null} + import { Anthropic } from "@anthropic-ai/sdk"; + import { + MessageParam, + Tool, + } from "@anthropic-ai/sdk/resources/messages/messages.mjs"; + import { Client } from "@modelcontextprotocol/sdk/client/index.js"; + import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; + import readline from "readline/promises"; + import dotenv from "dotenv"; -* Allows selecting the [transport](/docs/concepts/transports) for connecting to the server -* For local servers, supports customizing the command-line arguments and environment + dotenv.config(); -### Resources tab + const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; + if (!ANTHROPIC_API_KEY) { + throw new Error("ANTHROPIC_API_KEY is not set"); + } -* Lists all available resources -* Shows resource metadata (MIME types, descriptions) -* Allows resource content inspection -* Supports subscription testing + class MCPClient { + private mcp: Client; + private anthropic: Anthropic; + private transport: StdioClientTransport | null = null; + private tools: Tool[] = []; -### Prompts tab + constructor() { + this.anthropic = new Anthropic({ + apiKey: ANTHROPIC_API_KEY, + }); + this.mcp = new Client({ name: "mcp-client-cli", version: "1.0.0" }); + } + // methods will go here + } + ``` -* Displays available prompt templates -* Shows prompt arguments and descriptions -* Enables prompt testing with custom arguments -* Previews generated messages + ### Server Connection Management -### Tools tab + Next, we'll implement the method to connect to an MCP server: -* Lists available tools -* Shows tool schemas and descriptions -* Enables tool testing with custom inputs -* Displays tool execution results + ```typescript theme={null} + async connectToServer(serverScriptPath: string) { + try { + const isJs = serverScriptPath.endsWith(".js"); + const isPy = serverScriptPath.endsWith(".py"); + if (!isJs && !isPy) { + throw new Error("Server script must be a .js or .py file"); + } + const command = isPy + ? process.platform === "win32" + ? "python" + : "python3" + : process.execPath; -### Notifications pane + this.transport = new StdioClientTransport({ + command, + args: [serverScriptPath], + }); + await this.mcp.connect(this.transport); -* Presents all logs recorded from the server -* Shows notifications received from the server + const toolsResult = await this.mcp.listTools(); + this.tools = toolsResult.tools.map((tool) => { + return { + name: tool.name, + description: tool.description, + input_schema: tool.inputSchema, + }; + }); + console.log( + "Connected to server with tools:", + this.tools.map(({ name }) => name) + ); + } catch (e) { + console.log("Failed to connect to MCP server: ", e); + throw e; + } + } + ``` -## Best practices + ### Query Processing Logic -### Development workflow + Now let's add the core functionality for processing queries and handling tool calls: -1. Start Development - * Launch Inspector with your server - * Verify basic connectivity - * Check capability negotiation - -2. Iterative testing - * Make server changes - * Rebuild the server - * Reconnect the Inspector - * Test affected features - * Monitor messages + ```typescript theme={null} + async processQuery(query: string) { + const messages: MessageParam[] = [ + { + role: "user", + content: query, + }, + ]; -3. Test edge cases - * Invalid inputs - * Missing prompt arguments - * Concurrent operations - * Verify error handling and error responses + const response = await this.anthropic.messages.create({ + model: "claude-3-5-sonnet-20241022", + max_tokens: 1000, + messages, + tools: this.tools, + }); -## Next steps + const finalText = []; - - - Check out the MCP Inspector source code - + for (const content of response.content) { + if (content.type === "text") { + finalText.push(content.text); + } else if (content.type === "tool_use") { + const toolName = content.name; + const toolArgs = content.input as { [x: string]: unknown } | undefined; - - Learn about broader debugging strategies - - + const result = await this.mcp.callTool({ + name: toolName, + arguments: toolArgs, + }); + finalText.push( + `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]` + ); + messages.push({ + role: "user", + content: result.content as string, + }); -# Example Servers -Source: https://modelcontextprotocol.io/examples + const response = await this.anthropic.messages.create({ + model: "claude-3-5-sonnet-20241022", + max_tokens: 1000, + messages, + }); -A list of example servers and implementations + finalText.push( + response.content[0].type === "text" ? response.content[0].text : "" + ); + } + } -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. + return finalText.join("\n"); + } + ``` -## Reference implementations + ### Interactive Chat Interface -These official reference servers demonstrate core MCP features and SDK usage: + Now we'll add the chat loop and cleanup functionality: -### Data and file systems + ```typescript theme={null} + async chatLoop() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); -* **[Filesystem](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem)** - Secure file operations with configurable access controls -* **[PostgreSQL](https://github.com/modelcontextprotocol/servers/tree/main/src/postgres)** - Read-only database access with schema inspection capabilities -* **[SQLite](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite)** - Database interaction and business intelligence features -* **[Google Drive](https://github.com/modelcontextprotocol/servers/tree/main/src/gdrive)** - File access and search capabilities for Google Drive + try { + console.log("\nMCP Client Started!"); + console.log("Type your queries or 'quit' to exit."); -### Development tools + while (true) { + const message = await rl.question("\nQuery: "); + if (message.toLowerCase() === "quit") { + break; + } + const response = await this.processQuery(message); + console.log("\n" + response); + } + } finally { + rl.close(); + } + } -* **[Git](https://github.com/modelcontextprotocol/servers/tree/main/src/git)** - Tools to read, search, and manipulate Git repositories -* **[GitHub](https://github.com/modelcontextprotocol/servers/tree/main/src/github)** - Repository management, file operations, and GitHub API integration -* **[GitLab](https://github.com/modelcontextprotocol/servers/tree/main/src/gitlab)** - GitLab API integration enabling project management -* **[Sentry](https://github.com/modelcontextprotocol/servers/tree/main/src/sentry)** - Retrieving and analyzing issues from Sentry.io + async cleanup() { + await this.mcp.close(); + } + ``` -### Web and browser automation + ### Main Entry Point -* **[Brave Search](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)** - Web and local search using Brave's Search API -* **[Fetch](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch)** - Web content fetching and conversion optimized for LLM usage -* **[Puppeteer](https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer)** - Browser automation and web scraping capabilities + Finally, we'll add the main execution logic: -### Productivity and communication + ```typescript theme={null} + async function main() { + if (process.argv.length < 3) { + console.log("Usage: node index.ts "); + return; + } + const mcpClient = new MCPClient(); + try { + await mcpClient.connectToServer(process.argv[2]); + await mcpClient.chatLoop(); + } finally { + await mcpClient.cleanup(); + process.exit(0); + } + } -* **[Slack](https://github.com/modelcontextprotocol/servers/tree/main/src/slack)** - Channel management and messaging capabilities -* **[Google Maps](https://github.com/modelcontextprotocol/servers/tree/main/src/google-maps)** - Location services, directions, and place details -* **[Memory](https://github.com/modelcontextprotocol/servers/tree/main/src/memory)** - Knowledge graph-based persistent memory system + main(); + ``` -### AI and specialized tools + ## Running the Client -* **[EverArt](https://github.com/modelcontextprotocol/servers/tree/main/src/everart)** - AI image generation using various models -* **[Sequential Thinking](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking)** - Dynamic problem-solving through thought sequences -* **[AWS KB Retrieval](https://github.com/modelcontextprotocol/servers/tree/main/src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime + To run your client with any MCP server: -## Official integrations + ```bash theme={null} + # Build TypeScript + npm run build -These MCP servers are maintained by companies for their platforms: + # Run the client + node build/index.js path/to/server.py # python server + node build/index.js path/to/build/index.js # node server + ``` -* **[Axiom](https://github.com/axiomhq/mcp-server-axiom)** - Query and analyze logs, traces, and event data using natural language -* **[Browserbase](https://github.com/browserbase/mcp-server-browserbase)** - Automate browser interactions in the cloud -* **[Cloudflare](https://github.com/cloudflare/mcp-server-cloudflare)** - Deploy and manage resources on the Cloudflare developer platform -* **[E2B](https://github.com/e2b-dev/mcp-server)** - Execute code in secure cloud sandboxes -* **[Neon](https://github.com/neondatabase/mcp-server-neon)** - Interact with the Neon serverless Postgres platform -* **[Obsidian Markdown Notes](https://github.com/calclavia/mcp-obsidian)** - Read and search through Markdown notes in Obsidian vaults -* **[Prisma](https://pris.ly/docs/mcp-server)** - Manage and interact with Prisma Postgres databases -* **[Qdrant](https://github.com/qdrant/mcp-server-qdrant/)** - Implement semantic memory using the Qdrant vector search engine -* **[Raygun](https://github.com/MindscapeHQ/mcp-server-raygun)** - Access crash reporting and monitoring data -* **[Search1API](https://github.com/fatwang2/search1api-mcp)** - Unified API for search, crawling, and sitemaps -* **[Stripe](https://github.com/stripe/agent-toolkit)** - Interact with the Stripe API -* **[Tinybird](https://github.com/tinybirdco/mcp-tinybird)** - Interface with the Tinybird serverless ClickHouse platform -* **[Weaviate](https://github.com/weaviate/mcp-server-weaviate)** - Enable Agentic RAG through your Weaviate collection(s) + + If you're continuing [the weather tutorial from the server quickstart](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-typescript), your command might look something like this: `node build/index.js .../quickstart-resources/weather-server-typescript/build/index.js` + -## Community highlights + **The client will:** -A growing ecosystem of community-developed servers extends MCP's capabilities: + 1. Connect to the specified server + 2. List available tools + 3. Start an interactive chat session where you can: + * Enter queries + * See tool executions + * Get responses from Claude -* **[Docker](https://github.com/ckreiling/mcp-server-docker)** - Manage containers, images, volumes, and networks -* **[Kubernetes](https://github.com/Flux159/mcp-server-kubernetes)** - Manage pods, deployments, and services -* **[Linear](https://github.com/jerhadf/linear-mcp-server)** - Project management and issue tracking -* **[Snowflake](https://github.com/datawiz168/mcp-snowflake-service)** - Interact with Snowflake databases -* **[Spotify](https://github.com/varunneal/spotify-mcp)** - Control Spotify playback and manage playlists -* **[Todoist](https://github.com/abhiz123/todoist-mcp-server)** - Task management integration + ## How It Works -> **Note:** Community servers are untested and should be used at your own risk. They are not affiliated with or endorsed by Anthropic. + When you submit a query: -For a complete list of community servers, visit the [MCP Servers Repository](https://github.com/modelcontextprotocol/servers). + 1. The client gets the list of available tools from the server + 2. Your query is sent to Claude along with tool descriptions + 3. Claude decides which tools (if any) to use + 4. The client executes any requested tool calls through the server + 5. Results are sent back to Claude + 6. Claude provides a natural language response + 7. The response is displayed to you -## Getting started + ## Best practices -### Using reference servers + 1. **Error Handling** + * Use TypeScript's type system for better error detection + * Wrap tool calls in try-catch blocks + * Provide meaningful error messages + * Gracefully handle connection issues -TypeScript-based servers can be used directly with `npx`: + 2. **Security** + * Store API keys securely in `.env` + * Validate server responses + * Be cautious with tool permissions -```bash -npx -y @modelcontextprotocol/server-memory -``` + ## Troubleshooting -Python-based servers can be used with `uvx` (recommended) or `pip`: + ### Server Path Issues -```bash -# Using uvx -uvx mcp-server-git + * Double-check the path to your server script is correct + * Use the absolute path if the relative path isn't working + * For Windows users, make sure to use forward slashes (/) or escaped backslashes (\\) in the path + * Verify the server file has the correct extension (.js for Node.js or .py for Python) -# Using pip -pip install mcp-server-git -python -m mcp_server_git -``` + Example of correct path usage: -### Configuring with Claude + ```bash theme={null} + # Relative path + node build/index.js ./server/build/index.js -To use an MCP server with Claude, add it to your configuration: + # Absolute path + node build/index.js /Users/username/projects/mcp-server/build/index.js -```json -{ - "mcpServers": { - "memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"] - }, - "filesystem": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"] - }, - "github": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-github"], - "env": { - "GITHUB_PERSONAL_ACCESS_TOKEN": "" - } - } - } -} -``` + # Windows path (either format works) + node build/index.js C:/projects/mcp-server/build/index.js + node build/index.js C:\\projects\\mcp-server\\build\\index.js + ``` -## Additional resources + ### Response Timing -* [MCP Servers Repository](https://github.com/modelcontextprotocol/servers) - Complete collection of reference implementations and community servers -* [Awesome MCP Servers](https://github.com/punkpeye/awesome-mcp-servers) - Curated list of MCP servers -* [MCP CLI](https://github.com/wong2/mcp-cli) - Command-line inspector for testing MCP servers -* [MCP Get](https://mcp-get.com) - Tool for installing and managing MCP servers -* [Supergateway](https://github.com/supercorp-ai/supergateway) - Run MCP stdio servers over SSE -* [Zapier MCP](https://zapier.com/mcp) - MCP Server with over 7,000+ apps and 30,000+ actions + * The first response might take up to 30 seconds to return + * This is normal and happens while: + * The server initializes + * Claude processes the query + * Tools are being executed + * Subsequent responses are typically faster + * Don't interrupt the process during this initial waiting period -Visit our [GitHub Discussions](https://github.com/orgs/modelcontextprotocol/discussions) to engage with the MCP community. + ### Common Error Messages + If you see: -# FAQs -Source: https://modelcontextprotocol.io/faqs + * `Error: Cannot find module`: Check your build folder and ensure TypeScript compilation succeeded + * `Connection refused`: Ensure the server is running and the path is correct + * `Tool execution failed`: Verify the tool's required environment variables are set + * `ANTHROPIC_API_KEY is not set`: Check your .env file and environment variables + * `TypeError`: Ensure you're using the correct types for tool arguments + -Explaining MCP and why it matters in simple terms + + + This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. + To learn how to create sync and async MCP Clients manually, consult the [Java SDK Client](/sdk/java/mcp-client) documentation + -## What is MCP? + 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. + [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) -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). + ## System Requirements -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. + Before starting, ensure your system meets these requirements: -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. + * Java 17 or higher + * Maven 3.6+ + * npx package manager + * Anthropic API key (Claude) + * Brave Search API key -## Why does MCP matter? + ## Setting Up Your Environment -### For AI application users + 1. Install npx (Node Package eXecute): + First, make sure to install [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) + and then run: -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. + ```bash theme={null} + npm install -g npx + ``` -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. + 2. Clone the repository: -Imagine asking an AI assistant: "Summarize last week's team meeting notes and schedule follow-ups with everyone." + ```bash theme={null} + git clone https://github.com/spring-projects/spring-ai-examples.git + cd model-context-protocol/brave-chatbot + ``` -By using connections to data sources powered by MCP, the AI assistant can: + 3. Set up your API keys: -* Connect to your Google Drive through an MCP server to read meeting notes -* Understand who needs follow-ups based on the notes -* Connect to your calendar through another MCP server to schedule the meetings automatically + ```bash theme={null} + export ANTHROPIC_API_KEY='your-anthropic-api-key-here' + export BRAVE_API_KEY='your-brave-api-key-here' + ``` -### For developers + 4. Build the application: -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. + ```bash theme={null} + ./mvnw clean install + ``` -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. + 5. Run the application using Maven: + ```bash theme={null} + ./mvnw spring-boot:run + ``` -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. - -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. - -## How does MCP work? - - - - - -MCP creates a bridge between your AI applications and your data through a straightforward system: - -* **MCP servers** connect to your data sources and tools (like Google Drive or Slack) -* **MCP clients** are run by AI applications (like Claude Desktop) to connect them to these servers -* When you give permission, your AI application discovers available MCP servers -* The AI model can then use these connections to read information and take actions - -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. - -## Who creates and maintains MCP servers? - -MCP servers are developed and maintained by: - -* Developers at Anthropic who build servers for common tools and data sources -* Open source contributors who create servers for tools they use -* Enterprise development teams building servers for their internal systems -* Software providers making their applications AI-ready - -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). - - -# Introduction -Source: https://modelcontextprotocol.io/introduction - -Get started with the Model Context Protocol (MCP) - -C# SDK released! Check out [what else is new.](/development/updates) - -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. - -## Why MCP? - -MCP helps you build agents and complex workflows on top of LLMs. LLMs frequently need to integrate with data and tools, and MCP provides: + + Make sure you keep your `ANTHROPIC_API_KEY` and `BRAVE_API_KEY` keys secure! + -* A growing list of pre-built integrations that your LLM can directly plug into -* The flexibility to switch between LLM providers and vendors -* Best practices for securing your data within your infrastructure + ## How it Works -### General architecture + The application integrates Spring AI with the Brave Search MCP server through several components: -At its core, MCP follows a client-server architecture where a host application can connect to multiple servers: + ### MCP Client Configuration -```mermaid -flowchart LR - subgraph "Your Computer" - Host["Host with MCP Client\n(Claude, IDEs, Tools)"] - S1["MCP Server A"] - S2["MCP Server B"] - S3["MCP Server C"] - Host <-->|"MCP Protocol"| S1 - Host <-->|"MCP Protocol"| S2 - Host <-->|"MCP Protocol"| S3 - S1 <--> D1[("Local\nData Source A")] - S2 <--> D2[("Local\nData Source B")] - end - subgraph "Internet" - S3 <-->|"Web APIs"| D3[("Remote\nService C")] - end -``` + 1. Required dependencies in pom.xml: -* **MCP Hosts**: Programs like Claude Desktop, IDEs, or AI tools that want to access data through MCP -* **MCP Clients**: Protocol clients that maintain 1:1 connections with servers -* **MCP Servers**: Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol -* **Local Data Sources**: Your computer's files, databases, and services that MCP servers can securely access -* **Remote Services**: External systems available over the internet (e.g., through APIs) that MCP servers can connect to + ```xml theme={null} + + org.springframework.ai + spring-ai-starter-mcp-client + + + org.springframework.ai + spring-ai-starter-model-anthropic + + ``` -## Get started + 2. Application properties (application.yml): -Choose the path that best fits your needs: + ```yml theme={null} + spring: + ai: + mcp: + client: + enabled: true + name: brave-search-client + version: 1.0.0 + type: SYNC + request-timeout: 20s + stdio: + root-change-notification: true + servers-configuration: classpath:/mcp-servers-config.json + toolcallback: + enabled: true + anthropic: + api-key: ${ANTHROPIC_API_KEY} + ``` -#### Quick Starts + This activates the `spring-ai-starter-mcp-client` to create one or more `McpClient`s based on the provided server configuration. + The `spring.ai.mcp.client.toolcallback.enabled=true` property enables the tool callback mechanism, that automatically registers all MCP tool as spring ai tools. + It is disabled by default. - - - Get started building your own server to use in Claude for Desktop and other clients - + 3. MCP Server Configuration (`mcp-servers-config.json`): - - Get started building your own client that can integrate with all MCP servers - + ```json theme={null} + { + "mcpServers": { + "brave-search": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-brave-search"], + "env": { + "BRAVE_API_KEY": "" + } + } + } + } + ``` - - Get started using pre-built servers in Claude for Desktop - - + ### Chat Implementation -#### Examples + The chatbot is implemented using Spring AI's ChatClient with MCP tool integration: - - - Check out our gallery of official MCP servers and implementations - + ```java theme={null} + var chatClient = chatClientBuilder + .defaultSystem("You are useful assistant, expert in AI and Java.") + .defaultToolCallbacks((Object[]) mcpToolAdapter.toolCallbacks()) + .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())) + .build(); + ``` - - View the list of clients that support MCP integrations - - + Key features: -## Tutorials + * Uses Claude AI model for natural language understanding + * Integrates Brave Search through MCP for real-time web search capabilities + * Maintains conversation memory using InMemoryChatMemory + * Runs as an interactive command-line application - - - Learn how to use LLMs like Claude to speed up your MCP development - + ### Build and run - - Learn how to effectively debug MCP servers and integrations - + ```bash theme={null} + ./mvnw clean install + java -jar ./target/ai-mcp-brave-chatbot-0.0.1-SNAPSHOT.jar + ``` - - Test and inspect your MCP servers with our interactive debugging tool - + or - -