🔌 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
Popular MCP Servers
| 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)
📚 Related API Documentation
McpClient: MCP client for connecting to serversMcpClientOptions: Connection configurationMcpTransport: Transport type selectionToolRegistry: Tool registration including MCP
🔗 Related Glossary Topics
- AI Agent Tools: External functions extending agent capabilities
- Function Calling: How agents invoke tools
- AI Agents: Autonomous systems using MCP tools
- AI Agent Execution: Runtime tool invocation
🌐 External Resources
- MCP Specification: Official protocol specification
- MCP Servers Repository: Official and community servers
- MCP TypeScript SDK: SDK for building servers
- LM-Kit MCP Demo: MCP integration example
📝 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.