Source Generator - Garume/Manifold GitHub Wiki

Source Generator — Manifold.Generators

The Manifold.Generators package contains an incremental C# source generator (OperationDescriptorGenerator) that analyzes [Operation]-attributed code at compile time and emits up to six generated source files. These files provide the operation registry, CLI invoker, MCP tool catalog, MCP invoker, MCP tool integration, and a general-purpose operation invoker — all without runtime reflection.

This page covers the internal architecture of the generator, its analysis pipeline, the emitted artifacts, and the compile-time diagnostics it reports. The generator is the linchpin that connects the Core Contracts to both the CLI Runtime and the MCP Runtime. For attribute definitions consumed by the generator, see Attributes and Operation Definition. For the diagnostic reference, see Diagnostics and Compile-Time Validation.

Project Configuration

The generator targets netstandard2.0 so it can be loaded by any version of the Roslyn compiler. It is packaged as an analyzer (placed in analyzers/dotnet/cs within the NuGet package) and produces no library output (IncludeBuildOutput=false).

Sources: Manifold.Generators.csproj:1-45

Property Value
Target Framework netstandard2.0
Roslyn Dependency Microsoft.CodeAnalysis.CSharp 4.14.0
Analyzer Enforcement EnforceExtendedAnalyzerRules=true
Package Path analyzers/dotnet/cs
NuGet ID Manifold.Generators

Generator Architecture

The generator is implemented as a single class, OperationDescriptorGenerator, which implements the IIncrementalGenerator interface. The entire implementation resides in one file (~2,800 lines) within the Manifold.Generators namespace.

Sources: OperationDescriptorGenerator.cs:9-10

[Generator]
public sealed class OperationDescriptorGenerator : IIncrementalGenerator

Recognized Attribute Metadata Names

The generator resolves 12 attribute types by their fully qualified metadata names at compile time, never by runtime reflection:

Sources: OperationDescriptorGenerator.cs:12-23

Constant Metadata Name
OperationAttributeMetadataName Manifold.OperationAttribute
OptionAttributeMetadataName Manifold.OptionAttribute
ArgumentAttributeMetadataName Manifold.ArgumentAttribute
AliasAttributeMetadataName Manifold.AliasAttribute
CliCommandAttributeMetadataName Manifold.CliCommandAttribute
CliNameAttributeMetadataName Manifold.CliNameAttribute
McpToolAttributeMetadataName Manifold.McpToolAttribute
McpNameAttributeMetadataName Manifold.McpNameAttribute
CliOnlyAttributeMetadataName Manifold.CliOnlyAttribute
McpOnlyAttributeMetadataName Manifold.McpOnlyAttribute
FromServicesAttributeMetadataName Manifold.FromServicesAttribute
ResultFormatterAttributeMetadataName Manifold.ResultFormatterAttribute

Generation Pipeline

The generation pipeline follows the Roslyn incremental generator pattern with three stages: Predicate, Transform, and Execute.

flowchart TD
    A["ForAttributeWithMetadataName\n(OperationAttribute)"] --> B["CreateCandidate\n(Transform)"]
    B --> C{"Target Symbol\nType?"}
    C -->|IMethodSymbol| D["CreateMethodCandidate"]
    C -->|INamedTypeSymbol| E["CreateClassCandidate"]
    D --> F["OperationAnalysisResult"]
    E --> F
    F --> G["Collect + Combine\nwith Compilation"]
    G --> H["Execute\n(Source Output)"]
    H --> I["Report Diagnostics"]
    H --> J["Sort Operations\nby OperationId"]
    J --> K["Emit Source Files\n(Conditional)"]
Loading

Stage 1: Predicate and Transform

The Initialize method registers a ForAttributeWithMetadataName provider that finds all symbols decorated with [Operation]. The predicate accepts all syntax nodes (static (_, _) => true). The transform phase calls CreateCandidate, which dispatches to CreateMethodCandidate or CreateClassCandidate based on the target symbol type.

Sources: OperationDescriptorGenerator.cs:63-91

public void Initialize(IncrementalGeneratorInitializationContext context)
{
    IncrementalValuesProvider<OperationAnalysisResult> candidates = context.SyntaxProvider
        .ForAttributeWithMetadataName(
            OperationAttributeMetadataName,
            static (_, _) => true,
            static (attributeContext, cancellationToken) => CreateCandidate(attributeContext, cancellationToken));

    IncrementalValueProvider<(Compilation Left, ImmutableArray<OperationAnalysisResult> Right)> generationInputs =
        context.CompilationProvider.Combine(candidates.Collect());

    context.RegisterSourceOutput(generationInputs, static (productionContext, input) =>
        Execute(productionContext, input.Left, input.Right));
}

Stage 2: Operation Analysis

Static Method Operations

CreateMethodCandidate processes static methods annotated with [Operation]. It:

  1. Checks for conflicting [CliOnly]/[McpOnly] attributes (reports DMCF001)
  2. Analyzes each method parameter via CreateParameterCandidate
  3. Extracts the CLI command path from [CliCommand] or [CliName]
  4. Extracts the MCP tool name from [McpTool], [McpName], or the operation ID
  5. Unwraps the return type (Task/ValueTask) to determine the result type
  6. Builds an OperationCandidate with InvocationKind.StaticMethod

Sources: OperationDescriptorGenerator.cs:93-157

Class-Based Operations

CreateClassCandidate processes classes annotated with [Operation]. It:

  1. Checks for conflicting visibility attributes (DMCF001)
  2. Validates the class implements IOperation<TRequest, TResult> (reports DMCF004 if missing)
  3. Locates the ExecuteAsync(TRequest, OperationContext) method (reports DMCF004 if missing)
  4. Analyzes request type properties via CreatePropertyCandidate
  5. Builds an OperationCandidate with InvocationKind.InstanceOperation

Sources: OperationDescriptorGenerator.cs:159-255

flowchart TD
    A["CreateClassCandidate"] --> B{"Has [CliOnly]\nand [McpOnly]?"}
    B -->|Yes| C["Report DMCF001"]
    B -->|No| D{"Implements\nIOperation?"}
    D -->|No| E["Report DMCF004"]
    D -->|Yes| F{"Has\nExecuteAsync?"}
    F -->|No| E
    F -->|Yes| G["Analyze Request\nProperties"]
    G --> H{"Property\nWritable?"}
    H -->|No| I["Report DMCF005"]
    H -->|Yes| J["Build\nOperationCandidate"]
Loading

Parameter Analysis

CreateParameterCandidate handles method parameters and validates their binding:

  • [Option] and [Argument] are mutually exclusive (reports DMCF002)
  • Parameters without [Option], [Argument], [FromServices], or CancellationToken type trigger DMCF003
  • CancellationToken parameters are bound as ParameterSourceCandidate.CancellationToken
  • [FromServices] parameters are bound as ParameterSourceCandidate.Service

Sources: OperationDescriptorGenerator.cs:289-353

CreatePropertyCandidate handles request type properties for class-based operations. It additionally validates that properties have a public init or set accessor (reports DMCF005).

Sources: OperationDescriptorGenerator.cs:355-412

Stage 3: Execute and Emit

The Execute method collects validated candidates, reports any accumulated diagnostics, sorts operations by OperationId using ordinal comparison for deterministic output, and conditionally emits up to six source files.

Sources: OperationDescriptorGenerator.cs:620-688

flowchart TD
    A["Execute"] --> B["Report Diagnostics"]
    B --> C["Sort by OperationId"]
    C --> D["Always Emit:\nGeneratedOperationRegistry"]
    C --> E{"IOperationInvoker\nin compilation?"}
    E -->|Yes| F["Emit:\nGeneratedOperationInvoker"]
    C --> G{"ICliInvoker\nin compilation?"}
    G -->|Yes| H["Emit:\nGeneratedCliInvoker"]
    C --> I{"McpServerToolType\nin compilation?"}
    I -->|Yes| J["Emit:\nGeneratedMcpTools"]
    C --> K{"McpToolDescriptor\nin compilation?"}
    K -->|Yes| L["Emit:\nGeneratedMcpCatalog"]
    C --> M{"IMcpToolInvoker\nin compilation?"}
    M -->|Yes| N["Emit:\nGeneratedMcpInvoker"]
Loading

Each artifact is gated by a type availability check — the generator verifies that the required types exist in the compilation before emitting the corresponding source file. This allows consumers to reference only the packages they need.

Emitted Artifacts

All generated code is placed in the Manifold.Generated namespace and marked with // <auto-generated/> and #nullable enable.

GeneratedOperationRegistry

File: GeneratedOperationRegistry.g.cs — Always emitted.

A static class containing an array of OperationDescriptor instances and a lookup method. This is the central metadata registry used by both CLI and MCP runtimes.

Sources: OperationDescriptorGenerator.cs:690-724

public static class GeneratedOperationRegistry
{
    private static readonly OperationDescriptor[] operations = [ /* ... */ ];
    public static IReadOnlyList<OperationDescriptor> Operations => operations;
    public static bool TryFind(string operationId, out OperationDescriptor? descriptor) { /* ... */ }
}

Each OperationDescriptor is constructed with the operation ID, declaring type, method name, result type, visibility, parameter descriptors, description, CLI command path, CLI command aliases, MCP tool name, hidden flag, and request type.

Sources: OperationDescriptorGenerator.cs:2536-2572

GeneratedOperationInvoker

File: GeneratedOperationInvoker.g.cs — Emitted when IOperationInvoker, OperationInvocationResult, and OperationBinding exist in the compilation.

Sources: OperationDescriptorGenerator.cs:644-651

Implements IOperationInvoker with a TryInvoke method that dispatches by operation ID to per-operation methods. Only generated for class-based (instance) operations.

public sealed class GeneratedOperationInvoker : IOperationInvoker
{
    public bool TryInvoke(string operationId, object? request, IServiceProvider? services,
        InvocationSurface surface, CancellationToken cancellationToken,
        out ValueTask<OperationInvocationResult> invocation) { /* switch on operationId */ }
}

Sources: OperationDescriptorGenerator.cs:726-767

GeneratedCliInvoker

File: GeneratedCliInvoker.g.cs — Emitted when ICliInvoker and CliInvocationResult exist in the compilation.

Sources: OperationDescriptorGenerator.cs:653-659

Implements three interfaces for tiered dispatch performance:

Interface Method Description
IFastSyncCliInvoker TryInvokeFastSync Synchronous zero-allocation path
IFastCliInvoker TryInvokeFast Async fast path returning ValueTask<FastCliInvocationResult>
ICliInvoker TryInvoke General-purpose path with full binding

Sources: OperationDescriptorGenerator.cs:769-942

public sealed class GeneratedCliInvoker : ICliInvoker, IFastSyncCliInvoker, IFastCliInvoker
{
    public bool TryInvokeFastSync(string[] commandTokens, IServiceProvider? services,
        CancellationToken cancellationToken, out FastCliInvocationResult invocation) { /* ... */ }

    public bool TryInvokeFast(string[] commandTokens, IServiceProvider? services,
        CancellationToken cancellationToken, out ValueTask<FastCliInvocationResult> invocation) { /* ... */ }

    public bool TryInvoke(string operationId, IReadOnlyDictionary<string, string> options,
        IReadOnlyList<string> arguments, IServiceProvider? services, bool jsonRequested,
        CancellationToken cancellationToken, out ValueTask<CliInvocationResult> invocation) { /* ... */ }
}

Fast-Path Token Matching

The TryInvokeFastSync and TryInvokeFast methods match command tokens by array index against known command paths. Matching is case-sensitive first, with an OrdinalIgnoreCase fallback. Paths are ordered longest-first to match the most specific command. Before dispatching, the generator inserts a ContainsReservedGlobalFlag check to bail out when global flags (like --help) are present.

Sources: OperationDescriptorGenerator.cs:784-832

Fast-Path Eligibility

An operation qualifies for the fast sync invoker if all parameters have supported types and the return kind is Void or Value (synchronous). The fast async invoker supports the same parameter types but permits async return types.

Sources: OperationDescriptorGenerator.cs:2354-2373

Supported fast-path parameter types:

Type Parser Method
string identity (no parse)
bool ParseBoolean
int ParseInt32
long ParseInt64
double ParseDouble
decimal ParseDecimal
Guid ParseGuid
Uri ParseUri
DateTimeOffset ParseDateTimeOffset

Sources: OperationDescriptorGenerator.cs:2438-2473

GeneratedMcpTools

File: GeneratedMcpTools.g.cs — Emitted when McpBinding, McpServerToolTypeAttribute, and McpServerBuilderExtensions exist in the compilation.

Sources: OperationDescriptorGenerator.cs:661-668

This artifact integrates directly with the ModelContextProtocol SDK. It generates a class decorated with [McpServerToolType] where each MCP-visible operation becomes a public async method decorated with [McpServerTool] and [Description]. The file also emits an AddGeneratedMcpServer() extension method for IServiceCollection.

Sources: OperationDescriptorGenerator.cs:1003-1042

[McpServerToolType]
public sealed class GeneratedMcpTools
{
    private readonly IServiceProvider? services;
    public GeneratedMcpTools(IServiceProvider? services = null) { this.services = services; }

    [McpServerTool(Name = "math.add")]
    [Description("Add two integers.")]
    public async Task<string> MathAdd(
        [JsonPropertyName("x")] int x,
        [JsonPropertyName("y")] int y) { /* ... */ }
}

public static class GeneratedMcpServiceCollectionExtensions
{
    public static IMcpServerBuilder AddGeneratedMcpServer(this IServiceCollection services) { /* ... */ }
}

GeneratedMcpCatalog

File: GeneratedMcpCatalog.g.cs — Emitted when McpToolDescriptor and McpParameterDescriptor exist in the compilation.

Sources: OperationDescriptorGenerator.cs:670-676

A static class providing an array of McpToolDescriptor instances, a Dictionary-based lookup by tool name, and span access.

Sources: OperationDescriptorGenerator.cs:1044-1089

public static class GeneratedMcpCatalog
{
    private static readonly McpToolDescriptor[] tools = [ /* ... */ ];
    private static readonly Dictionary<string, McpToolDescriptor> toolsByName = CreateToolsByName();
    public static IReadOnlyList<McpToolDescriptor> Tools => tools;
    public static ReadOnlySpan<McpToolDescriptor> AsSpan() => tools;
    public static bool TryFind(string toolName, out McpToolDescriptor descriptor) { /* ... */ }
}

GeneratedMcpInvoker

File: GeneratedMcpInvoker.g.cs — Emitted when IMcpToolInvoker, IFastMcpToolInvoker, IFastSyncMcpToolInvoker, FastMcpInvocationResult, and OperationInvocationResult exist in the compilation.

Sources: OperationDescriptorGenerator.cs:678-687

Implements three interfaces mirroring the CLI invoker's tiered dispatch model but for MCP tool invocation with JSON argument parsing:

Sources: OperationDescriptorGenerator.cs:1091-1167

public sealed class GeneratedMcpInvoker : IMcpToolInvoker, IFastMcpToolInvoker, IFastSyncMcpToolInvoker
{
    public bool TryInvokeFastSync(string toolName, JsonElement? arguments,
        IServiceProvider? services, CancellationToken cancellationToken,
        out FastMcpInvocationResult invocation) { /* ... */ }

    public bool TryInvokeFast(string toolName, JsonElement? arguments,
        IServiceProvider? services, CancellationToken cancellationToken,
        out ValueTask<FastMcpInvocationResult> invocation) { /* ... */ }

    public bool TryInvoke(string toolName, JsonElement? arguments,
        IServiceProvider? services, CancellationToken cancellationToken,
        out ValueTask<OperationInvocationResult> invocation) { /* ... */ }
}

MCP parameter binding extracts values from JsonElement using UTF-8 property name matching and parses via McpBinding helper methods.

Sources: OperationDescriptorGenerator.cs:2420-2431

Conditional Emission Summary

flowchart TD
    subgraph Always
        A["GeneratedOperationRegistry.g.cs"]
    end
    subgraph Core["Requires Manifold"]
        B["GeneratedOperationInvoker.g.cs"]
    end
    subgraph CLI["Requires Manifold.Cli"]
        C["GeneratedCliInvoker.g.cs"]
    end
    subgraph MCP["Requires Manifold.Mcp + MCP SDK"]
        D["GeneratedMcpTools.g.cs"]
        E["GeneratedMcpCatalog.g.cs"]
        F["GeneratedMcpInvoker.g.cs"]
    end
    G["Compilation"] --> A
    G -->|IOperationInvoker| B
    G -->|ICliInvoker| C
    G -->|McpServerToolType| D
    G -->|McpToolDescriptor| E
    G -->|IMcpToolInvoker| F
Loading
Artifact Gate Types Namespace
GeneratedOperationRegistry (none — always) Manifold.Generated
GeneratedOperationInvoker IOperationInvoker, OperationInvocationResult, OperationBinding Manifold.Generated
GeneratedCliInvoker ICliInvoker, CliInvocationResult Manifold.Generated
GeneratedMcpTools McpBinding, McpServerToolTypeAttribute, McpServerBuilderExtensions Manifold.Generated
GeneratedMcpCatalog McpToolDescriptor, McpParameterDescriptor Manifold.Generated
GeneratedMcpInvoker IMcpToolInvoker, IFastMcpToolInvoker, IFastSyncMcpToolInvoker, FastMcpInvocationResult, OperationInvocationResult Manifold.Generated

Compile-Time Diagnostics

The generator defines five diagnostic rules, all in the Manifold category with Error severity.

Sources: OperationDescriptorGenerator.cs:27-61

Code Title Message Format Trigger
DMCF001 Conflicting CLI and MCP visibility Operation '{0}' cannot be marked with both [CliOnly] and [McpOnly] Both [CliOnly] and [McpOnly] on same operation
DMCF002 Conflicting parameter binding Parameter '{0}' on operation '{1}' cannot be marked with both [Option] and [Argument] Both [Option] and [Argument] on same parameter
DMCF003 Unsupported parameter binding Parameter '{0}' on operation '{1}' must be bound with [Option], [Argument], [FromServices], or be a CancellationToken Parameter without a recognized binding
DMCF004 Unsupported operation class Operation class '{0}' must implement IOperation<TRequest, TResult> and expose ExecuteAsync(TRequest, OperationContext) Class lacks IOperation<,> or ExecuteAsync
DMCF005 Unsupported request property binding Property '{0}' on request type '{1}' for operation '{2}' must be writable with a public init or set accessor Request property lacks public setter/init

When any diagnostic is reported during analysis of an operation, that operation's OperationCandidate is set to null and the operation is excluded from code generation. Diagnostics are accumulated and reported via SourceProductionContext.ReportDiagnostic.

Sources: OperationDescriptorGenerator.cs:626-632

Internal Data Models

The generator uses several private model classes to carry analysis results through the pipeline.

OperationCandidate

Represents a fully analyzed operation ready for code generation:

Sources: OperationDescriptorGenerator.cs:2619-2676

Property Type Description
OperationId string Unique operation identifier
DeclaringTypeName string Fully qualified declaring type
MethodName string Target method name
MethodReturnTypeName string Fully qualified return type
ResultTypeName string Unwrapped result type
ReturnKind MethodReturnKind Void, Value, Task, TaskOfT, ValueTask, ValueTaskOfT
Visibility OperationVisibilityCandidate Both, CliOnly, or McpOnly
Parameters ImmutableArray<ParameterCandidate> Analyzed parameters
Description string? Operation description text
Summary string? Operation summary text
CliCommandPath ImmutableArray<string>? CLI command path segments
CliCommandAliases ImmutableArray<ImmutableArray<string>>? CLI command alias paths
McpToolName string? MCP tool name
FormatterTypeName string? Custom result formatter type
Hidden bool Whether the operation is hidden from help
InvocationKind InvocationKind StaticMethod or InstanceOperation
RequestTypeName string? Request type for class-based operations

ParameterCandidate

Represents a fully analyzed parameter:

Sources: OperationDescriptorGenerator.cs:2692-2728

Property Type Description
Name string Parameter name
ParameterTypeName string Fully qualified type name
Source ParameterSourceCandidate Option, Argument, Service, or CancellationToken
Required bool Whether the parameter is required
Position int? Positional index for arguments
Description string? Parameter description
Aliases ImmutableArray<string>? Parameter aliases
CliName string? CLI-specific name override
McpName string? MCP-specific name override
RequestPropertyName string? Request property name (class-based operations)

Internal Enumerations

Sources: OperationDescriptorGenerator.cs:2771-2800

private enum OperationVisibilityCandidate { Both = 0, CliOnly = 1, McpOnly = 2 }
private enum ParameterSourceCandidate    { Option = 0, Argument = 1, Service = 2, CancellationToken = 3 }
private enum MethodReturnKind            { Void = 0, Value = 1, Task = 2, TaskOfT = 3, ValueTask = 4, ValueTaskOfT = 5 }
private enum InvocationKind              { StaticMethod = 0, InstanceOperation = 1 }

Parameter Binding Code Generation

CLI Parameter Binding

The AppendCliParameterBinding method emits binding code for each parameter source:

Sources: OperationDescriptorGenerator.cs:2285-2352

Source Generated Binding Pattern
CancellationToken Direct assignment from cancellationToken
Service CliBinding.GetRequiredService<T>(services)
Argument (required) CliBinding.ConvertValue(typeof(T), CliBinding.GetRequiredArgument(arguments, index, name))
Argument (optional) Bounds check on arguments.Count, falls back to default
Option (required) CliBinding.TryFindOptionValue(...) with throw ArgumentException on miss
Option (optional) CliBinding.TryFindOptionValue(...) with default on miss

MCP Parameter Binding

MCP parameters are extracted from JsonElement using UTF-8 property name matching. For known types, the generator calls McpBinding.Parse* methods directly. For unknown types, it falls back to McpBinding.ConvertValue.

Sources: OperationDescriptorGenerator.cs:2420-2431

Result Formatting

CLI Result Formatting

The generator emits result formatting code based on whether a custom [ResultFormatter] is present and the result type:

  1. Custom formatter: Resolves the formatter from services, calls FormatText(result, context)
  2. Known fast type: Uses FastCliInvocationResult.From* factory methods (FromText, FromBoolean, FromNumber, FromLargeNumber, FromRealNumber, FromPreciseNumber, FromIdentifier, FromTimestamp)
  3. Fallback: Uses CliBinding.FormatDefaultText(result)

Sources: OperationDescriptorGenerator.cs:2119-2205

MCP Result Formatting

MCP results follow the same tiered strategy using FastMcpInvocationResult.From* factory methods for known types.

Utility Methods

Operation Method Naming

GetOperationMethodBaseName converts dot-separated operation IDs to PascalCase method names (e.g., math.add becomes MathAdd). Non-alphanumeric characters act as separators.

Sources: OperationDescriptorGenerator.cs:2480-2497

Variable Name Generation

GetBoundVariableName generates prefixed variable names (__uops_ prefix) to avoid collisions with user code.

Sources: OperationDescriptorGenerator.cs:2499-2506

Return Type Classification

UnwrapResultType strips Task<T> and ValueTask<T> wrappers to obtain the underlying result type. GetMethodReturnKind classifies the return type into one of six categories used to generate appropriate async/await patterns.

Sources: OperationDescriptorGenerator.cs:526-562

ExecuteAsync Discovery

For class-based operations, FindExecuteMethod locates the ExecuteAsync method by checking for a non-static method with exactly two parameters: TRequest and OperationContext.

Sources: OperationDescriptorGenerator.cs:257-266

private static IMethodSymbol? FindExecuteMethod(INamedTypeSymbol typeSymbol, ITypeSymbol requestType)
{
    return typeSymbol.GetMembers("ExecuteAsync")
        .OfType<IMethodSymbol>()
        .FirstOrDefault(methodSymbol =>
            !methodSymbol.IsStatic &&
            methodSymbol.Parameters.Length == 2 &&
            SymbolEqualityComparer.Default.Equals(methodSymbol.Parameters[0].Type, requestType) &&
            string.Equals(methodSymbol.Parameters[1].Type.ToDisplayString(),
                OperationContextMetadataName, StringComparison.Ordinal));
}

End-to-End Data Flow

sequenceDiagram
    participant Compiler as Roslyn Compiler
    participant Gen as OperationDescriptorGenerator
    participant Analyze as Analysis Pipeline
    participant Emit as Code Emitter

    Compiler->>Gen: Initialize()
    Gen->>Compiler: Register ForAttributeWithMetadataName
    Compiler->>Gen: Transform (per [Operation] symbol)
    Gen->>Analyze: CreateCandidate()
    Analyze->>Analyze: CreateMethodCandidate() or CreateClassCandidate()
    Analyze->>Analyze: CreateParameterCandidate() / CreatePropertyCandidate()
    Analyze-->>Gen: OperationAnalysisResult (candidate + diagnostics)
    Compiler->>Gen: Execute (all candidates + compilation)
    Gen->>Compiler: ReportDiagnostic (DMCF001-DMCF005)
    Gen->>Gen: Sort operations by OperationId
    Gen->>Emit: GenerateSource (registry)
    Gen->>Emit: GenerateCliInvokerSource (conditional)
    Gen->>Emit: GenerateMcpToolsSource (conditional)
    Gen->>Emit: GenerateMcpCatalogSource (conditional)
    Gen->>Emit: GenerateMcpInvokerSource (conditional)
    Emit-->>Compiler: AddSource (*.g.cs files)
Loading

Related Pages

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