Semantic Kernel MCP in 2026: Python, C# and Auth Headers
Connect Semantic Kernel MCP tools to a remote server in Python and C#: a bearer key, function filters, cleanup, the real 401 and X output from one call.
Tarun Khatri
Published · Updated · 6 min read
Semantic Kernel MCP support works in both languages: Python has MCPStreamableHttpPlugin, and C# turns the official MCP SDK's tools into kernel functions.
This guide connects both to Weir's remote MCP server for public X (Twitter) data, with an API key. It covers headers, filters, cleanup, Semantic Kernel's status and a real call. We run Weir.
import asyncio, os
from semantic_kernel import Kernel
from semantic_kernel.connectors.mcp import MCPStreamableHttpPlugin
async def main() -> None:
async with MCPStreamableHttpPlugin(
name="weir", url="https://api.weirapp.io/mcp", load_prompts=False,
headers={"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
) as weir:
kernel = Kernel()
kernel.add_plugin(weir)
print(list(kernel.get_plugin("weir").functions))
asyncio.run(main())
How to connect a Semantic Kernel MCP client to a remote server
You need one install per language, a Weir key and a model key.
- Install for Pythonpip install semantic-kernel on Python 3.10 or later. MCP support comes with it.
- Install for C#dotnet add package Microsoft.SemanticKernel, then dotnet add package ModelContextProtocol.
- Get a Weir keyCreate one under API keys in your Weir dashboard. Keep it in WEIR_API_KEY.
- Set a model keyBoth examples call OpenAI with OPENAI_API_KEY.
As of 24 October 2026, PyPI lists semantic-kernel 1.45.0 and NuGet lists Microsoft.SemanticKernel 1.81.0, both from 6 October. The MCP C# SDK, ModelContextProtocol, is at 2.3.0.
The Python package pins the mcp SDK below 2.0, so its MCP code imports cleanly. AutoGen isn't so lucky, as our AutoGen MCP guide shows.
The two languages take different routes to the same tools:
| Python | C# | |
|---|---|---|
| Connect with | MCPStreamableHttpPlugin |
McpClient + HttpClientTransport |
| Key goes in | headers |
AdditionalHeaders |
| Drop tools | included_functions |
LINQ before AddFromFunctions |
| Close it | async with |
await using |
Either way, Weir sees the same calls.
Semantic Kernel's README now opens with "Semantic Kernel is now Microsoft Agent Framework". Microsoft's October 2025 post promised critical bug and security fixes for at least a year after Agent Framework's general release. Agent Framework 1.0 reached PyPI on 2 April 2026.
Semantic Kernel MCP in Python: a filtered agent
A default Weir key lists more than 40 tools. The plugin has no allow-list, so filter at call time with FunctionChoiceBehavior:
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
X_ONLY = FunctionChoiceBehavior.Auto(
filters={"included_functions": ["weir-search_x", "weir-get_x_post"]})
async def ask(weir, question: str) -> None:
agent = ChatCompletionAgent(
service=OpenAIChatCompletion(ai_model_id="gpt-5-mini"), name="x_analyst",
instructions="Search X with limit 5 or less. Link every post you cite.",
plugins=[weir], function_choice_behavior=X_ONLY)
print(await agent.get_response(messages=question))
Call await ask(weir, "What has @msdev posted about MCP lately?") inside the async with block from the top of this page. Here's what SK 1.45.0 does, per its source:
- Names get the plugin prefix. The model sees
weir-search_x, andincluded_functionsmust match it. - Only text reaches the model. SK passes on Weir's text blocks, the JSON and a charge line, and drops the structured copy.
- Errors arrive as plain text. SK ignores MCP's error flag, so a
402reads like any other result.
Why load_prompts=False? Weir has no MCP prompts, and SK's docs say listing prompts can hang on such servers.
Semantic Kernel MCP in C#: tools as kernel functions
C# has no MCP plugin class. You connect with the MCP C# SDK and turn each tool into a kernel function, as SK's own ModelContextProtocolPlugin sample does. Part one connects and filters:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using ModelContextProtocol.Client;
await using var weir = await McpClient.CreateAsync(new HttpClientTransport(new()
{
Endpoint = new Uri("https://api.weirapp.io/mcp"),
TransportMode = HttpTransportMode.StreamableHttp,
AdditionalHeaders = new Dictionary<string, string>
{
["Authorization"] = $"Bearer {Environment.GetEnvironmentVariable("WEIR_API_KEY")}",
},
}));
var xTools = (await weir.ListToolsAsync()).Where(t => t.Name is "search_x" or "get_x_post");
Part two builds the kernel and asks:
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-5-mini", Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);
var kernel = builder.Build();
kernel.Plugins.AddFromFunctions("weir", xTools.Select(t => t.AsKernelFunction()));
var settings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
Console.WriteLine(await kernel.InvokePromptAsync("What has @msdev posted about MCP?", new(settings)));
Three details from the SDK 2.3.0 source:
await usingcloses the session. SK's sample leaves it out.- Set
TransportMode. The default,AutoDetect, retries over SSE after a failed request, and Weir doesn't serve SSE. - The model gets the whole result. When a result has
structuredContent, as Weir's do, the tool returns the fullCallToolResultas JSON.
What does the agent get back?
To answer, the model calls search_x. We made that call through Weir's MCP server on 24 October 2026:
→ search_x {"fromUsers": ["pyautogen", "msdev"], "query": "MCP -filter:nativeretweets",
"onlyOriginal": true, "limit": 3}
← 3 posts · 4 credits · nextCursor set
2026-09-09 34 likes @msdev "Welcome to MCP Live!"
2026-08-20 62 likes @msdev "Join us September 9 for MCP Live!"
2026-08-17 99 likes @msdev "Claude in Microsoft Foundry now supports ... MCP connector"
Each post carries its url, text and counts, so the agent can link every claim.
Weir bills 1 credit per call plus 1 per X post, and failed calls are free. Packs start at $5 for 25,000 credits, as of October 2026. See our pricing page.
If it doesn't work
This is what Weir sent our request with no key, on 24 October 2026:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.weirapp.io/.well-known/
oauth-protected-resource/mcp", scope="read:social usage:read monitors:read"
{"error":"unauthorized","error_description":"Authorization is required."}
The challenge is for apps that sign in through a browser. Check your key with Weir's free GET /v1/whoami before you connect. Other errors:
async withnever returns. In SK 1.45.0's source, a failed handshake never releasesconnect(). We ran that code path with no key, and it was still waiting after 20 seconds.- The model calls no tools. Your filter says
search_x. Useweir-search_x. - A tool returns
402. Your Weir credits ran out, and retrying won't help.
When not to use Weir
- Your agent has to post or DM on X. Weir is read-only.
- You want private data. Weir reads public posts, not bookmarks, DMs or home timelines.
- Price per post matters most. TwitterAPI.io lists $0.15 per 1,000 tweets as of October 2026, less than our $5 pack.
- You need a guarantee. Weir isn't licensed by X or affiliated with it, so access can change.
FAQ
Does Semantic Kernel support MCP?
Yes, in Python and C#. Python has had MCP plugins since version 1.28.1, from April 2025, and 1.45.0 covers stdio, SSE, Streamable HTTP and WebSocket. In C#, you use the official MCP C# SDK and convert its tools with AsKernelFunction().
Is Semantic Kernel being replaced by Agent Framework?
Microsoft calls Agent Framework its successor, built by the same team. SK still gets releases, and its MCP code works today. For new projects, Agent Framework's MCPStreamableHTTPTool does the same job, as in our Agent Framework example.
Can Semantic Kernel be an MCP server?
Yes. In Python, kernel.as_mcp_server() turns a kernel's functions into an MCP server, and agents have as_mcp_server() too. In C#, SK's samples register kernel functions with the MCP SDK's McpServerTool.Create.
How do I pass headers to an MCP server in Semantic Kernel?
Pass headers={...} to MCPStreamableHttpPlugin in Python, or set AdditionalHeaders on the HttpClientTransport options in C#. Both send them on every request, and Weir reads the key only from Authorization.
Sources
All checked on 24 October 2026.
- Semantic Kernel README, Agent Framework notice: https://github.com/microsoft/semantic-kernel
- Semantic Kernel python-1.45.0 source, MCP connector: https://github.com/microsoft/semantic-kernel/blob/python-1.45.0/python/semantic_kernel/connectors/mcp.py
- Semantic Kernel dotnet-1.81.0 sample, ModelContextProtocolPlugin: https://github.com/microsoft/semantic-kernel/tree/dotnet-1.81.0/dotnet/samples/Demos/ModelContextProtocolPlugin
- Microsoft Learn, Give agents access to MCP Servers (updated 25 August 2026): https://learn.microsoft.com/en-us/semantic-kernel/concepts/plugins/adding-mcp-plugins
- Semantic Kernel blog, MCP support for Python (17 April 2025): https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-adds-model-context-protocol-mcp-support-for-python/
- Agent Framework blog, Semantic Kernel and Microsoft Agent Framework (7 October 2025): https://devblogs.microsoft.com/agent-framework/semantic-kernel-and-microsoft-agent-framework/
- semantic-kernel on PyPI, version 1.45.0: https://pypi.org/project/semantic-kernel/
- NuGet, Microsoft.SemanticKernel 1.81.0: https://www.nuget.org/packages/Microsoft.SemanticKernel
- NuGet, ModelContextProtocol 2.3.0: https://www.nuget.org/packages/ModelContextProtocol
- MCP C# SDK v2.3.0 source, client: https://github.com/modelcontextprotocol/csharp-sdk/tree/v2.3.0/src/ModelContextProtocol.Core/Client
- agent-framework on PyPI, release history: https://pypi.org/project/agent-framework/
- TwitterAPI.io pricing: https://twitterapi.io/pricing
- Weir docs, MCP: https://docs.weirapp.io/mcp
- Weir billing: https://docs.weirapp.io/billing
- Weir search_x call (request 594deb40-10ae-48af-82af-091ea97cb502) and no-key request (request 1cce84e3-15e7-42cb-8d2c-6de9fb3bd5f3)