Table of Contents

What MCP Capabilities Does LM-Kit.NET Support?


TL;DR

LM-Kit.NET implements the full MCP client specification (2025-06-18). This includes: tools (discovery and invocation), resources (reading and subscribing), prompts (listing and rendering), sampling (server-initiated LLM completions), elicitation (server-initiated user input), roots (filesystem scope), logging, argument completions, progress tracking, and cancellation. Both HTTP+SSE and stdio transports are supported.


Supported Capabilities

Tools

Discover and invoke tools exposed by any MCP server:

// List available tools
var tools = await client.GetToolsAsync();
foreach (var tool in tools)
    Console.WriteLine($"{tool.Name}: {tool.Description}");

// Register all MCP tools with an agent (they become standard ITool instances)
chat.Tools.Register(client);

// Or register with a filter
chat.Tools.Register(client, filter: tool => tool.Name.StartsWith("get_"));

MCP tools automatically refresh when the server sends a tools/listChanged notification.

Resources

Read data exposed by MCP servers (files, schemas, configurations):

// List resources
var resources = await client.GetResourcesAsync();

// Read a specific resource
var content = await client.ReadResourceAsync("file:///config/settings.json");
Console.WriteLine(content.Text);

// Subscribe to resource updates
await client.SubscribeToResourceAsync("file:///data/prices.csv");
client.ResourceUpdated += (sender, args) =>
{
    Console.WriteLine($"Resource updated: {args.Uri}");
};

// List resource templates (parameterized URIs)
var templates = await client.GetResourceTemplatesAsync();

Prompts

Access pre-built prompt templates from MCP servers:

// List available prompts
var prompts = await client.GetPromptsAsync();
foreach (var prompt in prompts)
    Console.WriteLine($"{prompt.Name}: {prompt.Description}");

// Render a prompt with arguments
var result = await client.GetPromptAsync("summarize-pr", new Dictionary<string, string>
{
    ["repo"] = "my-org/my-repo",
    ["pr_number"] = "42"
});

// Use the rendered prompt messages
foreach (var message in result.Messages)
    Console.WriteLine($"[{message.Role}] {message.Content}");

Sampling (Server-Initiated LLM Completions)

MCP servers can request LLM completions from the client, enabling server-side workflows that leverage the client's model:

client.SetSamplingHandler(async request =>
{
    // The server is asking your model to generate a completion
    var response = chat.Submit(request.Messages.Last().Content);

    return new McpSamplingResponse
    {
        Role = McpMessageRole.Assistant,
        Content = new McpSamplingContent { Type = "text", Text = response },
        Model = "qwen3.5:9b"
    };
});

Elicitation (Server-Initiated User Input)

MCP servers can request structured input from the user through the client:

client.SetElicitationHandler(async request =>
{
    Console.WriteLine($"Server asks: {request.Message}");
    Console.Write("Your response: ");
    string userInput = Console.ReadLine();

    return new McpElicitationResponse { Content = userInput };
});

Roots (Filesystem Scope)

Define which filesystem paths the server can access:

// Add filesystem roots
client.AddRoot(McpRoot.FromPath("/home/user/project"));
client.AddRoot(McpRoot.FromPath("/data/shared"));

// Remove a root
client.RemoveRoot("file:///data/shared");

// Server is notified of root changes automatically

Logging

Receive log messages from the server:

// Set minimum log level
await client.SetLogLevelAsync(McpLogLevel.Warning);

// Handle log messages
client.LogMessageReceived += (sender, args) =>
{
    Console.WriteLine($"[{args.Level}] {args.Message}");
};

Completions

Get argument autocompletion suggestions for prompts and resources:

var suggestions = await client.GetPromptCompletionsAsync("summarize-pr", "repo", "my-org/");
foreach (var suggestion in suggestions.Values)
    Console.WriteLine(suggestion);

Progress Tracking

Monitor long-running server operations:

client.ProgressReceived += (sender, args) =>
{
    Console.WriteLine($"Progress: {args.Progress}%");
};

Capability Negotiation

After connecting, you can check which capabilities the server supports:

await client.ConnectAsync();

if (client.HasCapability(McpServerCapabilities.Tools))
    Console.WriteLine("Server supports tools");

if (client.HasCapability(McpServerCapabilities.Resources))
    Console.WriteLine("Server supports resources");

if (client.HasCapability(McpServerCapabilities.Prompts))
    Console.WriteLine("Server supports prompts");

Events

Event When It Fires
CatalogChanged Tools, resources, or prompts list changed on server
ResourceUpdated A subscribed resource was modified
LogMessageReceived Server sent a log message
ProgressReceived Progress update on a long-running operation
SamplingRequested Server requests an LLM completion
ElicitationRequested Server requests user input
AuthFailed HTTP 401/403 authentication failure

Share