Connect to MCP Servers from Your Application
The Model Context Protocol (MCP) is an open standard that lets AI applications access external tools and data sources through a unified interface. LM-Kit.NET's McpClient class connects to MCP servers, discovers their tools, and makes those tools available to agents. This tutorial builds an application that connects to MCP servers, lists available tools, and integrates them into agent workflows.
Why MCP Integration Matters
Two enterprise problems that MCP connectivity solves:
- Plug into any tool ecosystem. MCP servers exist for databases, file systems, APIs, code repositories, and more. One integration protocol gives your agent access to dozens of tools without writing custom adapters for each.
- Separate tool logic from agent logic. MCP servers run independently. Update, scale, or replace a tool server without changing your agent code. This separation makes systems easier to maintain and test.
Prerequisites
| Requirement | Minimum |
|---|---|
| .NET SDK | 8.0+ |
| VRAM | 4+ GB |
| Disk | ~3 GB free for model download |
| MCP server | A running MCP server endpoint (HTTP/SSE) |
Step 1: Create the Project
dotnet new console -n McpQuickstart
cd McpQuickstart
dotnet add package LM-Kit.NET
Step 2: Connect to an MCP Server
using System.Text;
using System.Text.Json;
using LMKit.Model;
using LMKit.Mcp.Client;
LMKit.Licensing.LicenseManager.SetLicenseKey("");
Console.InputEncoding = Encoding.UTF8;
Console.OutputEncoding = Encoding.UTF8;
// ──────────────────────────────────────
// 1. Connect to an MCP server
// ──────────────────────────────────────
string serverUrl = "http://localhost:3000/mcp";
using var mcpClient = new McpClient(serverUrl, timeout: TimeSpan.FromSeconds(30));
Console.WriteLine($"Connecting to MCP server at {serverUrl}...");
JsonDocument initResult = mcpClient.Initialize();
Console.WriteLine($"Connected. Protocol version: {mcpClient.McpProtocolVersion}");
Console.WriteLine($"Session ID: {mcpClient.SessionId}\n");
// ──────────────────────────────────────
// 2. Check server capabilities
// ──────────────────────────────────────
Console.WriteLine("Server capabilities:");
if (mcpClient.HasCapability(McpServerCapabilities.Tools))
Console.WriteLine(" Tools: supported");
if (mcpClient.HasCapability(McpServerCapabilities.Resources))
Console.WriteLine(" Resources: supported");
if (mcpClient.HasCapability(McpServerCapabilities.Prompts))
Console.WriteLine(" Prompts: supported");
if (mcpClient.HasCapability(McpServerCapabilities.Logging))
Console.WriteLine(" Logging: supported");
Console.WriteLine();
Step 3: Use MCP Tools with an Agent
Register MCP tools with an agent so it can call them during conversations:
using LMKit.Agents;
// ──────────────────────────────────────
// 1. Load model
// ──────────────────────────────────────
Console.WriteLine("Loading model...");
using LM model = LM.LoadFromModelID("qwen3:8b",
downloadingProgress: (_, len, read) =>
{
if (len.HasValue) Console.Write($"\r Downloading: {(double)read / len.Value * 100:F1}% ");
return true;
},
loadingProgress: p => { Console.Write($"\r Loading: {p * 100:F0}% "); return true; });
Console.WriteLine("\n");
// ──────────────────────────────────────
// 2. Connect to MCP server
// ──────────────────────────────────────
string serverUrl = "http://localhost:3000/mcp";
using var mcpClient = new McpClient(serverUrl);
mcpClient.Initialize();
// ──────────────────────────────────────
// 3. Create agent with MCP tools
// ──────────────────────────────────────
var agent = Agent.CreateBuilder(model)
.WithSystemPrompt("You are a helpful assistant with access to external tools. " +
"Use the available tools to answer questions accurately.")
.WithMcpClient(mcpClient)
.Build();
// ──────────────────────────────────────
// 4. Interactive loop
// ──────────────────────────────────────
Console.WriteLine("Chat with MCP-enabled agent (type 'quit' to exit):\n");
while (true)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("You: ");
Console.ResetColor();
string? input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input) || input.Equals("quit", StringComparison.OrdinalIgnoreCase))
break;
AgentExecutionResult result = await agent.ExecuteAsync(input);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("Agent: ");
Console.ResetColor();
Console.WriteLine(result.Content);
Console.WriteLine();
}
Step 4: Authentication
Connect to authenticated MCP servers using bearer tokens:
using var mcpClient = new McpClient("https://api.example.com/mcp");
// Set bearer token for authenticated endpoints
mcpClient.SetBearerToken("your-api-token-here");
// Handle auth failures
mcpClient.AuthFailed += (sender, e) =>
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Authentication failed: {e}");
Console.ResetColor();
};
mcpClient.Initialize();
Step 5: Request/Response Monitoring
Observe the raw MCP protocol traffic for debugging:
using var mcpClient = new McpClient("http://localhost:3000/mcp");
mcpClient.Sending += (sender, e) =>
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine($" >> MCP Request: {e}");
Console.ResetColor();
};
mcpClient.Received += (sender, e) =>
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine($" << MCP Response: {e}");
Console.ResetColor();
};
mcpClient.Initialize();
Step 6: Multiple MCP Servers
Connect to multiple servers and combine their tools in a single agent:
// Connect to multiple MCP servers
using var fileServer = new McpClient("http://localhost:3001/mcp");
fileServer.Initialize();
using var dbServer = new McpClient("http://localhost:3002/mcp");
dbServer.Initialize();
using var webServer = new McpClient("http://localhost:3003/mcp");
webServer.Initialize();
// Register all tools with a single agent
var agent = Agent.CreateBuilder(model)
.WithSystemPrompt("You have access to file system tools, database queries, and web search.")
.WithMcpClient(fileServer)
.WithMcpClient(dbServer)
.WithMcpClient(webServer)
.Build();
// The agent can now use tools from all three servers
var result = await agent.ExecuteAsync("Search the web for the latest news, then save a summary to a file.");
Console.WriteLine(result.Content);
Step 7: Graceful Shutdown
Always shut down MCP connections cleanly:
using var mcpClient = new McpClient("http://localhost:3000/mcp");
try
{
mcpClient.Initialize();
// ... use the client ...
}
finally
{
// Notify the server that we're disconnecting
mcpClient.Shutdown();
}
// Dispose handles cleanup of HTTP resources
Common Issues
| Problem | Cause | Fix |
|---|---|---|
| Connection refused | MCP server not running | Start the server; verify the URL and port |
| Timeout on Initialize | Server takes too long to respond | Increase timeout: new McpClient(url, TimeSpan.FromSeconds(60)) |
| Auth failed | Invalid or expired token | Check token with SetBearerToken; handle AuthFailed event |
| Tools not appearing | Server does not advertise tools capability | Check HasCapability(McpServerCapabilities.Tools) |
| Agent does not use tools | Model too small for tool calling | Use qwen3:8b or larger for reliable tool use |
Next Steps
- Create an AI Agent with Tools: build agents with custom tools.
- Build a Multi-Agent Workflow: orchestrate agents with MCP tools.
- Samples: MCP Integration: MCP integration demo.
- Samples: MCP Stdio Integration: MCP stdio demo.