Manifold 1.0.0
dotnet add package Manifold --version 1.0.0
NuGet\Install-Package Manifold -Version 1.0.0
<PackageReference Include="Manifold" Version="1.0.0" />
<PackageVersion Include="Manifold" Version="1.0.0" />
<PackageReference Include="Manifold" />
paket add Manifold --version 1.0.0
#r "nuget: Manifold, 1.0.0"
#:package Manifold@1.0.0
#addin nuget:?package=Manifold&version=1.0.0
#tool nuget:?package=Manifold&version=1.0.0
<p align="center"> <img src="assets/logo/logo.svg" alt="Manifold" width="620" /> </p>
Manifold
Manifold is a .NET foundation for defining an operation once and exposing it through both CLI and MCP surfaces.
The model is simple:
- Write one operation by hand
- Let the source generator emit descriptors and invokers
- Wire those generated artifacts into your CLI and/or MCP host
Manifold does not own your transport, hosting model, or product-specific runtime. It focuses on operation definition, binding, metadata, and fast dispatch.
If you want a runnable starting point, the repository includes sample hosts under samples/.
What's Included
| Package | Purpose |
|---|---|
Manifold |
Core contracts, descriptors, attributes, and binding primitives |
Manifold.Cli |
CLI runtime helpers and generated invocation |
Manifold.Generators |
Source generator that emits descriptors and invokers |
Manifold.Mcp |
MCP metadata and invocation helpers |
Core Concepts
An operation is the single source of truth.
From that definition, Manifold.Generators emits:
GeneratedOperationRegistryGeneratedCliInvokerGeneratedMcpCatalogGeneratedMcpInvoker
You compose those generated types into your own application.
Manifold supports two authoring styles:
- Static method operations
- Class-based operations implementing
IOperation<TRequest, TResult>
Install
Pick the surfaces you need.
<ItemGroup>
<PackageReference Include="Manifold" Version="1.0.0" />
<PackageReference Include="Manifold.Generators" Version="1.0.0" PrivateAssets="all" />
<PackageReference Include="Manifold.Cli" Version="1.0.0" />
<PackageReference Include="Manifold.Mcp" Version="1.0.0" />
</ItemGroup>
If you only need CLI, omit Manifold.Mcp. If you only need MCP, omit Manifold.Cli.
Authoring Operations
Static Method Example
Static method operations work well when you want the simplest possible definition.
using Manifold;
public static class MathOperations
{
[Operation("math.add", Summary = "Adds two integers.")]
[CliCommand("math", "add")]
[McpTool("math_add")]
public static int Add(
[Argument(0, Name = "x")] int x,
[Argument(1, Name = "y")] int y)
{
return x + y;
}
}
Class-Based Example
Class-based operations are useful when you need a dedicated request type, richer modeling, or DI-managed construction.
using Manifold;
[Operation("math.add", Summary = "Adds two integers.")]
[CliCommand("math", "add")]
[McpTool("math_add")]
public sealed class AddOperation : IOperation<AddOperation.Request, int>
{
public ValueTask<int> ExecuteAsync(Request request, OperationContext context)
=> ValueTask.FromResult(request.X + request.Y);
public sealed class Request
{
[Argument(0, Name = "x")]
[McpName("x")]
public int X { get; init; }
[Argument(1, Name = "y")]
[McpName("y")]
public int Y { get; init; }
}
}
For class-based operations, register the operation type in DI before using the generated invokers.
using Microsoft.Extensions.DependencyInjection;
ServiceCollection services = new();
services.AddTransient<AddOperation>();
ServiceProvider serviceProvider = services.BuildServiceProvider();
Static method operations do not require DI registration unless they explicitly request services.
Attribute Model
The key attributes are:
[Operation("operation.id")][CliCommand("group", "verb")][McpTool("tool_name")][Argument(position)][Option("name")][Alias(...)][CliName("...")][McpName("...")][CliOnly][McpOnly][ResultFormatter(typeof(...))][FromServices]
Examples:
- Rename an option for CLI only with
[CliName("person")] - Rename an MCP argument with
[McpName("targetName")] - Expose to only one surface with
[CliOnly]or[McpOnly]
CLI Usage
At runtime, compose the generated registry and invoker into a CliApplication.
using Manifold.Cli;
using Manifold.Generated;
using Microsoft.Extensions.DependencyInjection;
ServiceCollection services = new();
services.AddTransient<AddOperation>();
ServiceProvider serviceProvider = services.BuildServiceProvider();
CliApplication cli = new(
GeneratedOperationRegistry.Operations,
new GeneratedCliInvoker(),
serviceProvider);
StringWriter output = new();
StringWriter error = new();
int exitCode = await cli.ExecuteAsync(
["math", "add", "2", "3"],
output,
error,
CancellationToken.None);
Notes:
CliApplicationhandles usage text and command dispatchGeneratedCliInvokeris the generated binding layer- Fast sync and async paths are selected automatically when available
MCP Usage
Manifold does not ship an MCP transport host. Instead, it provides:
- Generated tool metadata via
GeneratedMcpCatalog - Generated execution via
GeneratedMcpInvoker - MCP argument parsing and helper APIs in
Manifold.Mcp
A minimal local invocation looks like this:
using System.Text.Json;
using Manifold.Generated;
using Manifold.Mcp;
using Microsoft.Extensions.DependencyInjection;
ServiceCollection services = new();
services.AddTransient<AddOperation>();
ServiceProvider serviceProvider = services.BuildServiceProvider();
JsonElement args = JsonSerializer.Deserialize<JsonElement>(
"{\"x\":2,\"y\":3}");
GeneratedMcpInvoker invoker = new();
if (invoker.TryInvokeFast(
"math_add",
args,
serviceProvider,
CancellationToken.None,
out ValueTask<FastMcpInvocationResult> invocation))
{
FastMcpInvocationResult result = await invocation;
Console.WriteLine(result.Number);
}
Metadata discovery:
using Manifold.Generated;
foreach (var tool in GeneratedMcpCatalog.Tools)
{
Console.WriteLine($"{tool.Name}: {tool.Description}");
}
MCP Transports and Samples
The primary MCP transports are:
stdioStreamable HTTP
Manifold is intentionally transport-agnostic, so the repository includes sample hosts rather than baking transport hosting into the core packages.
Run them like this:
dotnet run --project .\samples\Manifold.Samples.McpStdioHost\Manifold.Samples.McpStdioHost.csproj
dotnet run --project .\samples\Manifold.Samples.McpHttpHost\Manifold.Samples.McpHttpHost.csproj
The HTTP sample listens on http://127.0.0.1:38474/mcp.
Note: the HTTP sample uses ModelContextProtocol.AspNetCore, which is currently a preview package. The stable core MCP package is ModelContextProtocol.
CLI Sample Host
There is also a minimal runnable CLI host:
dotnet run --project .\samples\Manifold.Samples.CliHost\Manifold.Samples.CliHost.csproj -- math add 2 3
dotnet run --project .\samples\Manifold.Samples.CliHost\Manifold.Samples.CliHost.csproj -- weather preview --city Tokyo --days 3
Dependency Injection and Services
There are two service access patterns.
Method-Based Operations
Use [FromServices] on a parameter.
[Operation("clock.now")]
[CliCommand("clock", "now")]
public static DateTimeOffset Now(
[FromServices] IClock clock)
{
return clock.UtcNow;
}
Class-Based Operations
Use constructor injection, or request services through OperationContext.
public sealed class GreetingOperation(IGreetingService greetings)
: IOperation<GreetingOperation.Request, string>
{
public ValueTask<string> ExecuteAsync(Request request, OperationContext context)
=> ValueTask.FromResult(greetings.Format(request.Name));
public sealed class Request
{
[Option("name")]
public string Name { get; init; } = string.Empty;
}
}
Result Formatting
To provide custom CLI text output while keeping structured results for JSON or MCP, implement IResultFormatter<TResult>.
using Manifold;
public sealed class WeatherFormatter : IResultFormatter<WeatherResult>
{
public string? FormatText(WeatherResult result, OperationContext context)
=> $"{result.City}:{result.TemperatureC}";
}
Then attach it:
[ResultFormatter(typeof(WeatherFormatter))]
Generated Types
The generator emits these public entry points under Manifold.Generated:
GeneratedOperationRegistryGeneratedCliInvokerGeneratedMcpCatalogGeneratedMcpInvoker
These are the standard integration surface for consumers.
Performance
Manifold includes dedicated BenchmarkDotNet suites under benchmarks/.
Benchmark notes and comparison tables are in benchmarks/README.md.
Comparison set:
- CLI
Manifold.CliConsoleAppFrameworkSystem.CommandLine
- MCP
Manifold.Mcp- official
ModelContextProtocol McpToolkitmcpdotnet
Current snapshot:
CLI:
| Scenario | Manifold | ConsoleAppFramework | System.CommandLine |
|---|---|---|---|
| Positional command | 22.61 ns / 0 B |
26.57 ns / 0 B |
1730.82 ns / 4688 B |
| Option-heavy command | 28.89 ns / 0 B |
24.76 ns / 0 B |
2110.84 ns / 5632 B |
MCP (roundtrip-shaped):
| Scenario | Manifold | ModelContextProtocol | McpToolkit | McpDotNet |
|---|---|---|---|---|
tools/list response |
756.3 ns / 0 B |
754.6 ns / 0 B |
635.4 ns / 0 B |
816.2 ns / 0 B |
tools/call response |
47.16 ns / 0 B |
68.56 ns / 0 B |
146.34 ns / 96 B |
93.20 ns / 256 B |
Notes:
- CLI numbers measure the parser + dispatch hot path
- MCP numbers above reflect in-memory response construction, not transport benchmarks
- The raw
ModelContextProtocolinvocation microbenchmark is nearZeroMeasurement; the roundtrip-shaped table is the more meaningful comparison
For methodology and full reports, see benchmarks/README.md.
Build
From the repository root:
./build/restore.ps1
./build/build.ps1 -NoRestore
./build/test.ps1 -NoBuild
./build/quality.ps1
./build/pack.ps1
./build/pack.ps1 writes .nupkg and .snupkg files to .artifacts/packages/.
Repository Status
- Windows-first scripts and CI
- MIT licensed
- CI verifies build, test, formatting, architecture checks, and package creation
OSS Housekeeping
- License:
LICENSE - Contribution notes:
CONTRIBUTING.md - Third-party notices:
THIRD_PARTY_NOTICES.md
Repository Layout
src/
Manifold
Manifold.Cli
Manifold.Generators
Manifold.Mcp
tests/
Manifold.Tests
Manifold.Cli.Tests
Manifold.Generators.Tests
Manifold.Mcp.Tests
benchmarks/
Manifold.Benchmarks
Manifold.Mcp.Benchmarks
samples/
Manifold.Samples.Operations
Manifold.Samples.CliHost
Manifold.Samples.McpStdioHost
Manifold.Samples.McpHttpHost
| 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
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Manifold:
| Package | Downloads |
|---|---|
|
Manifold.Cli
CLI binding and fast invocation runtime for Manifold operations. |
|
|
Manifold.Mcp
MCP binding and fast invocation runtime for Manifold operations. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 145 | 3/29/2026 |