ManagedCode.MCPGateway
0.2.0
Prefix Reserved
See the version list below for details.
dotnet add package ManagedCode.MCPGateway --version 0.2.0
NuGet\Install-Package ManagedCode.MCPGateway -Version 0.2.0
<PackageReference Include="ManagedCode.MCPGateway" Version="0.2.0" />
<PackageVersion Include="ManagedCode.MCPGateway" Version="0.2.0" />
<PackageReference Include="ManagedCode.MCPGateway" />
paket add ManagedCode.MCPGateway --version 0.2.0
#r "nuget: ManagedCode.MCPGateway, 0.2.0"
#:package ManagedCode.MCPGateway@0.2.0
#addin nuget:?package=ManagedCode.MCPGateway&version=0.2.0
#tool nuget:?package=ManagedCode.MCPGateway&version=0.2.0
ManagedCode.MCPGateway
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 vector ranking and built-in tokenizer-backed fallback
Install
dotnet add package ManagedCode.MCPGateway
Architecture And Decision Records
- Architecture overview
- ADR-0001: Runtime boundaries and index lifecycle
- ADR-0002: Search ranking and query normalization
- Feature spec: Search query normalization and ranking
What You Get
- one registry for local tools, stdio MCP servers, HTTP MCP servers, existing
McpClientinstances, or deferredMcpClientfactories - a DI-native split between
IMcpGatewayfor runtime search/invoke andIMcpGatewayRegistryfor catalog mutation - descriptor indexing that enriches search with tool name, description, required arguments, and input schema
- lazy index build on the first catalog/search/invoke operation, plus optional eager warmup hooks for startup scenarios
- configurable search strategy with embeddings or tokenizer-backed heuristic ranking
SearchStrategy.Autoby default: use embeddings when available, otherwise fall back to tokenizer-backed ranking automatically- built-in
ChatGptO200kBasetokenizer path for tokenizer search and tokenizer fallback - optional English query normalization before ranking when a keyed search rewrite
IChatClientis registered - top 5 matches by default when
maxResultsis not specified - vector search when an
IEmbeddingGenerator<string, Embedding<float>>is registered - optional persisted tool embeddings through
IMcpGatewayToolEmbeddingStore - token-aware lexical fallback when embeddings are unavailable or vector search cannot complete
- one invoke surface for both local
AIFunctiontools and MCP tools - optional meta-tools you can hand back to another model as normal
AIToolinstances
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>();
var search = await gateway.SearchAsync("find github repositories");
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.
The gateway builds its catalog lazily on the first ListToolsAsync(...), SearchAsync(...), or InvokeAsync(...) call. If you add more tools later through the registry, the next catalog/search/invoke operation rebuilds the index automatically. You only need an explicit warmup call when you want eager startup validation or a pre-warmed cache.
McpGateway is the runtime search/invoke facade. If you need to add tools or MCP sources after the container is built, resolve IMcpGatewayRegistry separately:
var registry = serviceProvider.GetRequiredService<IMcpGatewayRegistry>();
registry.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"weather:{query}",
new AIFunctionFactoryOptions
{
Name = "weather_search_forecast",
Description = "Search weather forecast and temperature information by city name."
}));
var tools = await gateway.ListToolsAsync();
AddManagedCodeMcpGateway(...) registers IMcpGateway, IMcpGatewayRegistry, and McpGatewayToolSet. Add AddManagedCodeMcpGatewayIndexWarmup() only when you want hosted eager initialization.
Public Surfaces
Resolve these services depending on what the host needs:
IMcpGateway: build, list, search, invoke, and create meta-toolsIMcpGatewayRegistry: add local tools or MCP sources after the container is builtMcpGatewayToolSet: expose the gateway itself as reusableAIToolinstances
Those three services deliberately separate runtime execution, catalog mutation, and meta-tool creation instead of collapsing everything into one mutable gateway type.
Register Existing Or Deferred MCP Clients
IMcpGatewayRegistry supports both immediate McpClient instances and deferred client factories:
var registry = serviceProvider.GetRequiredService<IMcpGatewayRegistry>();
registry.AddMcpClient(
sourceId: "issues",
client: existingClient,
disposeClient: false);
registry.AddMcpClientFactory(
sourceId: "work-items",
clientFactory: static async cancellationToken =>
{
return await CreateWorkItemClientAsync(cancellationToken);
});
Use AddMcpClient(...) when another part of the host already owns the client lifetime. Use AddMcpClientFactory(...) when the gateway should lazily create and cache the client through its normal source-loading path.
Invoke By Tool Id Or Stable Identity
The common flow is search first, then invoke by ToolId:
var search = await gateway.SearchAsync("find github repositories");
var invoke = await gateway.InvokeAsync(new McpGatewayInvokeRequest(
ToolId: search.Matches[0].ToolId,
Query: "managedcode"));
If the host already knows the stable tool name, invocation can target ToolName and optionally SourceId instead:
var invoke = await gateway.InvokeAsync(new McpGatewayInvokeRequest(
ToolName: "github_search_repositories",
SourceId: "local",
Query: "managedcode"));
Use SourceId when the same tool name may exist in more than one registered source.
Optional Eager Warmup
If you want to warm the catalog immediately after building the container, use the service-provider extension:
await using var serviceProvider = services.BuildServiceProvider();
var build = await serviceProvider.InitializeManagedCodeMcpGatewayAsync();
InitializeManagedCodeMcpGatewayAsync() returns McpGatewayIndexBuildResult, so startup code can inspect diagnostics or fail fast explicitly.
For hosted applications, register background warmup once and let the host trigger it on startup:
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."
}));
});
services.AddManagedCodeMcpGatewayIndexWarmup();
Use eager warmup when you want fail-fast startup behavior, a warmed cache before the first request, or deterministic startup benchmarking. Otherwise the lazy default is enough.
Recommended Hosted Setup
This example shows the full production-oriented integration shape in one place. Remove the optional registrations if your host does not need vector search, query normalization, or persistent embedding reuse.
using ManagedCode.MCPGateway;
using ManagedCode.MCPGateway.Abstractions;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddKeyedSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>(
McpGatewayServiceKeys.EmbeddingGenerator);
services.AddKeyedSingleton<IChatClient, MySearchRewriteChatClient>(
McpGatewayServiceKeys.SearchQueryChatClient);
services.AddSingleton<IMcpGatewayToolEmbeddingStore, McpGatewayInMemoryToolEmbeddingStore>();
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Auto;
options.SearchQueryNormalization = McpGatewaySearchQueryNormalization.TranslateToEnglishWhenAvailable;
options.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"github:{query}",
new AIFunctionFactoryOptions
{
Name = "github_search_repositories",
Description = "Search GitHub repositories by user query."
}));
options.AddHttpServer(
sourceId: "docs",
endpoint: new Uri("https://example.com/mcp"));
});
services.AddManagedCodeMcpGatewayIndexWarmup();
await using var serviceProvider = services.BuildServiceProvider();
var gateway = serviceProvider.GetRequiredService<IMcpGateway>();
var registry = serviceProvider.GetRequiredService<IMcpGatewayRegistry>();
var metaTools = serviceProvider.GetRequiredService<McpGatewayToolSet>().CreateTools();
registry.AddTool(
"runtime",
AIFunctionFactory.Create(
static (string query) => $"status:{query}",
new AIFunctionFactoryOptions
{
Name = "project_status_lookup",
Description = "Look up project status by identifier or short title."
}));
var search = await gateway.SearchAsync(
new McpGatewaySearchRequest(
Query: "review qeue for managedcode prs",
ContextSummary: "User is looking at repository maintenance work"));
Notes:
SearchStrategy.Autois the default and is usually the right production setting.- the embedding generator, search-query rewrite client, and embedding store are all optional DI integrations
- hosted warmup is optional; if you omit it, the gateway builds its catalog lazily on first use
- runtime registrations through
IMcpGatewayRegistryinvalidate the catalog automatically, so the next list/search/invoke call rebuilds the index McpGatewayToolSetandgateway.CreateMetaTools()expose the same meta-tools in two integration styles
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
AIFunctiontools can receive auto-mappedquery,contextSummary, andcontextarguments when those parameters are required
Meta-Tools
You can expose the gateway itself as two reusable AITool instances:
var tools = gateway.CreateMetaTools();
Or resolve the reusable helper from DI:
var toolSet = serviceProvider.GetRequiredService<McpGatewayToolSet>();
var tools = toolSet.CreateTools();
Custom stable tool names are supported:
var tools = gateway.CreateMetaTools(
searchToolName: "workspace_tool_search",
invokeToolName: "workspace_tool_invoke");
By default this creates:
gateway_tools_searchgateway_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
Default search profile:
SearchStrategy = McpGatewaySearchStrategy.AutoSearchQueryNormalization = McpGatewaySearchQueryNormalization.TranslateToEnglishWhenAvailableDefaultSearchLimit = 5MaxSearchResults = 15
McpGatewaySearchStrategy.Auto means:
- vector search when an embedding generator is registered
- tokenizer-backed heuristic search when embeddings are unavailable
- tokenizer-backed fallback when vector search cannot complete for a request
The tokenizer-backed mode builds field-aware search documents from tool names, display names, descriptions, required arguments, and schema properties. Ranking then happens in two stages:
- stage 1 retrieval with BM25-style field scoring, tokenizer-term cosine similarity, and character 3-gram similarity
- stage 2 reranking over the candidate pool with calibrated coverage, lexical similarity, approximate typo matching, and tool-name evidence
This keeps the search mathematical and tokenizer-driven instead of relying on hand-written query phrase exceptions. The tokenizer-backed path uses the built-in ChatGptO200kBase profile for the GPT-4o / ChatGPT tokenizer family.
There is no public tokenizer-selection option. The package ships one built-in tokenizer-backed path and keeps the behavior configurable through search strategy, optional embeddings, and optional English query normalization.
If an embedding generator is registered and vector search is active, the gateway vectorizes descriptor documents and uses cosine similarity plus lexical boosts. It first tries the keyed registration McpGatewayServiceKeys.EmbeddingGenerator and then falls back to any regular IEmbeddingGenerator<string, Embedding<float>>.
The embedding generator is resolved per gateway operation, so singleton, scoped, and transient DI registrations all work with index builds and search.
Reading Search Diagnostics
McpGatewaySearchResult exposes both the ranking mode and diagnostics for the chosen path:
var result = await gateway.SearchAsync("review qeue for managedcode prs");
Console.WriteLine(result.RankingMode);
foreach (var diagnostic in result.Diagnostics)
{
Console.WriteLine($"{diagnostic.Code}: {diagnostic.Message}");
}
Common diagnostics:
query_normalizedlexical_fallbackvector_search_failed
Optional English Query Normalization
By default, the gateway may rewrite the incoming search query into concise English before ranking:
- it only happens when
options.SearchQueryNormalizationis enabled - it only uses a keyed
IChatClientregistered asMcpGatewayServiceKeys.SearchQueryChatClient - if no keyed chat client is registered, search continues unchanged
- if normalization fails, search continues with the original query and emits a diagnostic
Preferred registration:
var services = new ServiceCollection();
services.AddKeyedSingleton<IChatClient>(
McpGatewayServiceKeys.SearchQueryChatClient,
mySearchRewriteChatClient);
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Auto;
options.SearchQueryNormalization = McpGatewaySearchQueryNormalization.TranslateToEnglishWhenAvailable;
options.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"travel:{query}",
new AIFunctionFactoryOptions
{
Name = "travel_hotel_search",
Description = "Find hotels by city, district, amenities, breakfast, or cancellation policy."
}));
});
Disable normalization when the host wants purely local tokenizer behavior:
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Tokenizer;
options.SearchQueryNormalization = McpGatewaySearchQueryNormalization.Disabled;
});
The package does not register or configure an IChatClient for you. This keeps the gateway generic while still allowing multilingual and typo-heavy search inputs to converge to an English retrieval form when the host opts in.
McpGatewaySearchResult.RankingMode stays:
vectorfor embedding-backed rankinglexicalfor tokenizer-backed ranking and tokenizer fallbackbrowsewhen no search text/context is providedemptywhen the catalog is empty
In other words, the current lexical mode is the working tokenizer mode.
Search Strategy Matrix
Use McpGatewaySearchStrategy.Auto when you want one production default that works everywhere:
- if embeddings are registered, use embeddings
- if embeddings are missing, use tokenizer ranking
- if embeddings fail for a query, fall back to tokenizer ranking
Use McpGatewaySearchStrategy.Embeddings when:
- embeddings are expected in that host
- you want vector search whenever it is available
- tokenizer ranking should only be the fallback path when vector search cannot complete
Use McpGatewaySearchStrategy.Tokenizer when:
- you want a zero-embedding deployment
- you want deterministic local search behavior without an embedding provider
- you want to benchmark tokenizer-backed ranking independently from vector search
Search Strategy Configuration
Force embeddings when they are available:
var services = new ServiceCollection();
services.AddKeyedSingleton<IEmbeddingGenerator<string, Embedding<float>>, MyEmbeddingGenerator>(
McpGatewayServiceKeys.EmbeddingGenerator);
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Embeddings;
options.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"github:{query}",
new AIFunctionFactoryOptions
{
Name = "github_search_repositories",
Description = "Search GitHub repositories by user query."
}));
});
Force tokenizer-backed ranking:
var services = new ServiceCollection();
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Tokenizer;
options.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"github:{query}",
new AIFunctionFactoryOptions
{
Name = "github_search_repositories",
Description = "Search GitHub repositories by user query."
}));
});
Keep the default auto strategy, but make the defaults explicit in code:
var services = new ServiceCollection();
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Auto;
options.DefaultSearchLimit = 5;
options.MaxSearchResults = 15;
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 do not register an embedding generator, the same configuration still works and automatically uses tokenizer ranking.
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.
Tokenizer Fallback Without Embeddings
This is the default operational fallback:
var services = new ServiceCollection();
services.AddManagedCodeMcpGateway(options =>
{
options.SearchStrategy = McpGatewaySearchStrategy.Auto;
options.AddTool(
"local",
AIFunctionFactory.Create(
static (string query) => $"github:{query}",
new AIFunctionFactoryOptions
{
Name = "github_search_repositories",
Description = "Search GitHub repositories by user query."
}));
});
await using var serviceProvider = services.BuildServiceProvider();
var gateway = serviceProvider.GetRequiredService<IMcpGateway>();
var result = await gateway.SearchAsync("review qeue for managedcode prs");
With no embedding generator registered:
- the gateway still builds the catalog
- search uses the built-in
ChatGptO200kBasetokenizer path and two-stage lexical ranking - an optional keyed search rewrite
IChatClientcan normalize the query to English first - typo-tolerant term heuristics still participate in ranking
- the result diagnostics contain
lexical_fallback - the default result set size is 5
If you want tokenizer search only, set options.SearchStrategy = McpGatewaySearchStrategy.Tokenizer.
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."
}));
});
When an index build runs, whether explicitly or through lazy/background warmup, the gateway:
- computes a descriptor-document hash per tool
- asks
IMcpGatewayToolEmbeddingStorefor 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>>.
Search Evaluation
The repository includes a tokenizer evaluation suite built around a 50-tool catalog with intentionally overlapping verbs such as search, lookup, timeline, and summary, while keeping the domain semantics separated in the descriptions.
Coverage buckets in tests/ManagedCode.MCPGateway.Tests/Search/McpGatewayTokenizerSearchEvaluationTests.cs:
- high relevance
- borderline / semantically adjacent tools
- multilingual
- typo / spelling mistakes
- weak-intent / underspecified commands
- irrelevant queries
The evaluation asserts:
top1,top3, andtop5- mean reciprocal rank
- low-confidence behavior for irrelevant queries
The noisy-query buckets intentionally include spelling mistakes and weakly specified commands so the tokenizer path is exercised as a real fallback, not only on clean benchmark phrasing.
Current reference numbers from the repository test corpus:
ChatGptO200kBase: high relevancetop1=95.65%,top3=100%,top5=100%,MRR=0.98; typotop1=100%; weak intenttop1=100%; irrelevantlow-confidence=100%
Supported Sources
- local
AITool/AIFunction - HTTP MCP servers
- stdio MCP servers
- existing
McpClientinstances - deferred
McpClientfactories
Local Development
dotnet restore ManagedCode.MCPGateway.slnx
dotnet build ManagedCode.MCPGateway.slnx -c Release --no-restore
dotnet test --solution ManagedCode.MCPGateway.slnx -c Release --no-build
Analyzer pass:
dotnet build ManagedCode.MCPGateway.slnx -c Release --no-restore -p:RunAnalyzers=true
Detailed TUnit output:
dotnet test --solution ManagedCode.MCPGateway.slnx -c Release --no-build --output Detailed --no-progress
This repository uses TUnit on top of Microsoft.Testing.Platform, so prefer the dotnet test --solution ... commands above. Do not assume VSTest-only flags such as --filter or --logger are available here.
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.AI (>= 10.3.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.ML.Tokenizers (>= 2.0.0)
- Microsoft.ML.Tokenizers.Data.O200kBase (>= 2.0.0)
- ModelContextProtocol (>= 1.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.