Table of Contents

🔌 Understanding Model Context Protocol (MCP) in LM-Kit.NET


📄 TL;DR

Model Context Protocol (MCP) is an open standard that enables AI agents to securely connect to external tools, data sources, and services through a unified interface. Instead of building custom integrations for each tool, MCP provides a standardized protocol for tool discovery, invocation, and resource access. In LM-Kit.NET, the LMKit.Mcp namespace provides McpClient for connecting agents to MCP servers, enabling seamless integration with databases, APIs, file systems, and third-party services without custom code for each integration.


📚 What is Model Context Protocol?

Definition: Model Context Protocol (MCP) is a specification that standardizes how AI applications communicate with external systems. It defines:

  • Tools: Functions that agents can invoke (search, calculate, query)
  • Resources: Data sources agents can access (files, databases, APIs)
  • Prompts: Pre-defined prompt templates for common tasks
  • Sampling: Allowing servers to request LLM completions from clients

The MCP Architecture

+---------------------------------------------------------------------------+
|                    Model Context Protocol Architecture                    |
+---------------------------------------------------------------------------+
|                                                                           |
|  +---------------------------------------------------------------------+ |
|  |                         MCP HOST (LM-Kit.NET)                        | |
|  |                                                                      | |
|  |  +---------------+    +---------------+    +---------------+       | |
|  |  |    Agent      |    |   McpClient   |    |   Tool        |       | |
|  |  |               |----->|               |----->|   Registry    |       | |
|  |  |  "Search for  |    |  • Connect    |    |               |       | |
|  |  |   files..."   |    |  • Discover   |    |  MCP tools    |       | |
|  |  |               |    |  • Invoke     |    |  registered   |       | |
|  |  +---------------+    +-------+-------+    +---------------+       | |
|  |                               |                                     | |
|  +-------------------------------┼-------------------------------------+ |
|                                  |                                       |
|                    +-------------+-------------+                        |
|                    |     MCP Protocol          |                        |
|                    |  (JSON-RPC over stdio/SSE)|                        |
|                    +-------------+-------------+                        |
|                                  |                                       |
|         +------------------------┼------------------------+             |
|         |                        |                        |             |
|         v                        v                        v             |
|  +-------------+          +-------------+          +-------------+     |
|  | MCP Server  |          | MCP Server  |          | MCP Server  |     |
|  |  (Files)    |          | (Database)  |          |   (APIs)    |     |
|  |             |          |             |          |             |     |
|  | • list_dir  |          | • query     |          | • get_user  |     |
|  | • read_file |          | • insert    |          | • send_msg  |     |
|  | • search    |          | • update    |          | • fetch     |     |
|  +-------------+          +-------------+          +-------------+     |
|                                                                           |
+---------------------------------------------------------------------------+

Why MCP Matters

Without MCP, each tool integration requires:

  • Custom API client code
  • Authentication handling
  • Error management
  • Schema definitions

With MCP:

  • Standardized interface for all tools
  • Automatic discovery of available capabilities
  • Consistent error handling across integrations
  • Security boundaries between host and servers

🏗️ MCP Components

Core Primitives

+--------------------------------------------------------------------------+
|                         MCP Core Primitives                              |
+--------------------------------------------------------------------------+
|                                                                          |
|  +-----------------+  +-----------------+  +-----------------+           |
|  |     TOOLS       |  |   RESOURCES     |  |    PROMPTS      |           |
|  |                 |  |                 |  |                 |           |
|  |  Functions the  |  |  Data sources   |  |  Pre-defined    |           |
|  |  agent can      |  |  the agent can  |  |  templates for  |           |
|  |  invoke         |  |  read from      |  |  common tasks   |           |
|  |                 |  |                 |  |                 |           |
|  |  • search_web   |  |  • file://      |  |  • summarize    |           |
|  |  • run_query    |  |  • db://        |  |  • analyze      |           |
|  |  • send_email   |  |  • api://       |  |  • translate    |           |
|  +-----------------+  +-----------------+  +-----------------+           |
|                                                                          |
|  +---------------------------------------------------------------------+ |
|  |                          SAMPLING                                   | |
|  |                                                                     | |
|  |  Allows MCP servers to request LLM completions from the host        | |
|  |  Enables agentic behaviors within server-side tools                 | |
|  |                                                                     | |
|  +---------------------------------------------------------------------+ |
|                                                                          |
+--------------------------------------------------------------------------+

Transport Mechanisms

Transport Description Use Case
stdio Standard input/output Local subprocess servers
SSE Server-Sent Events over HTTP Remote servers, web services

⚙️ Using MCP in LM-Kit.NET

Connecting to an MCP Server

using LMKit.Model;
using LMKit.Agents;
using LMKit.Mcp;

var model = LM.LoadFromModelID("gemma3:12b");

// Create MCP client for a local server
var mcpClient = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] { "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir" },
    Transport = McpTransport.Stdio
});

// Connect and discover tools
await mcpClient.ConnectAsync(CancellationToken.None);

// List available tools from the server
var tools = await mcpClient.ListToolsAsync(CancellationToken.None);
foreach (var tool in tools)
{
    Console.WriteLine($"Tool: {tool.Name} - {tool.Description}");
}

Registering MCP Tools with an Agent

using LMKit.Model;
using LMKit.Agents;
using LMKit.Mcp;

var model = LM.LoadFromModelID("glm4.7-flash");

// Connect to MCP server
var mcpClient = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] { "-y", "@modelcontextprotocol/server-filesystem", "./documents" },
    Transport = McpTransport.Stdio
});

await mcpClient.ConnectAsync(CancellationToken.None);

// Create agent with MCP tools
var agent = Agent.CreateBuilder(model)
    .WithSystemPrompt("You are a helpful assistant with access to the file system.")
    .WithTools(tools =>
    {
        // Register all tools from the MCP server
        tools.RegisterMcpClient(mcpClient);
    })
    .Build();

// Agent can now use MCP tools
var response = await agent.ExecuteAsync(
    "List all PDF files in the documents folder and summarize the first one.",
    CancellationToken.None
);

Console.WriteLine(response.Text);

Connecting to Multiple MCP Servers

using LMKit.Mcp;
using LMKit.Agents;

// File system server
var fileServer = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] { "-y", "@modelcontextprotocol/server-filesystem", "./data" },
    Transport = McpTransport.Stdio
});

// Database server
var dbServer = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] { "-y", "@modelcontextprotocol/server-postgres" },
    Transport = McpTransport.Stdio,
    Environment = new Dictionary<string, string>
    {
        ["POSTGRES_CONNECTION_STRING"] = "postgresql://localhost/mydb"
    }
});

// Web search server
var webServer = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] { "-y", "@modelcontextprotocol/server-brave-search" },
    Transport = McpTransport.Stdio,
    Environment = new Dictionary<string, string>
    {
        ["BRAVE_API_KEY"] = Environment.GetEnvironmentVariable("BRAVE_API_KEY")
    }
});

// Connect all servers
await Task.WhenAll(
    fileServer.ConnectAsync(CancellationToken.None),
    dbServer.ConnectAsync(CancellationToken.None),
    webServer.ConnectAsync(CancellationToken.None)
);

// Register all with agent
var agent = Agent.CreateBuilder(model)
    .WithSystemPrompt("You have access to files, database, and web search.")
    .WithTools(tools =>
    {
        tools.RegisterMcpClient(fileServer);
        tools.RegisterMcpClient(dbServer);
        tools.RegisterMcpClient(webServer);
    })
    .Build();

Accessing MCP Resources

using LMKit.Mcp;

// Read a resource from an MCP server
var resource = await mcpClient.ReadResourceAsync(
    "file:///documents/report.pdf",
    CancellationToken.None
);

Console.WriteLine($"Content type: {resource.MimeType}");
Console.WriteLine($"Content: {resource.Text}");

🎯 MCP Server Examples

Server Purpose Tools Provided
filesystem File access read_file, write_file, list_directory, search_files
postgres PostgreSQL query, list_tables, describe_table
sqlite SQLite read_query, write_query, list_tables
brave-search Web search brave_web_search, brave_local_search
github GitHub API search_repos, get_file_contents, create_issue
slack Slack list_channels, post_message, search_messages
google-drive Google Drive search_files, read_file, list_files

Creating a Custom MCP Server

MCP servers can be built in any language. A simple Node.js example:

// my-custom-server.js
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({
  name: "my-custom-tools",
  version: "1.0.0"
}, {
  capabilities: {
    tools: {}
  }
});

// Define a tool
server.setRequestHandler("tools/list", async () => ({
  tools: [{
    name: "get_weather",
    description: "Get current weather for a location",
    inputSchema: {
      type: "object",
      properties: {
        location: { type: "string", description: "City name" }
      },
      required: ["location"]
    }
  }]
}));

// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
  if (request.params.name === "get_weather") {
    const location = request.params.arguments.location;
    // Call weather API...
    return { content: [{ type: "text", text: `Weather in ${location}: Sunny, 72F` }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

📊 MCP vs Direct Tool Integration

Aspect Direct Tool Integration MCP Integration
Setup Custom code per tool Standardized connection
Discovery Manual registration Automatic via ListTools
Maintenance Update each integration Update server only
Security Custom per tool Protocol-level isolation
Reusability Application-specific Cross-application
Ecosystem Build everything Use existing servers

🔒 Security Considerations

MCP provides security through:

  • Process isolation: Servers run as separate processes
  • Capability declaration: Servers explicitly declare what they can do
  • Resource boundaries: Limited access to specified paths/databases
  • No implicit permissions: Host must explicitly connect and authorize
// Limit filesystem server to specific directory
var mcpClient = new McpClient(new McpClientOptions
{
    ServerCommand = "npx",
    ServerArguments = new[] {
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/safe/readonly/directory"  // Only this directory is accessible
    },
    Transport = McpTransport.Stdio
});

📖 Key Terms

  • MCP Host: The application running the AI agent (LM-Kit.NET)
  • MCP Server: A process providing tools and resources via MCP
  • MCP Client: Component in the host that connects to servers
  • Tool: A function the agent can invoke through MCP
  • Resource: A data source accessible through MCP (files, databases)
  • Prompt: A pre-defined template provided by an MCP server
  • Transport: Communication mechanism (stdio, SSE)



🌐 External Resources


📝 Summary

Model Context Protocol (MCP) standardizes how AI agents connect to external tools and data sources, eliminating the need for custom integrations. In LM-Kit.NET, the McpClient class enables agents to connect to any MCP-compliant server, automatically discovering and using its tools. MCP provides process isolation for security, standardized communication via JSON-RPC, and access to a growing ecosystem of pre-built servers for filesystems, databases, APIs, and more. By adopting MCP, developers can extend their agents' capabilities without writing integration code for each service, while maintaining security boundaries and benefiting from community-maintained server implementations.