Core Contracts - Garume/Manifold GitHub Wiki

Core Contracts — Manifold Package

The Manifold package is the foundational library upon which the entire Manifold framework is built. It defines the core abstractions — interfaces, descriptor records, enumerations, attributes, and binding primitives — that every other package (Manifold.Cli, Manifold.Mcp, and Manifold.Generators) depends on. This package contains no runtime logic for CLI parsing or MCP transport; it exists purely to establish the contracts that describe operations, their parameters, their execution context, and how results are formatted.

This page provides an exhaustive reference for every public type in the Manifold package. For an understanding of how these contracts are consumed by higher-level packages, see Architecture Overview. For the attributes used to declare operations, see Attributes and Operation Definition. For how the source generator emits code against these contracts, see Source Generator — Manifold.Generators.

Package Overview

The Manifold NuGet package targets .NET 10.0 with the latest C# language version, nullable reference types enabled, and deterministic builds. It has zero external dependencies — every type is self-contained within the Manifold namespace.

Sources: Manifold/Manifold.csproj:1-19, Directory.Build.props:1-16

Property Value
Package ID Manifold
Target Framework net10.0
Language Version latest
Nullable enable
External Dependencies None
License MIT

Type Inventory

The package consists of eight source files defining all public contracts:

Type Kind File Purpose
IOperation<TRequest, TResult> Interface IOperation.cs Operation execution contract
OperationContext Sealed class OperationContext.cs Execution context with services
OperationDescriptor Sealed record DescriptorModels.cs Operation metadata
ParameterDescriptor Sealed record DescriptorModels.cs Parameter metadata
OperationBinding Static class OperationBinding.cs Service resolution utility
IOperationInvoker Interface OperationInvoker.cs Reflectionless invocation
OperationInvocationResult Readonly record struct OperationInvoker.cs Invocation result container
IResultFormatter<TResult> Interface IResultFormatter.cs Result-to-text formatting
InvocationSurface Enum DescriptorModels.cs Invocation origin
OperationVisibility Enum DescriptorModels.cs Surface visibility scope
ParameterSource Enum DescriptorModels.cs Parameter binding source

Type Dependency Diagram

classDiagram
    class IOperation~TRequest TResult~ {
        +ExecuteAsync(TRequest, OperationContext) ValueTask~TResult~
    }
    class OperationContext {
        +OperationId : string?
        +Surface : InvocationSurface
        +Services : IServiceProvider?
        +CancellationToken : CancellationToken
        +State : object?
        +ForCli() OperationContext
        +ForMcp() OperationContext
        +ForProtocol() OperationContext
        +GetService~T~() T?
        +GetRequiredService~T~() T
    }
    class IOperationInvoker {
        +TryInvoke(...) bool
    }
    class OperationInvocationResult {
        +Result : object?
        +ResultType : Type
        +DisplayText : string?
    }
    class OperationDescriptor {
        +OperationId : string
        +DeclaringType : Type
        +MethodName : string
        +ResultType : Type
        +Visibility : OperationVisibility
        +Parameters : IReadOnlyList~ParameterDescriptor~
    }
    class ParameterDescriptor {
        +Name : string
        +ParameterType : Type
        +Source : ParameterSource
        +Required : bool
    }
    class IResultFormatter~TResult~ {
        +FormatText(TResult, OperationContext) string?
    }
    class OperationBinding {
        +GetRequiredService~T~(IServiceProvider?) T
    }

    IOperation~TRequest TResult~ --> OperationContext : receives
    IOperationInvoker --> OperationInvocationResult : produces
    OperationDescriptor --> ParameterDescriptor : contains
    OperationDescriptor --> OperationVisibility : uses
    ParameterDescriptor --> ParameterSource : uses
    OperationContext --> InvocationSurface : uses
    IResultFormatter~TResult~ --> OperationContext : receives
Loading

Enumerations

InvocationSurface

Identifies the runtime surface from which an operation was invoked. This enum is threaded through OperationContext and IOperationInvoker, allowing operation implementations to adapt their behavior based on the calling context.

public enum InvocationSurface
{
    Unknown = 0,
    Cli = 1,
    Mcp = 2,
    Protocol = 3
}

Sources: Manifold/DescriptorModels.cs:3-9

Value Integer Description
Unknown 0 Default / unspecified surface
Cli 1 Invoked from a command-line interface
Mcp 2 Invoked via Model Context Protocol
Protocol 3 Direct programmatic invocation

OperationVisibility

Controls which invocation surfaces can discover and execute a given operation. The source generator reads this value (derived from [CliOnly] and [McpOnly] attributes) to determine whether to emit CLI commands, MCP tools, or both.

public enum OperationVisibility
{
    Both = 0,
    CliOnly = 1,
    McpOnly = 2
}

Sources: Manifold/DescriptorModels.cs:11-16

Value Integer Description
Both 0 Visible on both CLI and MCP surfaces
CliOnly 1 Visible only on the CLI surface
McpOnly 2 Visible only on the MCP surface

ParameterSource

Describes where a parameter's value originates during binding. The source generator uses this to emit the correct binding code for each parameter.

public enum ParameterSource
{
    Option = 0,
    Argument = 1,
    Service = 2,
    CancellationToken = 3
}

Sources: Manifold/DescriptorModels.cs:18-24

Value Integer Description
Option 0 Named option (e.g., --name value)
Argument 1 Positional argument
Service 2 Resolved from IServiceProvider
CancellationToken 3 Injected cancellation token

For details on how each source is bound at runtime, see Parameter Binding and Type Conversion.

IOperation<TRequest, TResult>

The IOperation<TRequest, TResult> interface is the primary contract for class-based operations. When an operation is defined as a class (as opposed to a static method), it must implement this interface. The source generator detects classes decorated with [Operation] that implement IOperation<,> and emits the appropriate invocation code.

public interface IOperation<in TRequest, TResult>
{
    public ValueTask<TResult> ExecuteAsync(TRequest request, OperationContext context);
}

Sources: Manifold/IOperation.cs:1-6

Type Parameters:

Parameter Variance Description
TRequest Contravariant (in) The request/input type carrying parameter values
TResult Invariant The result type returned after execution

The TRequest type is typically a record or class with properties matching the operation's parameters. Each property is bound from CLI arguments/options or MCP JSON fields depending on the invocation surface. The TResult type can be any type; it flows through IResultFormatter<TResult> for text conversion and through the surface-specific result types (CliInvocationResult, FastMcpInvocationResult).

flowchart TD
    A[Host Application] --> B[IOperationInvoker]
    B --> C{Resolve Operation}
    C --> D[IOperation.ExecuteAsync]
    D --> E[OperationContext]
    D --> F[TRequest]
    D --> G[ValueTask of TResult]
    G --> H[IResultFormatter]
    H --> I[Display Text]
Loading

OperationContext

OperationContext is a sealed class that carries all ambient information needed during operation execution: the invocation surface, dependency injection services, cancellation support, and optional custom state. Every operation — whether static-method or class-based — receives an OperationContext instance.

Sources: Manifold/OperationContext.cs:1-84

Constructor

public OperationContext(
    string? operationId,
    InvocationSurface surface,
    IServiceProvider? services = null,
    object? state = null,
    CancellationToken cancellationToken = default)

The constructor normalizes the operationId — if the value is null, empty, or whitespace, it is stored as null; otherwise it is trimmed.

Sources: Manifold/OperationContext.cs:5-17

Properties

Property Type Description
OperationId string? Normalized identifier of the operation being executed
Surface InvocationSurface The surface that initiated this invocation
Services IServiceProvider? Optional DI container for resolving services
CancellationToken CancellationToken Token for cooperative cancellation
State object? Arbitrary state passed through by the host

Static Factory Methods

Three convenience factory methods create OperationContext instances with the Surface pre-set:

public static OperationContext ForCli(
    string? operationId = null,
    IServiceProvider? services = null,
    object? state = null,
    CancellationToken cancellationToken = default)

public static OperationContext ForMcp(...)
public static OperationContext ForProtocol(...)

Sources: Manifold/OperationContext.cs:29-54

Service Resolution Methods

OperationContext provides four methods for resolving services from the Services provider. These methods mirror the Microsoft.Extensions.DependencyInjection patterns but work directly with the IServiceProvider interface without requiring that dependency.

Method Return Behavior
GetService<TService>() TService? Returns null if not found
GetService(Type) object? Returns null if not found
GetRequiredService<TService>() TService Throws InvalidOperationException if not found
GetRequiredService(Type) object Throws InvalidOperationException if not found
public TService? GetService<TService>()
    where TService : class
{
    return Services?.GetService(typeof(TService)) as TService;
}

public object GetRequiredService(Type serviceType)
{
    ArgumentNullException.ThrowIfNull(serviceType);
    object? service = Services?.GetService(serviceType);
    if (service is not null)
        return service;
    throw new InvalidOperationException(
        $"Required service '{serviceType.FullName}' was not available.");
}

Sources: Manifold/OperationContext.cs:56-83

For more on how DI integrates with operations, see Dependency Injection and Service Resolution.

Descriptor Records

The descriptor records provide a metadata model for operations and their parameters. The source generator populates these records at compile time, and they are consumed by the CLI and MCP runtimes to build command structures, generate help text, produce MCP tool catalogs, and perform parameter binding.

flowchart TD
    A[Source Generator] --> B[OperationDescriptor]
    B --> C[ParameterDescriptor list]
    B --> D[CLI Runtime]
    B --> E[MCP Runtime]
    D --> F[Command Tree]
    D --> G[Help Text]
    E --> H[Tool Catalog]
    E --> I[JSON Schema]
Loading

OperationDescriptor

A sealed record that fully describes a single operation — its identity, declaring type, visibility, parameters, and surface-specific overrides.

public sealed record OperationDescriptor(
    string OperationId,
    Type DeclaringType,
    string MethodName,
    Type ResultType,
    OperationVisibility Visibility,
    IReadOnlyList<ParameterDescriptor> Parameters,
    string? Description = null,
    string? Summary = null,
    IReadOnlyList<string>? CliCommandPath = null,
    IReadOnlyList<IReadOnlyList<string>>? CliCommandAliases = null,
    string? McpToolName = null,
    bool Hidden = false,
    Type? RequestType = null);

Sources: Manifold/DescriptorModels.cs:38-51

Property Type Required Description
OperationId string Yes Unique identifier from [Operation] attribute
DeclaringType Type Yes The class or static class that defines the operation
MethodName string Yes Name of the method implementing the operation
ResultType Type Yes The CLR type of the result
Visibility OperationVisibility Yes Which surfaces can see this operation
Parameters IReadOnlyList<ParameterDescriptor> Yes Ordered list of parameter descriptors
Description string? No Detailed description for help/catalog
Summary string? No Brief one-line summary
CliCommandPath IReadOnlyList<string>? No CLI command path segments (e.g., ["file", "copy"])
CliCommandAliases IReadOnlyList<IReadOnlyList<string>>? No Alternative CLI command paths
McpToolName string? No Override name for MCP tool registration
Hidden bool No If true, operation is hidden from help/catalog
RequestType Type? No Request class type for class-based operations

ParameterDescriptor

A sealed record that describes a single parameter of an operation, including its binding source and surface-specific name overrides.

public sealed record ParameterDescriptor(
    string Name,
    Type ParameterType,
    ParameterSource Source,
    bool Required,
    int? Position = null,
    string? Description = null,
    IReadOnlyList<string>? Aliases = null,
    string? CliName = null,
    string? McpName = null,
    string? RequestPropertyName = null);

Sources: Manifold/DescriptorModels.cs:26-36

Property Type Required Description
Name string Yes Canonical parameter name
ParameterType Type Yes CLR type of the parameter
Source ParameterSource Yes Where the value comes from (Option, Argument, Service, CancellationToken)
Required bool Yes Whether the parameter must be provided
Position int? No Positional index for Argument source
Description string? No Help text for this parameter
Aliases IReadOnlyList<string>? No Alternative names (e.g., -n for --name)
CliName string? No Override name on the CLI surface
McpName string? No Override name on the MCP surface
RequestPropertyName string? No Property name in the request type for class-based operations

OperationBinding

A static utility class used by generated code to resolve required services from an IServiceProvider. This is called during parameter binding when a parameter is marked with [FromServices].

public static class OperationBinding
{
    public static TService GetRequiredService<TService>(IServiceProvider? services)
        where TService : class
    {
        object? service = services?.GetService(typeof(TService));
        if (service is TService typedService)
            return typedService;

        throw new InvalidOperationException(
            $"Required service '{typeof(TService).FullName}' was not available.");
    }
}

Sources: Manifold/OperationBinding.cs:1-14

The generated invoker code calls OperationBinding.GetRequiredService<T>(services) for each [FromServices] parameter. This keeps the generated code simple — a single static call — while providing a clear error message when a service is missing.

IOperationInvoker and OperationInvocationResult

OperationInvocationResult

A readonly record struct that wraps the result of an operation invocation along with type information and optional pre-formatted display text.

public readonly record struct OperationInvocationResult(
    object? Result,
    Type ResultType,
    string? DisplayText = null);

Sources: Manifold/OperationInvoker.cs:3-6

Property Type Description
Result object? The boxed result value
ResultType Type The CLR type of the result
DisplayText string? Pre-formatted text from IResultFormatter

IOperationInvoker

The IOperationInvoker interface defines the surface-agnostic contract for invoking operations by their string identifier. The source generator emits a GeneratedCliInvoker and related types that implement this interface.

public interface IOperationInvoker
{
    public bool TryInvoke(
        string operationId,
        object? request,
        IServiceProvider? services,
        InvocationSurface surface,
        CancellationToken cancellationToken,
        out ValueTask<OperationInvocationResult> invocation);
}

Sources: Manifold/OperationInvoker.cs:8-17

The TryInvoke method follows the Try pattern: it returns true if the operation was found and invocation began, writing the asynchronous result to the out parameter; it returns false if the operationId is not recognized.

flowchart TD
    A[Caller provides operationId] --> B[IOperationInvoker.TryInvoke]
    B --> C{Operation Found?}
    C -- Yes --> D[Bind Parameters]
    D --> E[Execute Operation]
    E --> F[OperationInvocationResult]
    C -- No --> G[Return false]
Loading

IResultFormatter<TResult>

The IResultFormatter<TResult> interface allows operations to define custom text formatting for their results. When an operation is decorated with [ResultFormatter(typeof(MyFormatter))], the generated invoker calls the formatter after execution to produce display text.

public interface IResultFormatter<in TResult>
{
    public string? FormatText(TResult result, OperationContext context);
}

Sources: Manifold/IResultFormatter.cs:1-6

The FormatText method receives both the result and the OperationContext, enabling surface-aware formatting. Returning null indicates that no special formatting is needed and the default behavior should apply.

For details on result types and formatting across surfaces, see Result Types and Formatting.

Attributes

The Manifold package defines all attributes used to annotate operations and their parameters. These attributes are read at compile time by the source generator, not at runtime via reflection.

Operation-Level Attributes

OperationAttribute

The primary attribute for declaring an operation. Can be applied to both static methods and classes.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
    AllowMultiple = false, Inherited = false)]
public class OperationAttribute(string operationId) : Attribute
{
    public string OperationId { get; }
    public string? Description { get; set; }
    public string? Summary { get; set; }
    public bool Hidden { get; set; }
}

Sources: Manifold/OperationAttribute.cs:1-15

The operationId constructor parameter is validated to be non-empty and is trimmed. Description and Summary are optional metadata used for help text and MCP tool catalogs.

CliCommandAttribute

Overrides the default CLI command path for an operation.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class CliCommandAttribute(params string[] pathSegments) : Attribute
{
    public string[] PathSegments { get; }
}

Sources: Manifold/ParameterAttributes.cs:66-75

Path segments are filtered for empty values and trimmed. At least one segment is required.

McpToolAttribute

Overrides the default MCP tool name for an operation.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class McpToolAttribute(string name) : Attribute
{
    public string Name { get; }
}

Sources: Manifold/ParameterAttributes.cs:77-83

Visibility Attributes

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class CliOnlyAttribute : Attribute;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class McpOnlyAttribute : Attribute;

Sources: Manifold/ParameterAttributes.cs:85-89

These marker attributes set OperationVisibility.CliOnly or OperationVisibility.McpOnly respectively. Applying both to the same operation produces diagnostic DMCF001 at compile time. See Diagnostics and Compile-Time Validation.

ResultFormatterAttribute

Associates an IResultFormatter<TResult> implementation with an operation.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class ResultFormatterAttribute(Type formatterType) : Attribute
{
    public Type FormatterType { get; }
}

Sources: Manifold/ParameterAttributes.cs:94-98

Parameter-Level Attributes

OptionAttribute

Marks a parameter as a named option (e.g., --name value on CLI, "name": "value" in MCP JSON).

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class OptionAttribute(string name) : Attribute
{
    public string Name { get; }
    public string? Description { get; set; }
    public bool Required { get; set; } = true;
}

Sources: Manifold/ParameterAttributes.cs:3-13

ArgumentAttribute

Marks a parameter as a positional argument. The position must be zero or greater.

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public sealed class ArgumentAttribute(int position) : Attribute
{
    public int Position { get; }
    public string? Name { get; set; }
    public string? Description { get; set; }
    public bool Required { get; set; } = true;
}

Sources: Manifold/ParameterAttributes.cs:15-27

Applying both [Option] and [Argument] to the same parameter produces diagnostic DMCF002.

AliasAttribute

Provides alternative names for commands or parameters. Supports multiple applications (AllowMultiple = true).

[AttributeUsage(... AllowMultiple = true)]
public sealed class AliasAttribute(params string[] aliases) : Attribute
{
    public string[] Aliases { get; }
}

Sources: Manifold/ParameterAttributes.cs:29-48

Aliases are normalized: empty values are removed, remaining values are trimmed, and duplicates (case-insensitive) are eliminated. At least one valid alias is required.

CliNameAttribute and McpNameAttribute

Override the parameter name on a specific surface without affecting the other.

public sealed class CliNameAttribute(string name) : Attribute { ... }
public sealed class McpNameAttribute(string name) : Attribute { ... }

Sources: Manifold/ParameterAttributes.cs:50-64

FromServicesAttribute

Marks a parameter for dependency injection. Parameters with this attribute have ParameterSource.Service and are resolved from IServiceProvider at invocation time.

[AttributeUsage(AttributeTargets.Parameter)]
public sealed class FromServicesAttribute : Attribute;

Sources: Manifold/ParameterAttributes.cs:91-92

For full details on all attributes, see Attributes and Operation Definition.

Attribute Summary Table

Attribute Targets AllowMultiple Purpose
[Operation] Method, Class No Declares an operation
[CliCommand] Method, Class No Custom CLI command path
[McpTool] Method, Class No Custom MCP tool name
[CliOnly] Method, Class No Restrict to CLI surface
[McpOnly] Method, Class No Restrict to MCP surface
[ResultFormatter] Method, Class No Custom result formatter
[Option] Parameter, Property No Named option binding
[Argument] Parameter, Property No Positional argument binding
[Alias] Method, Class, Parameter, Property Yes Alternative names
[CliName] Method, Class, Parameter, Property No CLI name override
[McpName] Method, Class, Parameter, Property No MCP name override
[FromServices] Parameter No DI service injection

End-to-End Data Flow

The following diagram shows how core contracts are used across the full operation lifecycle — from definition through generation to invocation.

sequenceDiagram
    participant Dev as Developer
    participant Gen as Source Generator
    participant Reg as OperationDescriptor Registry
    participant Host as Host Application
    participant Inv as IOperationInvoker
    participant Op as IOperation / Static Method
    participant Ctx as OperationContext
    participant Fmt as IResultFormatter

    Dev->>Gen: Annotate with [Operation]
    Gen->>Reg: Emit OperationDescriptor records
    Gen->>Inv: Emit generated invoker
    Host->>Inv: TryInvoke(operationId, request, ...)
    Inv->>Ctx: Create OperationContext
    Inv->>Op: ExecuteAsync(request, context)
    Op->>Ctx: GetService / GetRequiredService
    Op-->>Inv: ValueTask of TResult
    Inv->>Fmt: FormatText(result, context)
    Fmt-->>Inv: Display text
    Inv-->>Host: OperationInvocationResult
Loading

Design Principles

Zero Dependencies

The Manifold package deliberately has no NuGet dependencies. It uses only BCL types (IServiceProvider, Type, CancellationToken, ValueTask<T>). This ensures that the contracts can be referenced by any .NET project without introducing transitive dependencies.

Record-Based Descriptors

Both OperationDescriptor and ParameterDescriptor are sealed records, providing value equality, immutability, and with-expression support. This allows the source generator to emit compact construction code and enables runtime systems to safely cache and compare descriptors.

Struct-Based Results

OperationInvocationResult is a readonly record struct, avoiding heap allocation for the common case where the result flows synchronously through the invocation pipeline. This aligns with the zero-allocation fast-path design documented in Performance and Benchmarks.

Surface Abstraction

The InvocationSurface enum and OperationVisibility enum work together to provide a clean separation between the CLI and MCP surfaces. Operations can be written once and exposed on both surfaces, or restricted to one, without any changes to the operation logic itself.

Related Pages

⚠️ **GitHub.com Fallback** ⚠️