diff --git a/clients.mdx b/clients.mdx index 6031890..f5f328f 100644 --- a/clients.mdx +++ b/clients.mdx @@ -7,24 +7,34 @@ This page provides an overview of applications that support the Model Context Pr ## Feature support matrix -| Client | [Resources] | [Prompts] | [Tools] | [Sampling] | Roots | Notes | -|---------------------------|-------------|-----------|---------|------------|-------|---------------------------------------------------| -| [Claude Desktop App][Claude] | ✅ | ✅ | ✅ | ❌ | ❌ | Full support for all MCP features | -| [Zed][Zed] | ❌ | ✅ | ❌ | ❌ | ❌ | Prompts appear as slash commands | -| [Sourcegraph Cody][Cody] | ✅ | ❌ | ❌ | ❌ | ❌ | Supports resources through OpenCTX | -| [Firebase Genkit][Genkit] | ⚠️ | ✅ | ✅ | ❌ | ❌ | Supports resource list and lookup through tools | -| [Continue][Continue] | ✅ | ✅ | ✅ | ❌ | ❌ | Full support for all MCP features | -| [GenAIScript][GenAIScript] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | -| [Cline][Cline] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources | -| [LibreChat][LibreChat] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents | -| [TheiaAI/TheiaIDE][TheiaAI/TheiaIDE] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents in Theia AI and the AI-powered Theia IDE | -| [Superinterface][Superinterface] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | -| [5ire][5ire] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | -| [Bee Agent Framework][Bee Agent Framework] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in agentic workflows | +| Client | [Resources] | [Prompts] | [Tools] | [Sampling] | Roots | Notes | +|---------------------------------------------|-------------|-----------|---------|------------|--------|-----------------------------------------------------------------------------| +| [Claude Desktop App][Claude] | ✅ | ✅ | ✅ | ❌ | ❌ | Full support for all MCP features | +| [5ire][5ire] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | +| [BeeAI Framework][BeeAI Framework] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in agentic workflows. | +| [Cline][Cline] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | +| [Continue][Continue] | ✅ | ✅ | ✅ | ❌ | ❌ | Full support for all MCP features | +| [Cursor][Cursor] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | +| [Emacs Mcp][Mcp.el] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in Emacs. | +| [Firebase Genkit][Genkit] | ⚠️ | ✅ | ✅ | ❌ | ❌ | Supports resource list and lookup through tools. | +| [GenAIScript][GenAIScript] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | +| [Goose][Goose] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools. | +| [LibreChat][LibreChat] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents | +| [mcp-agent][mcp-agent] | ❌ | ❌ | ✅ | ⚠️ | ❌ | Supports tools, server connection management, and agent workflows. | +| [Roo Code][Roo Code] | ✅ | ❌ | ✅ | ❌ | ❌ | Supports tools and resources. | +| [Sourcegraph Cody][Cody] | ✅ | ❌ | ❌ | ❌ | ❌ | Supports resources through OpenCTX | +| [Superinterface][Superinterface] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | +| [TheiaAI/TheiaIDE][TheiaAI/TheiaIDE] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Agents in Theia AI and the AI-powered Theia IDE | +| [Windsurf Editor][Windsurf] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools with AI Flow for collaborative development. | +| [Zed][Zed] | ❌ | ✅ | ❌ | ❌ | ❌ | Prompts appear as slash commands | +| [SpinAI][SpinAI] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools for Typescript AI Agents | +| [OpenSumi][OpenSumi] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools in OpenSumi | +| [Daydreams Agents][Daydreams] | ✅ | ✅ | ✅ | ❌ | ❌ | Support for drop in Servers to Daydreams agents | | [Apify MCP Tester][Apify MCP Tester] | ❌ | ❌ | ✅ | ❌ | ❌ | Supports tools | [Claude]: https://claude.ai/download +[Cursor]: https://cursor.com [Zed]: https://zed.dev [Cody]: https://sourcegraph.com/cody [Genkit]: https://github.com/firebase/genkit @@ -35,8 +45,16 @@ This page provides an overview of applications that support the Model Context Pr [TheiaAI/TheiaIDE]: https://eclipsesource.com/blogs/2024/12/19/theia-ide-and-theia-ai-support-mcp/ [Superinterface]: https://superinterface.ai [5ire]: https://github.com/nanbingxyz/5ire -[Bee Agent Framework]: https://i-am-bee.github.io/bee-agent-framework [Apify MCP Tester]: https://apify.com/jiri.spilka/tester-mcp-client +[BeeAI Framework]: https://i-am-bee.github.io/beeai-framework +[mcp-agent]: https://github.com/lastmile-ai/mcp-agent +[Mcp.el]: https://github.com/lizqwerscott/mcp.el +[Roo Code]: https://roocode.com +[Goose]: https://block.github.io/goose/docs/goose-architecture/#interoperability-with-extensions +[Windsurf]: https://codeium.com/windsurf +[Daydreams]: https://github.com/daydreamsai/daydreams +[SpinAI]: https://spinai.dev +[OpenSumi]: https://github.com/opensumi/core [Resources]: https://modelcontextprotocol.io/docs/concepts/resources [Prompts]: https://modelcontextprotocol.io/docs/concepts/prompts @@ -56,32 +74,33 @@ The Claude desktop application provides comprehensive support for MCP, enabling > ⓘ Note: The Claude.ai web application does not currently support MCP. MCP features are only available in the desktop application. -### Zed -[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. +### 5ire +[5ire](https://github.com/nanbingxyz/5ire) is an open source cross-platform desktop AI assistant that supports tools through 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 +- Built-in MCP servers can be quickly enabled and disabled. +- Users can add more servers by modifying the configuration file. +- It is open-source and user-friendly, suitable for beginners. +- Future support for MCP will be continuously improved. -### Sourcegraph Cody -[Cody](https://openctx.org/docs/providers/modelcontextprotocol) is Sourcegraph's AI coding assistant, which implements MCP through OpenCTX. +### 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. **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 +- Seamlessly incorporate MCP tools into agentic workflows. +- Quickly instantiate framework-native tools from connected MCP client(s). +- Planned future support for agentic MCP capabilities. -### Firebase Genkit -[Genkit](https://github.com/firebase/genkit) is Firebase's SDK for building and integrating GenAI features into applications. The [genkitx-mcp](https://github.com/firebase/genkit/tree/main/js/plugins/mcp) plugin enables consuming MCP servers as a client or creating MCP servers from Genkit tools and prompts. +**Learn more:** +- [Example of using MCP tools in agentic workflow](https://i-am-bee.github.io/beeai-framework/#/typescript/tools?id=using-the-mcptool-class) + +### Cline +[Cline](https://github.com/cline/cline) is an autonomous coding agent in VS Code that edits files, runs commands, uses a browser, and more–with your permission at each step. **Key features:** -- Client support for tools and prompts (resources partially supported) -- Rich discovery with support in Genkit's Dev UI playground -- Seamless interoperability with Genkit's existing tools and prompts -- Works across a wide variety of GenAI models from top providers +- Create and add tools through natural language (e.g. "add a tool that searches the web") +- 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 ### Continue [Continue](https://github.com/continuedev/continue) is an open-source AI code assistant, with built-in support for all MCP features. @@ -92,6 +111,28 @@ The Claude desktop application provides comprehensive support for MCP, enabling - Use both built-in and MCP tools directly in chat - Supports VS Code and JetBrains IDEs, with any LLM +### Cursor +[Cursor](https://docs.cursor.com/advanced/model-context-protocol) is an AI code editor. + +**Key Features**: +- Support for MCP tools in Cursor Composer +- Support for both STDIO and SSE + +### 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. + +**Key features:** +- Provides MCP tool support for Emacs. + +### Firebase Genkit +[Genkit](https://github.com/firebase/genkit) is Firebase's SDK for building and integrating GenAI features into applications. The [genkitx-mcp](https://github.com/firebase/genkit/tree/main/js/plugins/mcp) plugin enables consuming MCP servers as a client or creating MCP servers from Genkit tools and prompts. + +**Key features:** +- Client support for tools and prompts (resources partially supported) +- Rich discovery with support in Genkit's Dev UI playground +- Seamless interoperability with Genkit's existing tools and prompts +- Works across a wide variety of GenAI models from top providers + ### GenAIScript Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft.github.io/genaiscript/) (in JavaScript). Orchestrate LLMs, tools, and data in JavaScript. @@ -100,13 +141,14 @@ Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft - Abstraction to make it easy and productive - Seamless Visual Studio Code integration -### Cline -[Cline](https://github.com/cline/cline) is an autonomous coding agent in VS Code that edits files, runs commands, uses a browser, and more–with your permission at each step. +### Goose +[Goose](https://github.com/block/goose) is an open source AI agent that supercharges your software development by automating coding tasks. **Key features:** -- Create and add tools through natural language (e.g. "add a tool that searches the web") -- 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 +- Expose MCP functionality to Goose through tools. +- MCPs can be installed directly via the [extensions directory](https://block.github.io/goose/v1/extensions/), CLI, or UI. +- 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. ### LibreChat [LibreChat](https://github.com/danny-avila/LibreChat) is an open-source, customizable AI chat UI that supports multiple AI providers, now including MCP integration. @@ -117,6 +159,49 @@ Programmatically assemble prompts for LLMs using [GenAIScript](https://microsoft - Open-source and self-hostable, with secure multi-user support - Future roadmap includes expanded MCP feature support +### mcp-agent +[mcp-agent] is a simple, composable framework to build agents using Model Context Protocol. + +**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. + +### Roo Code +[Roo Code](https://roocode.com) enables AI coding assistance via MCP. + +**Key features:** +- Support for MCP tools and resources +- Integration with development workflows +- Extensible AI capabilities + +### Sourcegraph Cody +[Cody](https://openctx.org/docs/providers/modelcontextprotocol) is Sourcegraph's AI coding assistant, which implements MCP through OpenCTX. + +**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 + +### SpinAI +[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. + +**Key features:** +- Built-in MCP compatibility for AI agents +- Open-source TypeScript framework +- Observable agent architecture +- Native support for MCP tools integration + +### Superinterface +[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. + +**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) + ### TheiaAI/TheiaIDE [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. @@ -131,33 +216,36 @@ Theia AI and Theia IDE's MCP integration provide users with flexibility, making - [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/) -### Superinterface -[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. +### Windsurf Editor +[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. **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) +- Revolutionary AI Flow paradigm for human-AI collaboration +- Intelligent code generation and understanding +- Rich development tools with multi-model support -### 5ire -[5ire](https://github.com/nanbingxyz/5ire) is an open source cross-platform desktop AI assistant that supports tools through MCP servers. +### Zed +[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. **Key features:** -- Built-in MCP servers can be quickly enabled and disabled. -- Users can add more servers by modifying the configuration file. -- It is open-source and user-friendly, suitable for beginners. -- Future support for MCP will be continuously improved. +- 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 -### Bee Agent Framework -[Bee Agent Framework](https://i-am-bee.github.io/bee-agent-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. +### OpenSumi +[OpenSumi](https://github.com/opensumi/core) is a framework helps you quickly build AI Native IDE products. **Key features:** -- Seamlessly incorporate MCP tools into agentic workflows. -- Quickly instantiate framework-native tools from connected MCP client(s). -- Planned future support for agentic MCP capabilities. +- Supports MCP tools in OpenSumi +- Supports built-in IDE MCP servers and custom MCP servers -**Learn more:** -- [Example of using MCP tools in agentic workflow](https://i-am-bee.github.io/bee-agent-framework/#/tools?id=using-the-mcptool-class) +### Daydreams +[Daydreams](https://github.com/daydreamsai/daydreams) is a generative agent framework for executing anything onchain + +**Key features:** +- Supports MCP Servers in config +- Exposes MCP Client ### Apify MCP Tester diff --git a/development/updates.mdx b/development/updates.mdx index f7fc2d4..f40e933 100644 --- a/development/updates.mdx +++ b/development/updates.mdx @@ -3,6 +3,18 @@ title: "What's New" description: 'The latest updates and improvements to MCP' --- + + - 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) @@ -16,4 +28,4 @@ description: 'The latest updates and improvements to MCP' - 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) - \ No newline at end of file + diff --git a/docs.json b/docs.json new file mode 100644 index 0000000..bbaa85f --- /dev/null +++ b/docs.json @@ -0,0 +1,140 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "willow", + "name": "Model Context Protocol", + "colors": { + "primary": "#09090b", + "light": "#FAFAFA", + "dark": "#09090b" + }, + "favicon": "/favicon.svg", + "navigation": { + "tabs": [ + { + "tab": "Documentation", + "groups": [ + { + "group": "Get Started", + "pages": [ + "introduction", + { + "group": "Quickstart", + "pages": [ + "quickstart/server", + "quickstart/client", + "quickstart/user" + ] + }, + "examples", + "clients" + ] + }, + { + "group": "Tutorials", + "pages": [ + "tutorials/building-mcp-with-llms", + "docs/tools/debugging", + "docs/tools/inspector" + ] + }, + { + "group": "Concepts", + "pages": [ + "docs/concepts/architecture", + "docs/concepts/resources", + "docs/concepts/prompts", + "docs/concepts/tools", + "docs/concepts/sampling", + "docs/concepts/roots", + "docs/concepts/transports" + ] + }, + { + "group": "Development", + "pages": [ + "development/updates", + "development/roadmap", + "development/contributing" + ] + } + ] + }, + { + "tab": "SDKs", + "icon": "book-open", + "groups": [ + { + "group": "Java", + "pages": [ + "sdk/java/mcp-overview", + "sdk/java/mcp-client", + "sdk/java/mcp-server" + ] + } + ] + } + ], + "global": { + "anchors": [ + { + "anchor": "Python SDK", + "href": "https://github.com/modelcontextprotocol/python-sdk", + "icon": "python" + }, + { + "anchor": "TypeScript SDK", + "href": "https://github.com/modelcontextprotocol/typescript-sdk", + "icon": "square-js" + }, + { + "anchor": "Java SDK", + "href": "https://github.com/modelcontextprotocol/java-sdk", + "icon": "java" + }, + { + "anchor": "Kotlin SDK", + "href": "https://github.com/modelcontextprotocol/kotlin-sdk", + "icon": "square-k" + }, + { + "anchor": "Specification", + "href": "https://spec.modelcontextprotocol.io", + "icon": "book" + } + ] + } + }, + "logo": { + "light": "/logo/light.svg", + "dark": "/logo/dark.svg" + }, + "navbar": { + "links": [], + "primary": { + "type": "button", + "label": "GitHub", + "href": "https://github.com/modelcontextprotocol" + } + }, + "seo": { + "metatags": { + "og:image": "https://raw.githubusercontent.com/modelcontextprotocol/docs/2eb6171ddbfeefde349dc3b8d5e2b87414c26250/images/og-image.png" + }, + "indexing": "navigable" + }, + "footer": { + "socials": { + "github": "https://github.com/modelcontextprotocol" + } + }, + "redirects": [ + { + "source": "/tutorials/building-a-client", + "destination": "/quickstart/client" + }, + { + "source": "/quickstart", + "destination": "/quickstart/server" + } + ] +} diff --git a/docs/concepts/architecture.mdx b/docs/concepts/architecture.mdx index 164628a..6d990e6 100644 --- a/docs/concepts/architecture.mdx +++ b/docs/concepts/architecture.mdx @@ -15,7 +15,7 @@ MCP follows a client-server architecture where: ```mermaid flowchart LR - subgraph " Host (e.g., Claude Desktop) " + subgraph "Host" client1[MCP Client] client2[MCP Client] end diff --git a/examples.mdx b/examples.mdx index 49cbd7f..6edfbcc 100644 --- a/examples.mdx +++ b/examples.mdx @@ -49,6 +49,7 @@ These MCP servers are maintained by companies for their platforms: - **[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 ## Community highlights diff --git a/images/java/class-diagrams.puml b/images/java/class-diagrams.puml new file mode 100644 index 0000000..5b08c73 --- /dev/null +++ b/images/java/class-diagrams.puml @@ -0,0 +1,282 @@ +@startuml Core Components + +' Core Interfaces +interface McpTransport { + +Mono connect(Function, Mono> handler) + +Mono sendMessage(JSONRPCMessage message) + +void close() + +Mono closeGracefully() + + T unmarshalFrom(Object data, TypeReference typeRef) +} + +interface McpSession { + + Mono sendRequest(String method, Object requestParams, TypeReference typeRef) + +Mono sendNotification(String method, Map params) + +Mono closeGracefully() + +void close() +} + +' Core Implementation Classes +class DefaultMcpSession { + +interface RequestHandler + +interface NotificationHandler +} + +' Client Classes +class McpClient { + +{static} Builder using(ClientMcpTransport transport) +} + +class McpAsyncClient { + +Mono initialize() + +ServerCapabilities getServerCapabilities() + +Implementation getServerInfo() + +ClientCapabilities getClientCapabilities() + +Implementation getClientInfo() + +void close() + +Mono closeGracefully() + +Mono ping() + +Mono addRoot(Root root) + +Mono removeRoot(String rootUri) + +Mono rootsListChangedNotification() + +Mono callTool(CallToolRequest request) + +Mono listTools() + +Mono listResources() + +Mono readResource(ReadResourceRequest request) + +Mono listResourceTemplates() + +Mono subscribeResource(SubscribeRequest request) + +Mono unsubscribeResource(UnsubscribeRequest request) + +Mono listPrompts() + +Mono getPrompt(GetPromptRequest request) + +Mono setLoggingLevel(LoggingLevel level) +} + +class McpSyncClient { + +InitializeResult initialize() + +ServerCapabilities getServerCapabilities() + +Implementation getServerInfo() + +ClientCapabilities getClientCapabilities() + +Implementation getClientInfo() + +void close() + +boolean closeGracefully() + +Object ping() + +void addRoot(Root root) + +void removeRoot(String rootUri) + +void rootsListChangedNotification() + +CallToolResult callTool(CallToolRequest request) + +ListToolsResult listTools() + +ListResourcesResult listResources() + +ReadResourceResult readResource(ReadResourceRequest request) + +ListResourceTemplatesResult listResourceTemplates() + +void subscribeResource(SubscribeRequest request) + +void unsubscribeResource(UnsubscribeRequest request) + +ListPromptsResult listPrompts() + +GetPromptResult getPrompt(GetPromptRequest request) + +void setLoggingLevel(LoggingLevel level) +} + +' Server Classes +class McpServer { + +{static} Builder using(ServerMcpTransport transport) +} + +class McpAsyncServer { + + +ServerCapabilities getServerCapabilities() + +Implementation getServerInfo() + +ClientCapabilities getClientCapabilities() + +Implementation getClientInfo() + +void close() + +Mono closeGracefully() + + ' Tool Management + +Mono addTool(ToolRegistration toolRegistration) + +Mono removeTool(String toolName) + +Mono notifyToolsListChanged() + + ' Resource Management + +Mono addResource(ResourceRegistration resourceHandler) + +Mono removeResource(String resourceUri) + +Mono notifyResourcesListChanged() + + ' Prompt Management + +Mono addPrompt(PromptRegistration promptRegistration) + +Mono removePrompt(String promptName) + +Mono notifyPromptsListChanged() + + ' Logging + +Mono loggingNotification(LoggingMessageNotification notification) + + ' Sampling + +Mono createMessage(CreateMessageRequest request) +} + +class McpSyncServer { + +McpAsyncServer getAsyncServer() + + +ServerCapabilities getServerCapabilities() + +Implementation getServerInfo() + +ClientCapabilities getClientCapabilities() + +Implementation getClientInfo() + +void close() + +void closeGracefully() + + ' Tool Management + +void addTool(ToolRegistration toolHandler) + +void removeTool(String toolName) + +void notifyToolsListChanged() + + ' Resource Management + +void addResource(ResourceRegistration resourceHandler) + +void removeResource(String resourceUri) + +void notifyResourcesListChanged() + + ' Prompt Management + +void addPrompt(PromptRegistration promptRegistration) + +void removePrompt(String promptName) + +void notifyPromptsListChanged() + + ' Logging + +void loggingNotification(LoggingMessageNotification notification) + + ' Sampling + +CreateMessageResult createMessage(CreateMessageRequest request) +} + +' Transport Implementations +class StdioClientTransport implements ClientMcpTransport { + +void setErrorHandler(Consumer errorHandler) + +Sinks.Many getErrorSink() +} + +class StdioServerTransport implements ServerMcpTransport { +} + + +class HttpServletSseServerTransport implements ServerMcpTransport { +} + + +class HttpClientSseClientTransport implements ClientMcpTransport { +} + + +class WebFluxSseClientTransport implements ClientMcpTransport { +} + + +class WebFluxSseServerTransport implements ServerMcpTransport { + +RouterFunction getRouterFunction() +} + +class WebMvcSseServerTransport implements ServerMcpTransport { + +RouterFunction getRouterFunction() +} + + +' Schema and Error Classes +class McpSchema { + +class ErrorCodes + +interface Request + +interface JSONRPCMessage + +interface ResourceContents + +interface Content + +interface ServerCapabilities + +{static} JSONRPCMessage deserializeJsonRpcMessage() +} + +class McpError { +} + +' Relationships +McpTransport <|.. ClientMcpTransport +McpTransport <|.. ServerMcpTransport + +McpSession <|.. DefaultMcpSession +DefaultMcpSession --o McpAsyncClient +DefaultMcpSession --o McpAsyncServer + +McpClient ..> McpAsyncClient : creates +McpClient ..> McpSyncClient : creates +McpSyncClient --> McpAsyncClient : delegates to + +McpServer ..> McpAsyncServer : creates +McpServer ..> McpSyncServer : creates +McpSyncServer o-- McpAsyncServer + +DefaultMcpSession o-- McpTransport +McpSchema <.. McpSession : uses +McpError ..> McpSession : throws + +@enduml + +@startuml Message Flow + +package "MCP Schema" { + interface JSONRPCMessage { + +String jsonrpc() + } + + interface Request { + } + + class InitializeRequest + class CallToolRequest + class ListToolsRequest + class ListResourcesRequest + class ReadResourceRequest + class ListResourceTemplatesRequest + class ListPromptsRequest + class GetPromptRequest +} + +package "Resource Types" { + interface ResourceContents { + +String uri() + +String mimeType() + } + + class TextResourceContents + class BlobResourceContents + + interface Content { + +String type() + } + + class TextContent + class ImageContent + class EmbeddedResource + + interface Annotated { + +Annotations annotations() + } + + interface PromptOrResourceReference { + +String type() + } + + class PromptReference + class ResourceReference +} + +JSONRPCMessage <|.. Request +Request <|.. InitializeRequest +Request <|.. CallToolRequest +Request <|.. ListToolsRequest +Request <|.. ListResourcesRequest +Request <|.. ReadResourceRequest +Request <|.. ListResourceTemplatesRequest +Request <|.. ListPromptsRequest +Request <|.. GetPromptRequest + +ResourceContents <|.. TextResourceContents +ResourceContents <|.. BlobResourceContents + +Content <|.. TextContent +Content <|.. ImageContent +Content <|.. EmbeddedResource + +PromptOrResourceReference <|.. PromptReference +PromptOrResourceReference <|.. ResourceReference + +@enduml diff --git a/images/java/java-mcp-client-architecture.jpg b/images/java/java-mcp-client-architecture.jpg new file mode 100644 index 0000000..688a2b4 Binary files /dev/null and b/images/java/java-mcp-client-architecture.jpg differ diff --git a/images/java/java-mcp-server-architecture.jpg b/images/java/java-mcp-server-architecture.jpg new file mode 100644 index 0000000..4b05ca1 Binary files /dev/null and b/images/java/java-mcp-server-architecture.jpg differ diff --git a/images/java/java-mcp-uml-classdiagram.svg b/images/java/java-mcp-uml-classdiagram.svg new file mode 100644 index 0000000..f83a586 --- /dev/null +++ b/images/java/java-mcp-uml-classdiagram.svg @@ -0,0 +1 @@ +McpTransportMono<Void> connect(Function<Mono<JSONRPCMessage>, Mono<JSONRPCMessage>> handler)Mono<Void> sendMessage(JSONRPCMessage message)void close()Mono<Void> closeGracefully()<T> T unmarshalFrom(Object data, TypeReference<T> typeRef)McpSession<T> Mono<T> sendRequest(String method, Object requestParams, TypeReference<T> typeRef)Mono<Void> sendNotification(String method, Map<String, Object> params)Mono<Void> closeGracefully()void close()DefaultMcpSessioninterface RequestHandlerinterface NotificationHandlerMcpClientBuilder using(ClientMcpTransport transport)McpAsyncClientMono<InitializeResult> initialize()ServerCapabilities getServerCapabilities()Implementation getServerInfo()ClientCapabilities getClientCapabilities()Implementation getClientInfo()void close()Mono<Void> closeGracefully()Mono<Object> ping()Mono<Void> addRoot(Root root)Mono<Void> removeRoot(String rootUri)Mono<Void> rootsListChangedNotification()Mono<CallToolResult> callTool(CallToolRequest request)Mono<ListToolsResult> listTools()Mono<ListResourcesResult> listResources()Mono<ReadResourceResult> readResource(ReadResourceRequest request)Mono<ListResourceTemplatesResult> listResourceTemplates()Mono<Void> subscribeResource(SubscribeRequest request)Mono<Void> unsubscribeResource(UnsubscribeRequest request)Mono<ListPromptsResult> listPrompts()Mono<GetPromptResult> getPrompt(GetPromptRequest request)Mono<Void> setLoggingLevel(LoggingLevel level)McpSyncClientInitializeResult initialize()ServerCapabilities getServerCapabilities()Implementation getServerInfo()ClientCapabilities getClientCapabilities()Implementation getClientInfo()void close()boolean closeGracefully()Object ping()void addRoot(Root root)void removeRoot(String rootUri)void rootsListChangedNotification()CallToolResult callTool(CallToolRequest request)ListToolsResult listTools()ListResourcesResult listResources()ReadResourceResult readResource(ReadResourceRequest request)ListResourceTemplatesResult listResourceTemplates()void subscribeResource(SubscribeRequest request)void unsubscribeResource(UnsubscribeRequest request)ListPromptsResult listPrompts()GetPromptResult getPrompt(GetPromptRequest request)void setLoggingLevel(LoggingLevel level)McpServerBuilder using(ServerMcpTransport transport)McpAsyncServerServerCapabilities getServerCapabilities()Implementation getServerInfo()ClientCapabilities getClientCapabilities()Implementation getClientInfo()void close()Mono<Void> closeGracefully() Mono<Void> addTool(ToolRegistration toolRegistration)Mono<Void> removeTool(String toolName)Mono<Void> notifyToolsListChanged() Mono<Void> addResource(ResourceRegistration resourceHandler)Mono<Void> removeResource(String resourceUri)Mono<Void> notifyResourcesListChanged() Mono<Void> addPrompt(PromptRegistration promptRegistration)Mono<Void> removePrompt(String promptName)Mono<Void> notifyPromptsListChanged() Mono<Void> loggingNotification(LoggingMessageNotification notification) Mono<CreateMessageResult> createMessage(CreateMessageRequest request)McpSyncServerMcpAsyncServer getAsyncServer() ServerCapabilities getServerCapabilities()Implementation getServerInfo()ClientCapabilities getClientCapabilities()Implementation getClientInfo()void close()void closeGracefully() void addTool(ToolRegistration toolHandler)void removeTool(String toolName)void notifyToolsListChanged() void addResource(ResourceRegistration resourceHandler)void removeResource(String resourceUri)void notifyResourcesListChanged() void addPrompt(PromptRegistration promptRegistration)void removePrompt(String promptName)void notifyPromptsListChanged() void loggingNotification(LoggingMessageNotification notification) CreateMessageResult createMessage(CreateMessageRequest request)StdioClientTransportvoid setErrorHandler(Consumer<String> errorHandler)Sinks.Many<String> getErrorSink()ClientMcpTransportStdioServerTransportServerMcpTransportHttpServletSseServerTransportHttpClientSseClientTransportWebFluxSseClientTransportWebFluxSseServerTransportRouterFunction<?> getRouterFunction()WebMvcSseServerTransportRouterFunction<?> getRouterFunction()McpSchemaclass ErrorCodesinterface Requestinterface JSONRPCMessageinterface ResourceContentsinterface Contentinterface ServerCapabilitiesJSONRPCMessage deserializeJsonRpcMessage()McpErrorcreatescreatesdelegates tocreatescreatesusesthrows \ No newline at end of file diff --git a/images/java/mcp-stack.svg b/images/java/mcp-stack.svg new file mode 100644 index 0000000..3847eaa --- /dev/null +++ b/images/java/mcp-stack.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/introduction.mdx b/introduction.mdx index 8620277..b9b01d8 100644 --- a/introduction.mdx +++ b/introduction.mdx @@ -3,7 +3,7 @@ title: Introduction description: 'Get started with the Model Context Protocol (MCP)' --- -Kotlin SDK released! Check out [what else is new.](/development/updates) +Java 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. diff --git a/mint.json b/mint.json deleted file mode 100644 index 265a246..0000000 --- a/mint.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "$schema": "https://mintlify.com/schema.json", - "name": "Model Context Protocol", - "logo": { - "dark": "/logo/dark.svg", - "light": "/logo/light.svg" - }, - "favicon": "/favicon.svg", - "theme": "quill", - "colors": { - "primary": "#09090b", - "light": "#FAFAFA", - "dark": "#09090b" - }, - "topbarLinks": [], - "topbarCtaButton": { - "name": "GitHub", - "url": "https://github.com/modelcontextprotocol" - }, - "search": { - "location": "top" - }, - "anchors": [ - { - "name": "Python SDK", - "icon": "python", - "url": "https://github.com/modelcontextprotocol/python-sdk" - }, - { - "name": "TypeScript SDK", - "icon": "square-js", - "url": "https://github.com/modelcontextprotocol/typescript-sdk" - }, - { - "name": "Kotlin SDK", - "icon": "square-k", - "url": "https://github.com/modelcontextprotocol/kotlin-sdk" - }, - { - "name": "Specification", - "icon": "book", - "url": "https://spec.modelcontextprotocol.io" - } - ], - "navigation": [ - { - "group": "Get Started", - "pages": [ - "introduction", - { - "group": "Quickstart", - "pages": ["quickstart/server", "quickstart/client", "quickstart/user"] - }, - "examples", - "clients" - ] - }, - - { - "group": "Tutorials", - "pages": [ - "tutorials/building-mcp-with-llms", - "docs/tools/debugging", - "docs/tools/inspector" - ] - }, - { - "group": "Concepts", - "pages": [ - "docs/concepts/architecture", - "docs/concepts/resources", - "docs/concepts/prompts", - "docs/concepts/tools", - "docs/concepts/sampling", - "docs/concepts/roots", - "docs/concepts/transports" - ] - }, - { - "group": "Development", - "pages": [ - "development/updates", - "development/roadmap", - "development/contributing" - ] - } - ], - "footerSocials": { - "github": "https://github.com/modelcontextprotocol" - }, - "feedback": { - "thumbsRating": true - }, - "redirects": [ - { - "source": "/tutorials/building-a-client", - "destination": "/quickstart/client" - }, - { - "source": "/quickstart", - "destination": "/quickstart/server" - } - ], - "metadata": { - "og:image": "https://raw.githubusercontent.com/modelcontextprotocol/docs/2eb6171ddbfeefde349dc3b8d5e2b87414c26250/images/og-image.png" - } -} diff --git a/quickstart/client.mdx b/quickstart/client.mdx index ab7866e..9d5161c 100644 --- a/quickstart/client.mdx +++ b/quickstart/client.mdx @@ -8,7 +8,7 @@ In this tutorial, you'll learn how to build a LLM-powered chatbot client that co -[You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client) +[You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-python) ## System Requirements @@ -19,7 +19,7 @@ Before starting, ensure your system meets these requirements: ## Setting Up Your Environment -First, create a new Python project with `uv`: +First, create a new Python project with `uv`: ```bash # Create project directory @@ -104,7 +104,7 @@ Next, we'll implement the method to connect to an MCP server: ```python async def connect_to_server(self, server_script_path: str): """Connect to an MCP server - + Args: server_script_path: Path to the server script (.py or .js) """ @@ -112,20 +112,20 @@ async def connect_to_server(self, server_script_path: str): 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 ) - + 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)) - + await self.session.initialize() - + # List available tools response = await self.session.list_tools() tools = response.tools @@ -147,7 +147,7 @@ async def process_query(self, query: str) -> str: ] response = await self.session.list_tools() - available_tools = [{ + available_tools = [{ "name": tool.name, "description": tool.description, "input_schema": tool.inputSchema @@ -162,30 +162,35 @@ async def process_query(self, query: str) -> str: ) # Process response and handle tool calls - tool_results = [] final_text = [] + 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 - + # Execute tool call result = await self.session.call_tool(tool_name, tool_args) - tool_results.append({"call": tool_name, "result": result}) final_text.append(f"[Calling tool {tool_name} with args {tool_args}]") - # Continue conversation with tool results - if hasattr(content, 'text') and content.text: - messages.append({ - "role": "assistant", - "content": content.text - }) + assistant_message_content.append(content) messages.append({ - "role": "user", - "content": result.content + "role": "assistant", + "content": assistant_message_content + }) + messages.append({ + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": content.id, + "content": result.content + } + ] }) # Get next response from Claude @@ -193,6 +198,7 @@ async def process_query(self, query: str) -> str: model="claude-3-5-sonnet-20241022", max_tokens=1000, messages=messages, + tools=available_tools ) final_text.append(response.content[0].text) @@ -208,17 +214,17 @@ async def chat_loop(self): """Run an interactive chat loop""" print("\nMCP Client Started!") print("Type your queries or 'quit' to exit.") - + while True: try: query = input("\nQuery: ").strip() - + if query.lower() == 'quit': break - + response = await self.process_query(query) print("\n" + response) - + except Exception as e: print(f"\nError: {str(e)}") @@ -236,7 +242,7 @@ async def main(): if len(sys.argv) < 2: print("Usage: python client.py ") sys.exit(1) - + client = MCPClient() try: await client.connect_to_server(sys.argv[1]) @@ -394,6 +400,572 @@ If you see: + + +[You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/mcp-client-typescript) +## System Requirements + +Before starting, ensure your system meets these requirements: +- Mac or Windows computer +- Node.js 16 or higher installed +- Latest version of `npm` installed +- Anthropic API key (Claude) + +## Setting Up Your Environment + +First, let's create and set up our project: + + +```bash MacOS/Linux +# Create project directory +mkdir mcp-client-typescript +cd mcp-client-typescript + +# Initialize npm project +npm init -y + +# Install dependencies +npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv + +# Install dev dependencies +npm install -D @types/node typescript + +# Create source file +touch index.ts +``` + +```powershell Windows +# Create project directory +md mcp-client-typescript +cd mcp-client-typescript + +# Initialize npm project +npm init -y + +# Install dependencies +npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv + +# Install dev dependencies +npm install -D @types/node typescript + +# Create source file +new-item index.ts +``` + + +Update your `package.json` to set `type: "module"` and a build script: + +```json package.json +{ + "type": "module", + "scripts": { + "build": "tsc && chmod 755 build/index.js" + } +} +``` + +Create a `tsconfig.json` in the root of your project: + +```json tsconfig.json +{ + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "outDir": "./build", + "rootDir": "./", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["index.ts"], + "exclude": ["node_modules"] +} +``` + +## Setting Up Your API Key + +You'll need an Anthropic API key from the [Anthropic Console](https://console.anthropic.com/settings/keys). + +Create a `.env` file to store it: + +```bash +echo "ANTHROPIC_API_KEY=" > .env +``` + +Add `.env` to your `.gitignore`: +```bash +echo ".env" >> .gitignore +``` + + +Make sure you keep your `ANTHROPIC_API_KEY` secure! + + +## Creating the Client + +### Basic Client Structure + +First, let's set up our imports and create the basic client class in `index.ts`: + +```typescript +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"; + +dotenv.config(); + +const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; +if (!ANTHROPIC_API_KEY) { + throw new Error("ANTHROPIC_API_KEY is not set"); +} + +class MCPClient { + private mcp: Client; + private anthropic: Anthropic; + private transport: StdioClientTransport | null = null; + private tools: Tool[] = []; + + 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 +} +``` + +### Server Connection Management + +Next, we'll implement the method to connect to an MCP server: + +```typescript +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; + + this.transport = new StdioClientTransport({ + command, + args: [serverScriptPath], + }); + this.mcp.connect(this.transport); + + 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; + } +} +``` + +### Query Processing Logic + +Now let's add the core functionality for processing queries and handling tool calls: + +```typescript +async processQuery(query: string) { + const messages: MessageParam[] = [ + { + role: "user", + content: query, + }, + ]; + + const response = await this.anthropic.messages.create({ + model: "claude-3-5-sonnet-20241022", + max_tokens: 1000, + messages, + tools: this.tools, + }); + + const finalText = []; + const toolResults = []; + + 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; + + const result = await this.mcp.callTool({ + name: toolName, + arguments: toolArgs, + }); + toolResults.push(result); + finalText.push( + `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]` + ); + + messages.push({ + role: "user", + content: result.content as string, + }); + + const response = await this.anthropic.messages.create({ + model: "claude-3-5-sonnet-20241022", + max_tokens: 1000, + messages, + }); + + finalText.push( + response.content[0].type === "text" ? response.content[0].text : "" + ); + } + } + + return finalText.join("\n"); +} +``` + +### Interactive Chat Interface + +Now we'll add the chat loop and cleanup functionality: + +```typescript +async chatLoop() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + try { + console.log("\nMCP Client Started!"); + console.log("Type your queries or 'quit' to exit."); + + 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(); + } +} + +async cleanup() { + await this.mcp.close(); +} +``` + +### Main Entry Point + +Finally, we'll add the main execution logic: + +```typescript +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); + } +} + +main(); +``` + +## Running the Client + +To run your client with any MCP server: + +```bash +# Build TypeScript +npm run build + +# Run the client +node build/index.js path/to/server.py # python server +node build/index.js path/to/build/index.js # node server +``` + + +If you're continuing the weather tutorial from the server quickstart, your command might look something like this: `node build/index.js .../quickstart-resources/weather-server-typescript/build/index.js` + + +**The client will:** +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 + +## How It Works + +When you submit a query: + +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 + +## Best practices + +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 + +2. **Security** + - Store API keys securely in `.env` + - Validate server responses + - Be cautious with tool permissions + +## Troubleshooting + +### Server Path Issues +- 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) + +Example of correct path usage: +```bash +# Relative path +node build/index.js ./server/build/index.js + +# Absolute path +node build/index.js /Users/username/projects/mcp-server/build/index.js + +# 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 +``` + +### Response Timing +- 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 + +### Common Error Messages + +If you see: +- `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 + + + + + + + +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 + + +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/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) + +## System Requirements + +Before starting, ensure your system meets these requirements: +- Java 17 or higher +- Maven 3.6+ +- npx package manager +- Anthropic API key (Claude) +- Brave Search API key + +## Setting Up Your Environment + +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: + ```bash + npm install -g npx + ``` + +2. Clone the repository: + ```bash + git clone https://github.com/spring-projects/spring-ai-examples.git + cd model-context-protocol/brave-chatbot + ``` + +3. Set up your API keys: + ```bash + export ANTHROPIC_API_KEY='your-anthropic-api-key-here' + export BRAVE_API_KEY='your-brave-api-key-here' + ``` + +4. Build the application: + ```bash + ./mvnw clean install + ``` + +5. Run the application using Maven: + ```bash + ./mvnw spring-boot:run + ``` + + +Make sure you keep your `ANTHROPIC_API_KEY` and `BRAVE_API_KEY` keys secure! + + + +## How it Works + +The application integrates Spring AI with the Brave Search MCP server through several components: + +### MCP Client Configuration + +1. Required dependencies in pom.xml: +```xml + + org.springframework.ai + spring-ai-mcp-client-spring-boot-starter + + + org.springframework.ai + spring-ai-anthropic-spring-boot-starter + +``` + +2. Application properties (application.yml): +```yml +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 + anthropic: + api-key: ${ANTHROPIC_API_KEY} +``` + +This activates the `spring-ai-mcp-client-spring-boot-starter` to create one or more `McpClient`s based on the provided server configuration. + +3. MCP Server Configuration (`mcp-servers-config.json`): +```json +{ + "mcpServers": { + "brave-search": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-brave-search" + ], + "env": { + "BRAVE_API_KEY": "" + } + } + } +} +``` + +### Chat Implementation + +The chatbot is implemented using Spring AI's ChatClient with MCP tool integration: + +```java +var chatClient = chatClientBuilder + .defaultSystem("You are useful assistant, expert in AI and Java.") + .defaultTools((Object[]) mcpToolAdapter.toolCallbacks()) + .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())) + .build(); +``` + +Key features: +- 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 + +### Build and run + +```bash +./mvnw clean install +java -jar ./target/ai-mcp-brave-chatbot-0.0.1-SNAPSHOT.jar +``` + +or + +```bash +./mvnw spring-boot:run +``` + +The application will start an interactive chat session where you can ask questions. The chatbot will use Brave Search when it needs to find information from the internet to answer your queries. + +The chatbot can: +- Answer questions using its built-in knowledge +- Perform web searches when needed using Brave Search +- Remember context from previous messages in the conversation +- Combine information from multiple sources to provide comprehensive answers + +### Advanced Configuration + +The MCP client supports additional configuration options: + +- Client customization through `McpSyncClientCustomizer` or `McpAsyncClientCustomizer` +- Multiple clients with multiple transport types: `STDIO` and `SSE` (Server-Sent Events) +- Integration with Spring AI's tool execution framework +- Automatic client initialization and lifecycle management + +For WebFlux-based applications, you can use the WebFlux starter instead: + +```xml + + org.springframework.ai + spring-ai-mcp-client-webflux-spring-boot-starter + +``` + +This provides similar functionality but uses a WebFlux-based SSE transport implementation, recommended for production deployments. + + + ## Next steps @@ -416,7 +988,7 @@ If you see: Learn how to use LLMs like Claude to speed up your MCP development @@ -427,4 +999,4 @@ If you see: > Understand how MCP connects clients, servers, and LLMs - \ No newline at end of file + diff --git a/quickstart/server.mdx b/quickstart/server.mdx index ec1972d..b391fea 100644 --- a/quickstart/server.mdx +++ b/quickstart/server.mdx @@ -311,12 +311,12 @@ Make sure you pass in the absolute path to your server. This tells Claude for Desktop: 1. There's an MCP server named "weather" -2. To launch it by running `uv --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather run weather` +2. To launch it by running `uv --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather run weather.py` Save the file, and restart **Claude for Desktop**. - + Let's get started with building our weather server! [You can find the complete code for what we'll be building here.](https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-typescript) ### Prerequisite knowledge @@ -386,7 +386,7 @@ Update your package.json to add type: "module" and a build script: "weather": "./build/index.js" }, "scripts": { - "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", + "build": "tsc && chmod 755 build/index.js" }, "files": [ "build" @@ -739,6 +739,299 @@ This tells Claude for Desktop: 2. Launch it by running `node /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/index.js` Save the file, and restart **Claude for Desktop**. + + + + +This is a quickstart demo based on Spring AI MCP auto-configuration and boot starters. +To learn how to create sync and async MCP Servers, manually, consult the [Java SDK Server](/sdk/java/mcp-server) documentation. + + + +Let's get started with building our weather server! +[You can find the complete code for what we'll be building here.](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-stdio-server) + +For more information, see the [MCP Server Boot Starter](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html) reference documentation. +For manual MCP Server implementation, refer to the [MCP Server Java SDK documentation](/sdk/java/mcp-server). + +### System requirements + +- Java 17 or higher installed. +- [Spring Boot 3.3.x](https://docs.spring.io/spring-boot/installing.html) or higher + +### Set up your environment + +Use the [Spring Initizer](https://start.spring.io/) to bootstrat the project. + +You will need to add the following dependencies: + + + + ```xml + + + org.springframework.ai + spring-ai-mcp-server-spring-boot-starter + + + + org.springframework + spring-web + + + ``` + + + ```groovy + dependencies { + implementation platform("org.springframework.ai:spring-ai-mcp-server-spring-boot-starter") + implementation platform("org.springframework:spring-web") + } + ``` + + + +Then configure your application by setting the applicaiton properties: + + + +```bash application.properties +spring.main.bannerMode=off +logging.pattern.console= +``` + +```yaml application.yml +logging: + pattern: + console: +spring: + main: + banner-mode: off +``` + + +The [Server Configuration Properties](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html#_configuration_properties) documents all available properties. + +Now let's dive into building your server. + +## Building your server + +### Weather Service + +Let's implement a [WeatheService.java](https://github.com/spring-projects/spring-ai-examples/blob/main/model-context-protocol/weather/starter-stdio-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java) that uses a REST client to query the data from the National Weather Service API: + +```java +@Service +public class WeatherService { + + private final RestClient restClient; + + public WeatherService() { + this.restClient = RestClient.builder() + .baseUrl("https://api.weather.gov") + .defaultHeader("Accept", "application/geo+json") + .defaultHeader("User-Agent", "WeatherApiClient/1.0 (your@email.com)") + .build(); + } + + @Tool(description = "Get weather forecast for a specific latitude/longitude") + public String getWeatherForecastByLocation( + double latitude, // Latitude coordinate + double longitude // Longitude coordinate + ) { + // Returns detailed forecast including: + // - Temperature and unit + // - Wind speed and direction + // - Detailed forecast description + } + + @Tool(description = "Get weather alerts for a US state") + public String getAlerts( + @ToolParam(description = "Two-letter US state code (e.g. CA, NY") String state) + ) { + // Returns active alerts including: + // - Event type + // - Affected area + // - Severity + // - Description + // - Safety instructions + } + + // ...... +} +``` + +The `@Service` annotation with auto-register the service in your applicaiton context. +The Spring AI `@Tool` annotation, making it easy to create and maintain MCP tools. + +The auto-configuration will automatically register these tools with the MCP server. + +### Create your Boot Applicaiton + +```java +@SpringBootApplication +public class McpServerApplication { + + public static void main(String[] args) { + SpringApplication.run(McpServerApplication.class, args); + } + + @Bean + public ToolCallbackProvider weatherTools(WeatherService weatherService) { + return MethodToolCallbackProvider.builder().toolObjects(weatherService).build(); + } +} +``` + +Uses the the `MethodToolCallbackProvider` utils to convert the `@Tools` into actionalble callbackes used by the MCP server. + +### Running the server + +Finally, let's build the server: + +```bash +./mvnw clean install +``` + +This will generate a `mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar` file within the `target` folder. + +Let's now test your server from an existing MCP host, Claude for Desktop. + +## Testing your server with Claude for Desktop + + +Claude for Desktop is not yet available on Linux. + + +First, make sure you have Claude for Desktop installed. +[You can install the latest version here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.** + +We'll need to configure Claude for Desktop for whichever MCP servers you want to use. +To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor. +Make sure to create the file if it doesn't exist. + +For example, if you have [VS Code](https://code.visualstudio.com/) installed: + + + + ```bash + code ~/Library/Application\ Support/Claude/claude_desktop_config.json + ``` + + + ```powershell + code $env:AppData\Claude\claude_desktop_config.json + ``` + + + +You'll then add your servers in the `mcpServers` key. +The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured. + +In this case, we'll add our single weather server like so: + + + + ```json java + { + "mcpServers": { + "spring-ai-mcp-weather": { + "command": "java", + "args": [ + "-Dspring.ai.mcp.server.stdio=true", + "-jar", + "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar" + ] + } + } + } + ``` + + + + ```json java + { + "mcpServers": { + "spring-ai-mcp-weather": { + "command": "java", + "args": [ + "-Dspring.ai.mcp.server.transport=STDIO", + "-jar", + "C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather\\mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar" + ] + } + } + } + ``` + + + + +Make sure you pass in the absolute path to your server. + + +This tells Claude for Desktop: +1. There's an MCP server named "my-weather-server" +2. To launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar` + +Save the file, and restart **Claude for Desktop**. + +## Testing your server with Java client + +### Create a MCP Client manually + +Use the `McpClient` to connect to the server: + +```java +var stdioParams = ServerParameters.builder("java") + .args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar") + .build(); + +var stdioTransport = new StdioClientTransport(stdioParams); + +var mcpClient = McpClient.sync(stdioTransport).build(); + +mcpClient.initialize(); + +ListToolsResult toolsList = mcpClient.listTools(); + +CallToolResult weather = mcpClient.callTool( + new CallToolRequest("getWeatherForecastByLocation", + Map.of("latitude", "47.6062", "longitude", "-122.3321"))); + +CallToolResult alert = mcpClient.callTool( + new CallToolRequest("getAlerts", Map.of("state", "NY"))); + +mcpClient.closeGracefully(); +``` + +### Use MCP Client Boot Starter + +Create a new boot starter applicaiton using the `spring-ai-mcp-client-spring-boot-starter` dependency: + +```xml + + org.springframework.ai + spring-ai-mcp-client-spring-boot-starter + +``` + +and set the `spring.ai.mcp.client.stdio.servers-configuration` property to point to your `claude_desktop_config.json`. +You can re-use the existing Anthropic Destop configuration: + +```properties +spring.ai.mcp.client.stdio.servers-configuration=file:PATH/TO/claude_desktop_config.json +``` + +When you stasrt your client applicaiton, the auto-configuration will create, automatically MCP clients from the claude_desktop_config.json. + +For more information, see the [MCP Client Boot Starters](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-client-docs.html) reference documentation. + +## More Java MCP Server examples + +The [starter-webflux-server](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-webflux-server) demonstrates how to create a MCP server using SSE transport. +It showcases how to define and register MCP Tools, Resources, and Prompts, using the Spring Boot's auto-configuration capabilities. + @@ -872,7 +1165,7 @@ For more advanced troubleshooting, check out our guide on [Debugging MCP](/docs/ Learn how to use LLMs like Claude to speed up your MCP development diff --git a/quickstart/user.mdx b/quickstart/user.mdx index a6a53e5..810dc56 100644 --- a/quickstart/user.mdx +++ b/quickstart/user.mdx @@ -98,7 +98,7 @@ If you get an error saying "command not found" or "node is not recognized", down **How does the configuration file work?** -This configuration file tells Claude for Dekstop which MCP servers to start up every time you start the application. In this case, we have added one server called "filesystem" that will use the Node `npx` command to install and run `@modelcontextprotocol/server-filesystem`. This server, described [here](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem), will let you access your file system in Claude for Desktop. +This configuration file tells Claude for Desktop which MCP servers to start up every time you start the application. In this case, we have added one server called "filesystem" that will use the Node `npx` command to install and run `@modelcontextprotocol/server-filesystem`. This server, described [here](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem), will let you access your file system in Claude for Desktop. @@ -241,4 +241,4 @@ npm install -g npm > Now build your own custom server to use in Claude for Desktop and other clients - \ No newline at end of file + diff --git a/sdk/java/mcp-client.mdx b/sdk/java/mcp-client.mdx new file mode 100644 index 0000000..14ec5f6 --- /dev/null +++ b/sdk/java/mcp-client.mdx @@ -0,0 +1,322 @@ +--- +title: MCP Client +description: Learn how to use the Model Context Protocol (MCP) client to interact with MCP servers +--- + +# Model Context Protocol Client + +The MCP Client is a key component in the Model Context Protocol (MCP) architecture, responsible for establishing and managing connections with MCP servers. It implements the client-side of the protocol, handling: + +- Protocol version negotiation to ensure compatibility with servers +- Capability negotiation to determine available features +- Message transport and JSON-RPC communication +- Tool discovery and execution +- Resource access and management +- Prompt system interactions +- Optional features like roots management and sampling support + +The client provides both synchronous and asynchronous APIs for flexibility in different application contexts. + + + +```java +// Create a sync client with custom configuration +McpSyncClient client = McpClient.sync(transport) + .requestTimeout(Duration.ofSeconds(10)) + .capabilities(ClientCapabilities.builder() + .roots(true) // Enable roots capability + .sampling() // Enable sampling capability + .build()) + .sampling(request -> new CreateMessageResult(response)) + .build(); + +// Initialize connection +client.initialize(); + +// List available tools +ListToolsResult tools = client.listTools(); + +// Call a tool +CallToolResult result = client.callTool( + new CallToolRequest("calculator", + Map.of("operation", "add", "a", 2, "b", 3)) +); + +// List and read resources +ListResourcesResult resources = client.listResources(); +ReadResourceResult resource = client.readResource( + new ReadResourceRequest("resource://uri") +); + +// List and use prompts +ListPromptsResult prompts = client.listPrompts(); +GetPromptResult prompt = client.getPrompt( + new GetPromptRequest("greeting", Map.of("name", "Spring")) +); + +// Add/remove roots +client.addRoot(new Root("file:///path", "description")); +client.removeRoot("file:///path"); + +// Close client +client.closeGracefully(); +``` + + + +```java +// Create an async client with custom configuration +McpAsyncClient client = McpClient.async(transport) + .requestTimeout(Duration.ofSeconds(10)) + .capabilities(ClientCapabilities.builder() + .roots(true) // Enable roots capability + .sampling() // Enable sampling capability + .build()) + .sampling(request -> Mono.just(new CreateMessageResult(response))) + .toolsChangeConsumer(tools -> Mono.fromRunnable(() -> { + logger.info("Tools updated: {}", tools); + })) + .resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> { + logger.info("Resources updated: {}", resources); + })) + .promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> { + logger.info("Prompts updated: {}", prompts); + })) + .build(); + +// Initialize connection and use features +client.initialize() + .flatMap(initResult -> client.listTools()) + .flatMap(tools -> { + return client.callTool(new CallToolRequest( + "calculator", + Map.of("operation", "add", "a", 2, "b", 3) + )); + }) + .flatMap(result -> { + return client.listResources() + .flatMap(resources -> + client.readResource(new ReadResourceRequest("resource://uri")) + ); + }) + .flatMap(resource -> { + return client.listPrompts() + .flatMap(prompts -> + client.getPrompt(new GetPromptRequest( + "greeting", + Map.of("name", "Spring") + )) + ); + }) + .flatMap(prompt -> { + return client.addRoot(new Root("file:///path", "description")) + .then(client.removeRoot("file:///path")); + }) + .doFinally(signalType -> { + client.closeGracefully().subscribe(); + }) + .subscribe(); +``` + + + +## Client Transport + +The transport layer handles the communication between MCP clients and servers, providing different implementations for various use cases. The client transport manages message serialization, connection establishment, and protocol-specific communication patterns. + + + + Creates transport for in-process based communication + ```java + ServerParameters params = ServerParameters.builder("npx") + .args("-y", "@modelcontextprotocol/server-everything", "dir") + .build(); + McpTransport transport = new StdioClientTransport(params); + ``` + + + Creates a framework agnostic (pure Java API) SSE client transport. Included in the core mcp module. + ```java + McpTransport transport = new HttpClientSseClientTransport("http://your-mcp-server"); + ``` + + + Creates WebFlux-based SSE client transport. Requires the mcp-webflux-sse-transport dependency. + ```java + WebClient.Builder webClientBuilder = WebClient.builder() + .baseUrl("http://your-mcp-server"); + McpTransport transport = new WebFluxSseClientTransport(webClientBuilder); + ``` + + + +## Client Capabilities + +The client can be configured with various capabilities: + +```java +var capabilities = ClientCapabilities.builder() + .roots(true) // Enable filesystem roots support with list changes notifications + .sampling() // Enable LLM sampling support + .build(); +``` + +### Roots Support + +Roots define the boundaries of where servers can operate within the filesystem: + +```java +// Add a root dynamically +client.addRoot(new Root("file:///path", "description")); + +// Remove a root +client.removeRoot("file:///path"); + +// Notify server of roots changes +client.rootsListChangedNotification(); +``` + +The roots capability allows servers to: + +- Request the list of accessible filesystem roots +- Receive notifications when the roots list changes +- Understand which directories and files they have access to + + +### Sampling Support + +Sampling enables servers to request LLM interactions ("completions" or "generations") through the client: + +```java +// Configure sampling handler +Function samplingHandler = request -> { + // Sampling implementation that interfaces with LLM + return new CreateMessageResult(response); +}; + +// Create client with sampling support +var client = McpClient.sync(transport) + .capabilities(ClientCapabilities.builder() + .sampling() + .build()) + .sampling(samplingHandler) + .build(); +``` + +This capability allows: +- Servers to leverage AI capabilities without requiring API keys +- Clients to maintain control over model access and permissions +- Support for both text and image-based interactions +- Optional inclusion of MCP server context in prompts + + +## Using MCP Clients + +### Tool Execution + +Tools are server-side functions that clients can discover and execute. The MCP client provides methods to list available tools and execute them with specific parameters. Each tool has a unique name and accepts a map of parameters. + + + +```java +// List available tools and their names +var tools = client.listTools(); +tools.forEach(tool -> System.out.println(tool.getName())); + +// Execute a tool with parameters +var result = client.callTool("calculator", Map.of( + "operation", "add", + "a", 1, + "b", 2 +)); +``` + + + +```java +// List available tools asynchronously +client.listTools() + .doOnNext(tools -> tools.forEach(tool -> + System.out.println(tool.getName()))) + .subscribe(); + +// Execute a tool asynchronously +client.callTool("calculator", Map.of( + "operation", "add", + "a", 1, + "b", 2 + )) + .subscribe(); +``` + + + +### Resource Access + +Resources represent server-side data sources that clients can access using URI templates. The MCP client provides methods to discover available resources and retrieve their contents through a standardized interface. + + + +```java +// List available resources and their names +var resources = client.listResources(); +resources.forEach(resource -> System.out.println(resource.getName())); + +// Retrieve resource content using a URI template +var content = client.getResource("file", Map.of( + "path", "/path/to/file.txt" +)); +``` + + + +```java +// List available resources asynchronously +client.listResources() + .doOnNext(resources -> resources.forEach(resource -> + System.out.println(resource.getName()))) + .subscribe(); + +// Retrieve resource content asynchronously +client.getResource("file", Map.of( + "path", "/path/to/file.txt" + )) + .subscribe(); +``` + + + +### Prompt System + +The prompt system enables interaction with server-side prompt templates. These templates can be discovered and executed with custom parameters, allowing for dynamic text generation based on predefined patterns. + + + +```java +// List available prompt templates +var prompts = client.listPrompts(); +prompts.forEach(prompt -> System.out.println(prompt.getName())); + +// Execute a prompt template with parameters +var response = client.executePrompt("echo", Map.of( + "text", "Hello, World!" +)); +``` + + + +```java +// List available prompt templates asynchronously +client.listPrompts() + .doOnNext(prompts -> prompts.forEach(prompt -> + System.out.println(prompt.getName()))) + .subscribe(); + +// Execute a prompt template asynchronously +client.executePrompt("echo", Map.of( + "text", "Hello, World!" + )) + .subscribe(); +``` + + diff --git a/sdk/java/mcp-overview.mdx b/sdk/java/mcp-overview.mdx new file mode 100644 index 0000000..ed1eb47 --- /dev/null +++ b/sdk/java/mcp-overview.mdx @@ -0,0 +1,168 @@ +--- +title: Overview +description: Introduction to the Model Context Protocol (MCP) Java SDK +--- + +Java SDK for the [Model Context Protocol](https://modelcontextprotocol.org/docs/concepts/architecture) +enables standardized integration between AI models and tools. + +## Features + +- MCP Client and MCP Server implementations supporting: + - Protocol [version compatibility negotiation](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/lifecycle/#initialization) + - [Tool](https://spec.modelcontextprotocol.io/specification/2024-11-05/server/tools/) discovery, execution, list change notifications + - [Resource](https://spec.modelcontextprotocol.io/specification/2024-11-05/server/resources/) management with URI templates + - [Roots](https://spec.modelcontextprotocol.io/specification/2024-11-05/client/roots/) list management and notifications + - [Prompt](https://spec.modelcontextprotocol.io/specification/2024-11-05/server/prompts/) handling and management + - [Sampling](https://spec.modelcontextprotocol.io/specification/2024-11-05/client/sampling/) support for AI model interactions +- Multiple transport implementations: + - Default transports: + - Stdio-based transport for process-based communication + - Java HttpClient-based SSE client transport for HTTP SSE Client-side streaming + - Servlet-based SSE server transport for HTTP SSE Server streaming + - Spring-based transports: + - WebFlux SSE client and server transports for reactive HTTP streaming + - WebMVC SSE transport for servlet-based HTTP streaming +- Supports Synchronous and Asynchronous programming paradigms + +## Architecture + +The SDK follows a layered architecture with clear separation of concerns: + +![MCP Stack Architecture](/images/java/mcp-stack.svg) + +- **Client/Server Layer (McpClient/McpServer)**: Both use McpSession for sync/async operations, +with McpClient handling client-side protocol operations and McpServer managing server-side protocol operations. +- **Session Layer (McpSession)**: Manages communication patterns and state using DefaultMcpSession implementation. +- **Transport Layer (McpTransport)**: Handles JSON-RPC message serialization/deserialization via: + - StdioTransport (stdin/stdout) in the core module + - HTTP SSE transports in dedicated transport modules (Java HttpClient, Spring WebFlux, Spring WebMVC) + + +The MCP Client is a key component in the Model Context Protocol (MCP) architecture, responsible for establishing and managing connections with MCP servers. +It implements the client-side of the protocol. + +![Java MCP Client Architecture](/images/java/java-mcp-client-architecture.jpg) + +The MCP Server is a foundational component in the Model Context Protocol (MCP) architecture that provides tools, resources, and capabilities to clients. +It implements the server-side of the protocol. + +![Java MCP Server Architecture](/images/java/java-mcp-server-architecture.jpg) + +Key Interactions: + +- **Client/Server Initialization**: Transport setup, protocol compatibility check, capability negotiation, and implementation details exchange. +- **Message Flow**: JSON-RPC message handling with validation, type-safe response processing, and error handling. +- **Resource Management**: Resource discovery, URI template-based access, subscription system, and content retrieval. + +## Dependencies + +Add the following Maven dependency to your project: + + + +The core MCP functionality: + +```xml + + io.modelcontextprotocol.sdk + mcp + +``` + +For HTTP SSE transport implementations, add one of the following dependencies: + +```xml + + + io.modelcontextprotocol.sdk + mcp-spring-webflux + + + + + io.modelcontextprotocol.sdk + mcp-spring-webmvc + +``` + + + The core MCP functionality: + + ```groovy + dependencies { + implementation platform("io.modelcontextprotocol.sdk:mcp") + //... + } + ``` + + For HTTP SSE transport implementations, add one of the following dependencies: + + ```groovy + // Spring WebFlux-based SSE client and server transport + dependencies { + implementation platform("io.modelcontextprotocol.sdk:mcp-spring-webflux") + } + + // Spring WebMVC-based SSE server transport + dependencies { + implementation platform("io.modelcontextprotocol.sdk:mcp-spring-webmvc") + } + ``` + + + +### Bill of Materials (BOM) + +The Bill of Materials (BOM) declares the recommended versions of all the dependencies used by a given release. +Using the BOM from your application's build script avoids the need for you to specify and maintain the dependency versions yourself. +Instead, the version of the BOM you're using determines the utilized dependency versions. +It also ensures that you're using supported and tested versions of the dependencies by default, unless you choose to override them. + +Add the BOM to your project: + + + +```xml + + + + io.modelcontextprotocol.sdk + mcp-bom + 0.7.0 + pom + import + + + +``` + + + +```groovy +dependencies { + implementation platform("io.modelcontextprotocol.sdk:mcp-bom:0.7.0") + //... +} +``` + +Gradle users can also use the Spring AI MCP BOM by leveraging Gradle (5.0+) native support for declaring dependency constraints using a Maven BOM. +This is implemented by adding a 'platform' dependency handler method to the dependencies section of your Gradle build script. +As shown in the snippet above this can then be followed by version-less declarations of the Starter Dependencies for the one or more spring-ai modules you wish to use, e.g. spring-ai-openai. + + + +Replace the version number with the version of the BOM you want to use. + +### Available Dependencies + +The following dependencies are available and managed by the BOM: + +- Core Dependencies + - `io.modelcontextprotocol.sdk:mcp` - Core MCP library providing the base functionality and APIs for Model Context Protocol implementation. +- Transport Dependencies + - `io.modelcontextprotocol.sdk:mcp-spring-webflux` - WebFlux-based Server-Sent Events (SSE) transport implementation for reactive applications. + - `io.modelcontextprotocol.sdk:mcp-spring-webmvc` - WebMVC-based Server-Sent Events (SSE) transport implementation for servlet-based applications. +- Testing Dependencies + - `io.modelcontextprotocol.sdk:mcp-test` - Testing utilities and support for MCP-based applications. + diff --git a/sdk/java/mcp-server.mdx b/sdk/java/mcp-server.mdx new file mode 100644 index 0000000..d7047f9 --- /dev/null +++ b/sdk/java/mcp-server.mdx @@ -0,0 +1,386 @@ +--- +title: MCP Server +description: Learn how to implement and configure a Model Context Protocol (MCP) server +--- + +## Overview + +The MCP Server is a foundational component in the Model Context Protocol (MCP) architecture that provides tools, resources, and capabilities to clients. It implements the server-side of the protocol, responsible for: + +- Exposing tools that clients can discover and execute +- Managing resources with URI-based access patterns +- Providing prompt templates and handling prompt requests +- Supporting capability negotiation with clients +- Implementing server-side protocol operations +- Managing concurrent client connections +- Providing structured logging and notifications + +The server supports both synchronous and asynchronous APIs, allowing for flexible integration in different application contexts. + + + +```java +// Create a server with custom configuration +McpSyncServer syncServer = McpServer.sync(transport) + .serverInfo("my-server", "1.0.0") + .capabilities(ServerCapabilities.builder() + .resources(true) // Enable resource support + .tools(true) // Enable tool support + .prompts(true) // Enable prompt support + .logging() // Enable logging support + .build()) + .build(); + +// Register tools, resources, and prompts +syncServer.addTool(syncToolRegistration); +syncServer.addResource(syncResourceRegistration); +syncServer.addPrompt(syncPromptRegistration); + +// Send logging notifications +syncServer.loggingNotification(LoggingMessageNotification.builder() + .level(LoggingLevel.INFO) + .logger("custom-logger") + .data("Server initialized") + .build()); + +// Close the server when done +syncServer.close(); +``` + + + +```java +// Create an async server with custom configuration +McpAsyncServer asyncServer = McpServer.async(transport) + .serverInfo("my-server", "1.0.0") + .capabilities(ServerCapabilities.builder() + .resources(true) // Enable resource support + .tools(true) // Enable tool support + .prompts(true) // Enable prompt support + .logging() // Enable logging support + .build()) + .build(); + +// Register tools, resources, and prompts +asyncServer.addTool(asyncToolRegistration) + .doOnSuccess(v -> logger.info("Tool registered")) + .subscribe(); + +asyncServer.addResource(asyncResourceRegistration) + .doOnSuccess(v -> logger.info("Resource registered")) + .subscribe(); + +asyncServer.addPrompt(asyncPromptRegistration) + .doOnSuccess(v -> logger.info("Prompt registered")) + .subscribe(); + +// Send logging notifications +asyncServer.loggingNotification(LoggingMessageNotification.builder() + .level(LoggingLevel.INFO) + .logger("custom-logger") + .data("Server initialized") + .build()); + +// Close the server when done +asyncServer.close() + .doOnSuccess(v -> logger.info("Server closed")) + .subscribe(); +``` + + + + +## Server Transport + +The transport layer in the MCP SDK is responsible for handling the communication between clients and servers. It provides different implementations to support various communication protocols and patterns. The SDK includes several built-in transport implementations: + + + + + <> + Create in-process based transport: + + ```java + StdioServerTransport transport = new StdioServerTransport(new ObjectMapper()); + ``` + + Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support. + + Key features: +
    +
  • Bidirectional communication through stdin/stdout
  • +
  • Process-based integration support
  • +
  • Simple setup and configuration
  • +
  • Lightweight implementation
  • +
+ +
+ + + <> +

Creates WebFlux-based SSE server transport.
Requires the mcp-spring-webflux dependency.

+ + ```java + @Configuration + class McpConfig { + @Bean + WebFluxSseServerTransport webFluxSseServerTransport(ObjectMapper mapper) { + return new WebFluxSseServerTransport(mapper, "/mcp/message"); + } + + @Bean + RouterFunction mcpRouterFunction(WebFluxSseServerTransport transport) { + return transport.getRouterFunction(); + } + } + ``` + +

Implements the MCP HTTP with SSE transport specification, providing:

+
    +
  • Reactive HTTP streaming with WebFlux
  • +
  • Concurrent client connections through SSE endpoints
  • +
  • Message routing and session management
  • +
  • Graceful shutdown capabilities
  • +
+ +
+ + + + <> +

Creates WebMvc-based SSE server transport.
Requires the mcp-spring-webmvc dependency.

+ + ```java + @Configuration + @EnableWebMvc + class McpConfig { + @Bean + WebMvcSseServerTransport webMvcSseServerTransport(ObjectMapper mapper) { + return new WebMvcSseServerTransport(mapper, "/mcp/message"); + } + + @Bean + RouterFunction mcpRouterFunction(WebMvcSseServerTransport transport) { + return transport.getRouterFunction(); + } + } + ``` + +

Implements the MCP HTTP with SSE transport specification, providing:

+
    +
  • Server-side event streaming
  • +
  • Integration with Spring WebMVC
  • +
  • Support for traditional web applications
  • +
  • Synchronous operation handling
  • +
+ +
+ + + + <> +

+ Creates a Servlet-based SSE server transport. It is included in the core mcp module.
+ The HttpServletSseServerTransport can be used with any Servlet container.
+ To use it with a Spring Web application, you can register it as a Servlet bean: +

+ + ```java + @Configuration + @EnableWebMvc + public class McpServerConfig implements WebMvcConfigurer { + + @Bean + public HttpServletSseServerTransport servletSseServerTransport() { + return new HttpServletSseServerTransport(new ObjectMapper(), "/mcp/message"); + } + + @Bean + public ServletRegistrationBean customServletBean(HttpServletSseServerTransport servlet) { + return new ServletRegistrationBean(servlet); + } + } + ``` + +

+ Implements the MCP HTTP with SSE transport specification using the traditional Servlet API, providing: +

+
    +
  • Asynchronous message handling using Servlet 6.0 async support
  • +
  • Session management for multiple client connections
  • +
  • + Two types of endpoints: +
      +
    • SSE endpoint (/sse) for server-to-client events
    • +
    • Message endpoint (configurable) for client-to-server requests
    • +
    +
  • +
  • Error handling and response formatting
  • +
  • Graceful shutdown support
  • +
+ +
+ +
+ + +## Server Capabilities + +The server can be configured with various capabilities: + +```java +var capabilities = ServerCapabilities.builder() + .resources(false, true) // Resource support with list changes notifications + .tools(true) // Tool support with list changes notifications + .prompts(true) // Prompt support with list changes notifications + .logging() // Enable logging support (enabled by default with loging level INFO) + .build(); +``` + +### Logging Support + +The server provides structured logging capabilities that allow sending log messages to clients with different severity levels: + +```java +// Send a log message to clients +server.loggingNotification(LoggingMessageNotification.builder() + .level(LoggingLevel.INFO) + .logger("custom-logger") + .data("Custom log message") + .build()); +``` + +Clients can control the minimum logging level they receive through the `mcpClient.setLoggingLevel(level)` request. Messages below the set level will be filtered out. +Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7) + +### Tool Registration + + + +```java +// Sync tool registration +var schema = """ + { + "type" : "object", + "id" : "urn:jsonschema:Operation", + "properties" : { + "operation" : { + "type" : "string" + }, + "a" : { + "type" : "number" + }, + "b" : { + "type" : "number" + } + } + } + """; +var syncToolRegistration = new McpServerFeatures.SyncToolRegistration( + new Tool("calculator", "Basic calculator", schema), + arguments -> { + // Tool implementation + return new CallToolResult(result, false); + } +); +``` + + + +```java +// Async tool registration +var schema = """ + { + "type" : "object", + "id" : "urn:jsonschema:Operation", + "properties" : { + "operation" : { + "type" : "string" + }, + "a" : { + "type" : "number" + }, + "b" : { + "type" : "number" + } + } + } + """; +var asyncToolRegistration = new McpServerFeatures.AsyncToolRegistration( + new Tool("calculator", "Basic calculator", schema), + arguments -> { + // Tool implementation + return Mono.just(new CallToolResult(result, false)); + } +); +``` + + + +### Resource Registration + + + +```java +// Sync resource registration +var syncResourceRegistration = new McpServerFeatures.SyncResourceRegistration( + new Resource("custom://resource", "name", "description", "mime-type", null), + request -> { + // Resource read implementation + return new ReadResourceResult(contents); + } +); +``` + + + +```java +// Async resource registration +var asyncResourceRegistration = new McpServerFeatures.AsyncResourceRegistration( + new Resource("custom://resource", "name", "description", "mime-type", null), + request -> { + // Resource read implementation + return Mono.just(new ReadResourceResult(contents)); + } +); +``` + + + +### Prompt Registration + + + +```java +// Sync prompt registration +var syncPromptRegistration = new McpServerFeatures.SyncPromptRegistration( + new Prompt("greeting", "description", List.of( + new PromptArgument("name", "description", true) + )), + request -> { + // Prompt implementation + return new GetPromptResult(description, messages); + } +); +``` + + + +```java +// Async prompt registration +var asyncPromptRegistration = new McpServerFeatures.AsyncPromptRegistration( + new Prompt("greeting", "description", List.of( + new PromptArgument("name", "description", true) + )), + request -> { + // Prompt implementation + return Mono.just(new GetPromptResult(description, messages)); + } +); +``` + + + +## Error Handling + +The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.