|
| 1 | +# AGENTS.md — AI Agent Instructions for dotnet-template-mcp |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +MCP server wrapping the .NET Template Engine for AI-driven template discovery, inspection, and instantiation. Ships as a dotnet tool (`DotnetTemplateMCP`) on NuGet. |
| 6 | + |
| 7 | +## Build & Test |
| 8 | + |
| 9 | +```bash |
| 10 | +dotnet build |
| 11 | +dotnet test |
| 12 | +``` |
| 13 | + |
| 14 | +- Targets **net10.0** (see `global.json` for SDK version). |
| 15 | +- Uses **Central Package Management** — all versions in `Directory.Packages.props`. |
| 16 | +- CI runs on **ubuntu-latest** and **windows-latest** (see `.github/workflows/ci.yml`). |
| 17 | +- When the MCP server is running locally (e.g., as a tool provider), `dotnet build` may fail with a file lock on `bin/Debug/net10.0/Microsoft.TemplateEngine.MCP.exe`. Use `-o <tempdir>` to build to an alternate output path. |
| 18 | + |
| 19 | +## Architecture |
| 20 | + |
| 21 | +### Tool Registration Pattern |
| 22 | + |
| 23 | +Each MCP tool is a `static async` method in a sealed class under `src/Microsoft.TemplateEngine.MCP/Tools/`: |
| 24 | + |
| 25 | +```csharp |
| 26 | +[McpServerToolType] |
| 27 | +internal sealed class MyTool |
| 28 | +{ |
| 29 | + [McpServerTool(Name = "tool_name")] |
| 30 | + [Description("Description shown to AI agents — lead with the pain point, not the feature name.")] |
| 31 | + public static async Task<string> MyMethodAsync( |
| 32 | + TemplateEngineService engineService, // DI-injected service |
| 33 | + McpFeatureFlags featureFlags, // DI-injected feature flags |
| 34 | + [Description("...")] string param1, // User-facing params with [Description] |
| 35 | + CancellationToken cancellationToken = default) |
| 36 | + { |
| 37 | + // 1. Telemetry |
| 38 | + using var activity = McpTelemetry.StartToolActivity("tool_name"); |
| 39 | + var sw = Stopwatch.StartNew(); |
| 40 | + try |
| 41 | + { |
| 42 | + // 2. Profile check (for non-lite tools) |
| 43 | + if (!featureFlags.IsToolEnabled("tool_name")) |
| 44 | + { |
| 45 | + return ToolProfileResponse.DisabledMessage("tool_name", "Hint for the user."); |
| 46 | + } |
| 47 | + |
| 48 | + // 3. Tool logic |
| 49 | + // ... |
| 50 | + } |
| 51 | + finally |
| 52 | + { |
| 53 | + McpTelemetry.RecordDuration("tool_name", sw.Elapsed.TotalMilliseconds); |
| 54 | + } |
| 55 | + } |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +### Key Rules |
| 60 | + |
| 61 | +1. **DI parameters come first** — `TemplateEngineService`, `McpFeatureFlags`, `McpServer` (if elicitation is needed) are injected by the MCP framework. User-facing parameters follow, each with a `[Description]` attribute. |
| 62 | + |
| 63 | +2. **When you add or change a DI parameter on a tool method, you MUST update all test call sites.** Tests in `test/Microsoft.TemplateEngine.MCP.Tests/` call tool methods directly (not through DI), so they must pass all parameters explicitly. Example: `new McpFeatureFlags()` for the default (Full profile). |
| 64 | + |
| 65 | +3. **Tool profiles** — Tools are either "lite" (5 core tools always available) or "full" (all tools). Non-lite tools must include a `featureFlags.IsToolEnabled()` check at the start. The lite tools are: `template_from_intent`, `template_instantiate`, `template_inspect`, `template_search`, `template_dry_run`. |
| 66 | + |
| 67 | +4. **Telemetry** — Every tool must call `McpTelemetry.StartToolActivity()` and `McpTelemetry.RecordDuration()`. Use `McpTelemetry.RecordError()` for failures. |
| 68 | + |
| 69 | +5. **Return format** — Tools return JSON strings via `JsonSerializer.Serialize(new { ... }, new JsonSerializerOptions { WriteIndented = true })`. Errors use `{ error, hint }` shape. |
| 70 | + |
| 71 | +6. **File header** — Every `.cs` file starts with: |
| 72 | + ```csharp |
| 73 | + // Licensed to the .NET Foundation under one or more agreements. |
| 74 | + // The .NET Foundation licenses this file to you under the MIT license. |
| 75 | + ``` |
| 76 | + |
| 77 | +## PR Workflow |
| 78 | + |
| 79 | +1. **Always create PRs on a feature branch**, not directly to `main`. |
| 80 | +2. **After pushing, monitor the CI run** — check GitHub Actions status. If build or tests fail, fix and push again before considering the PR ready. |
| 81 | +3. **Version bumps** require updating three files: `Microsoft.TemplateEngine.MCP.csproj` (`<Version>`), `server.json` (both `version` fields), and `README.md` (install commands). |
| 82 | + |
| 83 | +## Testing |
| 84 | + |
| 85 | +- Unit tests use **xUnit** + **FakeItEasy** for mocking. |
| 86 | +- `TemplateEngineService` is mocked via `A.Fake<TemplateEngineService>()` in unit tests. |
| 87 | +- Integration tests (in `IntegrationTests.cs`, `EndToEndTests.cs`) use a real template engine instance. |
| 88 | +- Test naming: `MethodName_Scenario_ExpectedBehavior`. |
| 89 | + |
| 90 | +## Key Files |
| 91 | + |
| 92 | +| File | Purpose | |
| 93 | +|------|---------| |
| 94 | +| `src/.../McpFeatureFlags.cs` | Environment-based feature flags (transport, profiles, elicitation) | |
| 95 | +| `src/.../Tools/ToolProfileResponse.cs` | Consistent "tool disabled" JSON responses | |
| 96 | +| `src/.../Host/TemplateEngineService.cs` | Core service wrapping the template engine | |
| 97 | +| `src/.../Telemetry/McpTelemetry.cs` | ActivitySource + Meter for observability | |
| 98 | +| `server.json` | MCP Registry manifest | |
| 99 | +| `.github/copilot-instructions.md` | Instructions for AI agents *using* this tool (not developing it) | |
0 commit comments