Table of Contents

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:

  1. 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.
  2. 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