ManagedCode.MCPGateway 0.1.1

Prefix Reserved
dotnet add package ManagedCode.MCPGateway --version 0.1.1
                    
NuGet\Install-Package ManagedCode.MCPGateway -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ManagedCode.MCPGateway" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ManagedCode.MCPGateway" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="ManagedCode.MCPGateway" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ManagedCode.MCPGateway --version 0.1.1
                    
#r "nuget: ManagedCode.MCPGateway, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ManagedCode.MCPGateway@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ManagedCode.MCPGateway&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=ManagedCode.MCPGateway&version=0.1.1
                    
Install as a Cake Tool

ManagedCode.MCPGateway

CI Release CodeQL NuGet License: MIT

ManagedCode.MCPGateway is a .NET 10 library that turns local AITool instances and remote MCP servers into one searchable execution surface.

The package is built on:

  • Microsoft.Extensions.AI
  • the official ModelContextProtocol .NET SDK
  • in-memory descriptor indexing with optional embedding-based ranking

Install

dotnet add package ManagedCode.MCPGateway

What You Get

  • one registry for local tools, stdio MCP servers, HTTP MCP servers, or prebuilt McpClient instances
  • descriptor indexing that enriches search with tool name, description, required arguments, and input schema
  • vector search when an IEmbeddingGenerator<string, Embedding<float>> is registered
  • optional persisted tool embeddings through IMcpGatewayToolEmbeddingStore
  • lexical fallback when embeddings are unavailable
  • one invoke surface for both local AIFunction tools and MCP tools
  • optional meta-tools you can hand back to another model as normal AITool instances

Quickstart

using ManagedCode.MCPGateway;
using ManagedCode.MCPGateway.Abstractions;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

services.AddManagedCodeMcpGateway(options =>
{
    options.AddTool(
        "local",
        AIFunctionFactory.Create(
            static (string query) => $"github:{query}",
            new AIFunctionFactoryOptions
            {
                Name = "github_search_repositories",
                Description = "Search GitHub repositories by user query."
            }));

    options.AddStdioServer(
        sourceId: "filesystem",
        command: "npx",
        arguments: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]);
});

await using var serviceProvider = services.BuildServiceProvider();
var gateway = serviceProvider.GetRequiredService<IMcpGateway>();

await gateway.BuildIndexAsync();

var search = await gateway.SearchAsync("find github repositories", maxResults: 3);
var selectedTool = search.Matches[0];

var invoke = await gateway.InvokeAsync(new McpGatewayInvokeRequest(
    ToolId: selectedTool.ToolId,
            Query: "managedcode"));

AddManagedCodeMcpGateway(...) does not create or configure an embedding generator for you. Vector ranking is enabled only when the same DI container also has an IEmbeddingGenerator<string, Embedding<float>>. The gateway first tries the keyed registration McpGatewayServiceKeys.EmbeddingGenerator and falls back to any regular registration. Otherwise it stays fully functional and uses lexical ranking.

Context-Aware Search And Invoke

When the current turn has extra UI, workflow, or chat context, pass it through the request models:

var search = await gateway.SearchAsync(new McpGatewaySearchRequest(
    Query: "search",
    ContextSummary: "User is on the GitHub repository settings page",
    Context: new Dictionary<string, object?>
    {
        ["page"] = "settings",
        ["domain"] = "github"
    },
    MaxResults: 3));

var invoke = await gateway.InvokeAsync(new McpGatewayInvokeRequest(
    ToolId: search.Matches[0].ToolId,
    Query: "managedcode",
    ContextSummary: "User wants repository administration actions",
    Context: new Dictionary<string, object?>
    {
        ["page"] = "settings",
        ["domain"] = "github"
    }));

The gateway uses this request context in two ways:

  • search combines the query, context summary, and context values into one effective search input for embeddings or lexical fallback
  • MCP invocation sends the request context in MCP meta
  • local AIFunction tools can receive auto-mapped query, contextSummary, and context arguments when those parameters are required

Meta-Tools

You can expose the gateway itself as two reusable AITool instances:

var tools = gateway.CreateMetaTools();

By default this creates:

  • gateway_tools_search
  • gateway_tool_invoke

These tools are useful when another model should first search the gateway catalog and then invoke the selected tool.

Search Behavior

ManagedCode.MCPGateway builds one descriptor document per tool from:

  • tool name
  • display name
  • description
  • required arguments
  • input schema summaries

If an embedding generator is registered, the gateway vectorizes those descriptor documents and uses cosine similarity plus a small lexical boost. It first tries the keyed registration McpGatewayServiceKeys.EmbeddingGenerator and then falls back to any regular IEmbeddingGenerator<string, Embedding<float>>. If no embedding generator is present, it falls back to lexical ranking without disabling execution.

The embedding generator is resolved per gateway operation, so singleton, scoped, and transient DI registrations all work with index builds and search.

Optional Embeddings

Register any provider-specific implementation of IEmbeddingGenerator<string, Embedding<float>> in the same DI container before building the service provider.

Preferred registration for the gateway:

var services = new ServiceCollection();

services.AddKeyedSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>(
    McpGatewayServiceKeys.EmbeddingGenerator);

services.AddManagedCodeMcpGateway(options =>
{
    options.AddTool(
        "local",
        AIFunctionFactory.Create(
            static (string query) => $"github:{query}",
            new AIFunctionFactoryOptions
            {
                Name = "github_search_repositories",
                Description = "Search GitHub repositories by user query."
            }));
});

Fallback when your app already exposes a regular embedding generator:

var services = new ServiceCollection();

services.AddSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>();

services.AddManagedCodeMcpGateway(options =>
{
    options.AddTool(
        "local",
        AIFunctionFactory.Create(
            static (string query) => $"github:{query}",
            new AIFunctionFactoryOptions
            {
                Name = "github_search_repositories",
                Description = "Search GitHub repositories by user query."
            }));
});

The keyed registration is the preferred one, so you can dedicate a specific embedder to the gateway without affecting other app services.

Persistent Tool Embeddings

For process-local caching, the package already includes McpGatewayInMemoryToolEmbeddingStore:

var services = new ServiceCollection();

services.AddKeyedSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>(
    McpGatewayServiceKeys.EmbeddingGenerator);
services.AddSingleton<IMcpGatewayToolEmbeddingStore, McpGatewayInMemoryToolEmbeddingStore>();

services.AddManagedCodeMcpGateway(options =>
{
    options.AddTool(
        "local",
        AIFunctionFactory.Create(
            static (string query) => $"github:{query}",
            new AIFunctionFactoryOptions
            {
                Name = "github_search_repositories",
                Description = "Search GitHub repositories by user query."
            }));
});

If you want to keep descriptor embeddings in a database or another persistent store, register your own IMcpGatewayToolEmbeddingStore implementation instead:

var services = new ServiceCollection();

services.AddKeyedSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>(
    McpGatewayServiceKeys.EmbeddingGenerator);
services.AddSingleton<IMcpGatewayToolEmbeddingStore, MyToolEmbeddingStore>();

services.AddManagedCodeMcpGateway(options =>
{
    options.AddTool(
        "local",
        AIFunctionFactory.Create(
            static (string query) => $"github:{query}",
            new AIFunctionFactoryOptions
            {
                Name = "github_search_repositories",
                Description = "Search GitHub repositories by user query."
            }));
});

During BuildIndexAsync() the gateway:

  • computes a descriptor-document hash per tool
  • asks IMcpGatewayToolEmbeddingStore for matching stored vectors
  • generates embeddings only for tools that are missing in the store
  • upserts the newly generated vectors back into the store

This avoids recalculating tool embeddings on every rebuild while still refreshing them automatically when the descriptor document changes. Stored vectors are scoped to both the descriptor hash and the resolved embedding-generator fingerprint, so changing the provider or model automatically forces regeneration. Query embeddings are still generated at search time from the registered IEmbeddingGenerator<string, Embedding<float>>.

Supported Sources

  • local AITool / AIFunction
  • HTTP MCP servers
  • stdio MCP servers
  • existing McpClient instances
  • deferred McpClient factories

Local Development

dotnet restore ManagedCode.MCPGateway.slnx
dotnet build ManagedCode.MCPGateway.slnx -c Release
dotnet test --solution ManagedCode.MCPGateway.slnx -c Release
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 30 3/6/2026
0.1.0 30 3/6/2026