Skip to main content
The Qyl.Agents.Generator package is an incremental source generator that transforms [McpServer] classes into fully functional MCP servers at build time.

How It Works

  1. Extraction — scans for [McpServer] classes and [Tool] methods
  2. Modeling — builds value-equatable models (incremental generator cache-friendly)
  3. Generation — emits a single .g.cs file per server with all dispatch, schema, OTel, and metadata code

Server Declaration

The class must be partial — the generator adds the IMcpServer implementation.

McpServer Attribute

Tool Attribute

Safety hints are emitted in tools/list only when non-Unset. ToolHint has three values: Unset (omitted), True, False. ToolTaskSupport controls whether a tool can return an MCP task instead of an immediate result:

Generated Output

For each [McpServer] class, the generator produces a single .g.cs file containing:

Tool Dispatch

A DispatchToolCallAsync method that routes by tool name using a switch expression:

Parameter Deserialization

Primitives use direct JsonElement accessors (AOT-safe). Complex types fall back to JsonSerializer.

JSON Schema

Each tool gets a static s_schema_{MethodName} byte array with the JSON Schema for its input parameters, including types, formats, required fields, descriptions, and enum values.

OpenTelemetry Instrumentation

Every tool call emits:
  • An ActivitySource("Qyl.Agents") span with gen_ai.* semantic conventions
  • A gen_ai.client.operation.duration histogram for latency tracking
  • Error status and error.type tag on exceptions

SKILL.md

A SkillMd static property with the full SKILL.md content including YAML frontmatter, tool descriptions, and parameter documentation.

LLMS.txt

A LlmsTxt static property with a summary of the server’s capabilities, including tools, resources, and prompts sections.

Resources

Expose read-only data via [Resource]:

Resource Attribute

The generator emits DispatchResourceReadAsync for URI-based dispatch and GetResourceInfos for resources/list. Supported return types for resource methods:

Prompts

Expose reusable prompt templates via [Prompt("name")]:
  • string return → wrapped as a single user-role message
  • PromptResult return → structured messages passed through directly
PromptMessage takes (string role, string content) via constructor. Use the PromptRole constants (User, Assistant, System) for type-safe role values. The generator emits DispatchPromptAsync and GetPromptInfos for prompts/list and prompts/get. Prompt methods must return string, Task<string>, PromptResult, or Task<PromptResult>.

Supported Parameter Types

Supported Return Types