{"id":4678,"date":"2025-04-17T07:33:16","date_gmt":"2025-04-17T14:33:16","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/semantic-kernel\/?p=4678"},"modified":"2025-04-17T07:33:16","modified_gmt":"2025-04-17T14:33:16","slug":"semantic-kernel-adds-model-context-protocol-mcp-support-for-python","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/semantic-kernel-adds-model-context-protocol-mcp-support-for-python\/","title":{"rendered":"Semantic Kernel adds Model Context Protocol (MCP) support for Python"},"content":{"rendered":"<p>We are excited to announce that <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\">Semantic Kernel (SK)<\/a> now has first-class support for the <a href=\"https:\/\/modelcontextprotocol.io\/introduction\">Model Context Protocol (MCP)<\/a> \u2014 a standard created by Anthropic to enable models, tools, and agents to share context and capabilities seamlessly.<\/p>\n<p>With this release, SK can act as both an MCP <strong>host<\/strong> (client) and an MCP <strong>server<\/strong>, and you can leverage these capabilities directly in your agents. This unlocks powerful new scenarios for tool interoperability, prompt sharing, and agent orchestration across local and remote boundaries. This requires Semantic Kernel Python version 1.28.1 or higher.<\/p>\n<h3>What is MCP?<\/h3>\n<p>MCP is a protocol that standardizes how models, tools, and agents communicate and share context. It supports multiple transport types (stdio, sse, websocket) and allows for dynamic discovery and invocation of tools and prompts. Learn more in the <a href=\"https:\/\/modelcontextprotocol.io\/introduction\">official documentation<\/a>.<\/p>\n<h2>SK as an MCP host: consuming MCP servers<\/h2>\n<p>SK can now connect to any MCP server, whether it&#8217;s running locally (via stdio), remotely (via sse), or even in a container. This means you can:<\/p>\n<ul>\n<li><strong>Call tools and prompts exposed by any MCP server<\/strong> as if they were native SK plugins.<\/li>\n<li><strong>Perform sampling<\/strong> (e.g., text generation) by using all of Semantic Kernel&#8217;s service connectors.<\/li>\n<li><strong>Chain together multiple MCP servers<\/strong> in a single agent.<\/li>\n<\/ul>\n<h3>Example: connecting to a local MCP server via stdio<\/h3>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel.connectors.mcp import MCPStdioPlugin\r\n\r\nasync with MCPStdioPlugin(\r\n    name=\"ReleaseNotes\",\r\n    description=\"SK Release Notes Plugin\",\r\n    command=\"uv\",\r\n    args=[\r\n        \"--directory=python\/samples\/demos\/mcp_server\",\r\n        \"run\",\r\n        \"mcp_server_with_sampling.py\",\r\n    ],\r\n) as plugin:\r\n    # Use plugin as a tool in your agent or kernel\r\n    ...\r\n<\/code><\/pre>\n<h3>Example: connecting to a remote MCP server via sse<\/h3>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel.connectors.mcp import MCPSsePlugin\r\n\r\nasync with MCPSsePlugin(\r\n    name=\"RemoteTools\",\r\n    url=\"&lt;http:\/\/localhost:8000\/sse&gt;\",\r\n) as plugin:\r\n    ...\r\n<\/code><\/pre>\n<h3>Sampling: handling sampling requests<\/h3>\n<p>By default, whenever a MCP Plugin is added to a Kernel, either directly, or through an agent, it will be able to use all of the Chat Completion services registered in that kernel to perform sampling with, this is done automatically and requires no setup outside of making sure the kernel you are using has services registered, see the section on sampling below on how you would call that from a server.<\/p>\n<h2>SK as an MCP server: exposing your functions and prompts<\/h2>\n<p>You can now expose your SK functions and prompts as an MCP server, making them available to any MCP-compatible client or agent. This is perfect for sharing custom tools, chaining agents, or integrating with other ecosystems.<\/p>\n<h3>Example: exposing SK as an MCP server<\/h3>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel import Kernel\r\nfrom semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion\r\n\r\nkernel = Kernel()\r\nkernel.add_service(OpenAIChatCompletion(service_id=\"default\"))\r\n\r\n# Add functions and prompts as usual\r\n\r\nserver = kernel.as_mcp_server(server_name=\"sk\")\r\n\r\n# Run as stdio server\r\n\r\nimport anyio\r\nfrom mcp.server.stdio import stdio_server\r\n\r\nasync def handle_stdin():\r\n    async with stdio_server() as (read_stream, write_stream):\r\n        await server.run(read_stream, write_stream, server.create_initialization_options())\r\n\r\nanyio.run(handle_stdin)\r\n<\/code><\/pre>\n<p>You can also run as an sse server for remote access:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">uv --directory=python\/samples\/demos\/mcp_server \\\r\n   run sk_mcp_server.py --transport sse --port 8000\r\n<\/code><\/pre>\n<h3>Example: Claude Desktop configuration to connect to your SK MCP server<\/h3>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n    \"mcpServers\": {\r\n        \"sk\": {\r\n            \"command\": \"uv\",\r\n            \"args\": [\r\n                \"--directory=\/path\/to\/your\/semantic-kernel\/python\/samples\/demos\/mcp_server\",\r\n                \"run\",\r\n                \"sk_mcp_server.py\"\r\n            ],\r\n            \"env\": {\r\n                \"OPENAI_API_KEY\": \"\",\r\n                \"OPENAI_CHAT_MODEL_ID\": \"gpt-4o-mini\"\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<h3>Sampling support: create function that request a generation from their host<\/h3>\n<p>With MCP, you can expose functions that delegate sampling (e.g., text generation) to the host. This is not particularly useful because Semantic Kernel can obviously connect to a number of models, but it could be that you want to run SK as a server in a environment that is not allowed to directly call out to those models, while the host can do that.<\/p>\n<p>To use this, you can create a <code>KernelFunction<\/code> that receives a <code>server<\/code> object (excluded from function choice) and uses it to request sampling from the MCP host:<\/p>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel.functions import kernel_function\r\nfrom typing import Annotated\r\nfrom mcp.server.lowlevel import Server\r\n\r\n@kernel_function(\r\n    name=\"run_prompt\",\r\n    description=\"Run the prompts for a full set of release notes based on the PR messages given.\",\r\n)\r\nasync def sampling_function(\r\n    messages: Annotated[str, \"The list of PR messages, as a string with newlines\"],\r\n    temperature: float = 0.0,\r\n    max_tokens: int = 1000,\r\n    server: Annotated[Server | None, \"The server session\", {\"include_in_function_choices\": False}] = None,\r\n) -&gt; str:\r\n    if not server:\r\n        raise ValueError(\"Request context is required for sampling function.\")\r\n    sampling_response = await server.request_context.session.create_message(\r\n        messages=[\r\n            types.SamplingMessage(role=\"user\", content=types.TextContent(type=\"text\", text=messages)),\r\n        ],\r\n        max_tokens=max_tokens,\r\n        temperature=temperature,\r\n        model_preferences=types.ModelPreferences(\r\n            hints=[types.ModelHint(name=\"gpt-4o-mini\")],\r\n        ),\r\n    )\r\n    return sampling_response.content.text\r\n<\/code><\/pre>\n<p>This function can be exposed as a tool on your MCP server, and when called, it will use the host&#8217;s sampling endpoint to generate the output. The <code>server<\/code> argument is automatically injected by the MCP infrastructure and is not shown to users or in function choice UIs.<\/p>\n<p>See the <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/blob\/main\/python\/samples\/demos\/mcp_server\/mcp_server_with_sampling.py\">mcp_server_with_sampling.py<\/a> sample for a full walkthrough.<\/p>\n<h3>Using MCP with agents: tool calls and more<\/h3>\n<p>You can use MCP plugins directly in your SK agents, allowing your agent to:<\/p>\n<ul>\n<li>Call tools and prompts from any MCP server<\/li>\n<li>Chain together multiple MCP servers (e.g., GitHub + Release Notes)<\/li>\n<li>Use sampling and tool calls as part of the agent&#8217;s reasoning<\/li>\n<\/ul>\n<h3>Example: agent with multiple MCP plugins<\/h3>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel.agents import ChatCompletionAgent\r\nfrom semantic_kernel.connectors.mcp import MCPStdioPlugin\r\n\r\nasync with (\r\n    MCPStdioPlugin(\r\n        name=\"Github\",\r\n        command=\"docker\",\r\n        args=[\"run\", \"-i\", \"--rm\", \"-e\", \"GITHUB_PERSONAL_ACCESS_TOKEN\", \"ghcr.io\/github\/github-mcp-server\"],\r\n        env={\"GITHUB_PERSONAL_ACCESS_TOKEN\": os.getenv(\"GITHUB_PERSONAL_ACCESS_TOKEN\")},\r\n    ) as github_plugin,\r\n    MCPStdioPlugin(\r\n        name=\"ReleaseNotes\",\r\n        command=\"uv\",\r\n        args=[\"--directory=python\/samples\/demos\/mcp_server\", \"run\", \"mcp_server_with_prompts.py\"],\r\n    ) as release_notes_plugin,\r\n):\r\n    agent = ChatCompletionAgent(\r\n        service=OllamaChatCompletion(),\r\n        name=\"GithubAgent\",\r\n        plugins=[github_plugin, release_notes_plugin],\r\n    )\r\n    ...\r\n<\/code><\/pre>\n<p>See the <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/blob\/main\/python\/samples\/concepts\/mcp\/local_agent_with_local_server.py\">local_agent_with_local_server.py<\/a> sample for a full example.<\/p>\n<h2>Exposing agents as MCP servers<\/h2>\n<p>You can also expose an entire SK agent as an MCP server, making its reasoning and tool orchestration available to other clients and agents. This enables powerful agent-to-agent collaboration and chaining.<\/p>\n<h3>Example: exposing an agent as an MCP server<\/h3>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from semantic_kernel.agents import ChatCompletionAgent\r\nfrom semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion\r\n\r\nagent = ChatCompletionAgent(\r\n    service=OpenAIChatCompletion(),\r\n    name=\"ReleaseNotesAgent\",\r\n    instructions=\"You are a release notes generator agent. Use the run_prompt function to generate release notes.\",\r\n    plugins=[release_notes_plugin],\r\n)\r\n\r\nserver = agent.as_mcp_server(server_name=\"release_notes_agent\")\r\n\r\n# Now you can run this server using stdio or sse as shown above\r\n\r\n<\/code><\/pre>\n<p>You can use this to even go a step further and create multiple agents as servers, consume those servers as plugins in another agent to create a simple multi-agent setup, see the <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/blob\/main\/python\/samples\/concepts\/mcp\/agent_with_mcp_agent.py\">agent_with_mcp_agent.py<\/a> sample for how this works.<\/p>\n<h3>Try it out and share your feedback!<\/h3>\n<p>We invite you to try out the new MCP features in Semantic Kernel:<\/p>\n<ul>\n<li>Connect to local or remote MCP servers<\/li>\n<li>Expose your own tools and prompts as MCP servers<\/li>\n<li>Use MCP plugins in your agents<\/li>\n<li>Chain agents and tools across process and network boundaries<\/li>\n<\/ul>\n<p>Check out the <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/tree\/main\/python\/samples\/concepts\/mcp\/\">samples<\/a> and <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/tree\/main\/python\/samples\/demos\/mcp_server\/\">demos<\/a> folders for more scenarios and code.<\/p>\n<p><strong>Let us know what you build and what you think!<\/strong> Open an issue or discussion on <a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\">GitHub<\/a> \u2014 we can&#8217;t wait to see what you create!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are excited to announce that Semantic Kernel (SK) now has first-class support for the Model Context Protocol (MCP) \u2014 a standard created by Anthropic to enable models, tools, and agents to share context and capabilities seamlessly. With this release, SK can act as both an MCP host (client) and an MCP server, and you [&hellip;]<\/p>\n","protected":false},"author":150044,"featured_media":2364,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[137,34,2,1],"tags":[48,133,63,9],"class_list":["post-4678","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mcp","category-python-2","category-samples","category-semantic-kernel","tag-ai","tag-mcp","tag-microsoft-semantic-kernel","tag-semantic-kernel"],"acf":[],"blog_post_summary":"<p>We are excited to announce that Semantic Kernel (SK) now has first-class support for the Model Context Protocol (MCP) \u2014 a standard created by Anthropic to enable models, tools, and agents to share context and capabilities seamlessly. With this release, SK can act as both an MCP host (client) and an MCP server, and you [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/4678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/150044"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=4678"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/4678\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/2364"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=4678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=4678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=4678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}