@polymorphism-tech/morph-spec 7.9.4 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.md +31 -2
  3. package/bin/morph-spec.js +50 -2
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +38 -1
  7. package/docs/QUICKSTART.md +60 -1
  8. package/framework/CLAUDE.md +14 -3
  9. package/framework/MORPH.md +41 -5
  10. package/framework/agents.json +22 -3
  11. package/framework/commands/commit.md +166 -166
  12. package/framework/commands/morph-hotfix.md +39 -0
  13. package/framework/commands/morph-infra.md +215 -215
  14. package/framework/commands/morph-preflight.md +205 -205
  15. package/framework/commands/morph-troubleshoot.md +124 -124
  16. package/framework/hooks/README.md +25 -11
  17. package/framework/hooks/claude-code/core/gate-guard.js +4 -2
  18. package/framework/hooks/claude-code/core/loop-detect.js +2 -1
  19. package/framework/hooks/claude-code/core/post-edit-typecheck.js +14 -5
  20. package/framework/hooks/claude-code/core/tasks-json-guard.js +4 -2
  21. package/framework/hooks/claude-code/core/validate-completion.js +1 -1
  22. package/framework/hooks/claude-code/core/worktree-context.js +160 -0
  23. package/framework/hooks/claude-code/statusline.py +679 -679
  24. package/framework/hooks/claude-code/statusline.sh +11 -11
  25. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  26. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  27. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  28. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  29. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  30. package/framework/hooks/shared/activity-logger.js +160 -160
  31. package/framework/hooks/shared/build-check.js +2 -2
  32. package/framework/hooks/shared/hook-response.js +17 -5
  33. package/framework/hooks/shared/payload-utils.js +42 -0
  34. package/framework/hooks/shared/state-reader.js +22 -2
  35. package/framework/hooks/shared/stdin-reader.js +26 -26
  36. package/framework/rubrics/backend.json +41 -41
  37. package/framework/rules/ai-agents-standards.md +45 -45
  38. package/framework/rules/dotnet-templates.md +86 -86
  39. package/framework/rules/frontend-standards.md +13 -13
  40. package/framework/rules/infrastructure-standards.md +27 -27
  41. package/framework/rules/neon-standards.md +25 -25
  42. package/framework/rules/nextjs-standards.md +20 -20
  43. package/framework/rules/nextjs-templates.md +40 -40
  44. package/framework/schemas/feature.schema.json +95 -1
  45. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  46. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  47. package/framework/skills/core/morph-apply/SKILL.md +49 -27
  48. package/framework/skills/core/morph-brainstorming/SKILL.md +9 -1
  49. package/framework/skills/core/morph-eval/SKILL.md +6 -1
  50. package/framework/skills/core/morph-hotfix/SKILL.md +134 -0
  51. package/framework/skills/core/morph-implement/SKILL.md +17 -22
  52. package/framework/skills/core/morph-plan/SKILL.md +5 -1
  53. package/framework/skills/core/morph-proposal/SKILL.md +24 -1
  54. package/framework/skills/core/morph-review/SKILL.md +13 -16
  55. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  56. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  57. package/framework/standards/ai-agents/agent-session.md +160 -160
  58. package/framework/standards/ai-agents/batching.md +193 -193
  59. package/framework/standards/ai-agents/context-providers.md +188 -188
  60. package/framework/standards/ai-agents/mcp-server.md +250 -250
  61. package/framework/standards/ai-agents/mcp-tools.md +197 -197
  62. package/framework/standards/ai-agents/middleware-patterns.md +207 -207
  63. package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
  64. package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
  65. package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
  66. package/framework/standards/ai-agents/modalities-vision.md +201 -201
  67. package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
  68. package/framework/standards/ai-agents/production.md +275 -275
  69. package/framework/standards/ai-agents/prompts-in-db.md +214 -214
  70. package/framework/standards/ai-agents/providers/model-registry.md +158 -158
  71. package/framework/standards/ai-agents/service-tier-flex.md +135 -135
  72. package/framework/standards/ai-agents/structured-output.md +249 -249
  73. package/framework/standards/ai-agents/sweet-spot.md +109 -109
  74. package/framework/templates/.idea/morph-templates.xml +92 -0
  75. package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  76. package/framework/templates/IDE-SNIPPETS.md +262 -262
  77. package/framework/templates/REGISTRY.json +0 -62
  78. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  79. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  80. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  81. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  82. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  83. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  84. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  85. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  86. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  87. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  88. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  89. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  90. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  91. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  92. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  93. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  94. package/framework/templates/code/typescript/contracts.ts +167 -167
  95. package/framework/templates/docs/clarifications.md +253 -253
  96. package/framework/templates/docs/schema-analysis.md +119 -119
  97. package/framework/templates/docs/ui-components.md +52 -52
  98. package/framework/templates/docs/ui-design-system.md +76 -76
  99. package/framework/templates/docs/ui-flows.md +167 -167
  100. package/framework/templates/docs/ui-mockups.md +98 -98
  101. package/framework/templates/feature/decisions.md +122 -122
  102. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  103. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  104. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  105. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  106. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  107. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  108. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  109. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  110. package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
  111. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  112. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  113. package/framework/templates/infrastructure/github/README.md +56 -56
  114. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  115. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  116. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  117. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  118. package/framework/templates/integrations/asaas-client.cs +387 -387
  119. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  120. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  121. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  122. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  123. package/framework/templates/project/validate.js +120 -120
  124. package/framework/templates/state.template.json +17 -17
  125. package/framework/templates/ui/design-system.css +226 -226
  126. package/package.json +1 -1
  127. package/src/commands/dashboard/dashboard.js +53 -53
  128. package/src/commands/index.js +13 -13
  129. package/src/commands/mcp/mcp-setup.js +519 -519
  130. package/src/commands/project/checkpoint.js +209 -209
  131. package/src/commands/project/doctor.js +4 -2
  132. package/src/commands/project/init.js +46 -2
  133. package/src/commands/project/update.js +5 -3
  134. package/src/commands/project/worktree.js +1005 -46
  135. package/src/commands/state/advance.js +17 -2
  136. package/src/commands/state/approve.js +18 -1
  137. package/src/commands/state/create.js +158 -14
  138. package/src/commands/state/retype.js +126 -0
  139. package/src/commands/state/score.js +4 -0
  140. package/src/commands/tasks/dag.js +32 -0
  141. package/src/commands/validation/index.js +1 -0
  142. package/src/commands/validation/validate-feature.js +33 -5
  143. package/src/commands/validation/verify.js +190 -0
  144. package/src/core/state/phase-state-machine.js +197 -197
  145. package/src/core/state/state-manager.js +35 -10
  146. package/src/core/templates/template-renderer.js +477 -477
  147. package/src/core/work-types.js +79 -0
  148. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  149. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  150. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  151. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  152. package/src/dashboard/app/main.jsx +13 -13
  153. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  154. package/src/dashboard/app/pages/HookInspector.jsx +418 -418
  155. package/src/dashboard/app/pages/LiveState.jsx +11 -1
  156. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  157. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  158. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  159. package/src/dashboard/app/pages/Standards.jsx +332 -332
  160. package/src/dashboard/app/styles/index.css +47 -47
  161. package/src/dashboard/index.html +12 -12
  162. package/src/dashboard/package.json +24 -24
  163. package/src/dashboard/scanner/hooks-scanner.js +41 -41
  164. package/src/dashboard/scanner/phases-scanner.js +15 -15
  165. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  166. package/src/dashboard/scanner/rules-scanner.js +37 -37
  167. package/src/dashboard/scanner/skills-scanner.js +43 -43
  168. package/src/dashboard/scanner/squads-scanner.js +13 -13
  169. package/src/dashboard/scanner/standards-scanner.js +26 -26
  170. package/src/dashboard/scanner/state-scanner.js +42 -0
  171. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  172. package/src/dashboard/vite.config.js +24 -24
  173. package/src/lib/agents/metrics-aggregator.js +56 -56
  174. package/src/lib/agents/metrics-calculator.js +125 -125
  175. package/src/lib/agents/output-collector.js +73 -73
  176. package/src/lib/detectors/claude-config-detector.js +152 -152
  177. package/src/lib/detectors/design-system-detector.js +231 -231
  178. package/src/lib/detectors/index.js +217 -217
  179. package/src/lib/generators/architecture-scanner.js +639 -639
  180. package/src/lib/generators/design-system-generator.js +508 -508
  181. package/src/lib/generators/index.js +13 -13
  182. package/src/lib/generators/settings-generator.js +209 -209
  183. package/src/lib/hooks/hook-executor.js +167 -167
  184. package/src/lib/installers/mcp-installer.js +719 -719
  185. package/src/lib/installers/memory-installer.js +1 -1
  186. package/src/lib/risk-detector.js +16 -0
  187. package/src/lib/tasks/dispatch-planner.js +122 -4
  188. package/src/lib/tasks/mermaid-renderer.js +132 -0
  189. package/src/lib/tasks/task-classifier.js +30 -30
  190. package/src/lib/tasks/task-parser.js +209 -209
  191. package/src/lib/tasks/test-runner.js +27 -6
  192. package/src/lib/validators/architecture/architecture-validator.js +259 -259
  193. package/src/lib/validators/checkpoint-persistence.js +39 -39
  194. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
  195. package/src/lib/validators/css/css-validator.js +340 -340
  196. package/src/lib/validators/packages/package-validator.js +347 -347
  197. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  198. package/src/lib/validators/shared/issue-counter.js +14 -14
  199. package/src/lib/validators/validation-runner.js +349 -349
  200. package/src/lib/validators/verify-runner.js +322 -0
  201. package/src/lib/work-type-detector.js +143 -0
  202. package/src/scripts/setup-infra.js +32 -5
  203. package/src/utils/agent-id-mapper.js +11 -11
  204. package/src/utils/agents-installer.js +10 -6
  205. package/src/utils/claude-settings-manager.js +300 -300
  206. package/src/utils/file-copier.js +43 -0
  207. package/src/utils/hooks-installer.js +43 -34
  208. package/src/utils/skills-installer.js +174 -174
  209. package/framework/hooks/claude-code/core/subagent-report-guard.js +0 -95
  210. package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  211. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  212. package/src/lib/tasks/wave-resolver.js +0 -353
@@ -1,250 +1,250 @@
1
- # MCP Server — Exposing project capabilities as MCP
2
-
3
- > **Scope:** stacks=["dotnet"]
4
- > **Layer:** 2 (on-keyword)
5
- > **Keywords:** mcp server, expose mcp, build mcp server, mcp host, publish tools, McpServerTool, AddMcpServer
6
- > **Read by Claude in:** implement (quando um projeto expõe capacidades como MCP server para consumo externo)
7
-
8
- **Verified against:** MAF 1.0 GA + ModelContextProtocol C# SDK server-side (`[McpServerToolType]`/`[McpServerTool]`, `WithStdioServerTransport`/`WithHttpTransport`, `ModelContextProtocol.AspNetCore`). Last-verified: 2026-05-19.
9
-
10
- ---
11
-
12
- ## Quando criar um MCP server
13
-
14
- Crie um MCP server quando você quer **expor capacidades do projeto** de forma padronizada para **agentes ou ferramentas externas** consumirem. O protocolo MCP garante interoperabilidade: qualquer agente compatível (Claude Code, outro agent MAF, VS Code Copilot, etc.) pode descobrir e usar as tools do servidor.
15
-
16
- **Crie um MCP server quando:**
17
-
18
- - Claude Code (ou outro agente externo) precisa executar queries/ações neste projeto
19
- - Outro projeto MAF precisa consumir lógica encapsulada aqui via protocolo padrão
20
- - Você quer expor capacidades de negócio de forma descobrível via `ListTools`
21
- - O projeto é um serviço de infraestrutura que deve ser consumível cross-framework
22
-
23
- **NÃO crie um MCP server quando:**
24
-
25
- - As tools são usadas apenas pelos agentes do próprio projeto → use tools nativas `[Description]`
26
- - É uma lógica de um único endpoint interno → `AIFunctionFactory.Create()` é suficiente
27
- - A integração é ponto-a-ponto com um único consumidor → DI direta ou A2A é mais simples
28
-
29
- ---
30
-
31
- ## A API
32
-
33
- **Packages:**
34
-
35
- ```xml
36
- <!-- SDK cliente+servidor do protocolo MCP -->
37
- <PackageReference Include="ModelContextProtocol" Version="0.1.*" />
38
-
39
- <!-- Pacote base MAF (para AsAIAgent, AsAIFunction) -->
40
- <PackageReference Include="Microsoft.Agents.AI" Version="1.0.*" />
41
-
42
- <!-- Apenas se o transporte for HTTP (server-side) -->
43
- <PackageReference Include="ModelContextProtocol.AspNetCore" Version="0.1.*" />
44
- ```
45
-
46
- > `ModelContextProtocol` versão 0.1.* (preview) — GA previsto. Verifique versão corrente no NuGet antes de travar.
47
-
48
- **Dois jeitos de declarar tools:**
49
-
50
- | Padrão | Quando usar |
51
- |--------|-------------|
52
- | Atributos `[McpServerToolType]` + `[McpServerTool]` | Tools são métodos estáticos do projeto — padrão canônico do SDK. Descoberta automática via `WithToolsFromAssembly()`. |
53
- | `McpServerTool.Create(...)` | Embrulhar um agente MAF (`agent.AsAIFunction()`) ou um `AIFunction` construído em runtime como tool. |
54
-
55
- **Padrão de servidor (stdio):**
56
-
57
- ```
58
- Tools ([McpServerTool] ou McpServerTool.Create)
59
- → services.AddMcpServer() // registra o servidor
60
- → .WithStdioServerTransport() // transporte: stdio (Claude Code, subprocesso)
61
- → .WithToolsFromAssembly() // descobre [McpServerTool] no assembly
62
- ou .WithTools([tool]) // registra tools criadas em runtime
63
- → Host.Build().RunAsync() // sobe o servidor
64
- ```
65
-
66
- **Transport stdio** é o padrão para servidores locais (subprocessos, Claude Code tools). **HTTP server-side** usa o pacote `ModelContextProtocol.AspNetCore`: troque `WithStdioServerTransport()` por `WithHttpTransport(o => o.Stateless = true)` e exponha o endpoint com `app.MapMcp()` num `WebApplication`.
67
-
68
- ---
69
-
70
- ## Exemplo C# — tools por atributo (stdio)
71
-
72
- Padrão canônico: tools são métodos estáticos decorados, descobertos por assembly.
73
-
74
- ```csharp
75
- using System.ComponentModel;
76
- using Microsoft.Extensions.DependencyInjection;
77
- using Microsoft.Extensions.Hosting;
78
- using ModelContextProtocol.Server;
79
-
80
- HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
81
-
82
- builder.Services
83
- .AddMcpServer()
84
- .WithStdioServerTransport() // stdio: Claude Code / subprocesso
85
- .WithToolsFromAssembly(); // descobre [McpServerToolType] neste assembly
86
-
87
- await builder.Build().RunAsync();
88
-
89
- // ─── Tool exposta via atributo ──────────────────────────────────────────────
90
- [McpServerToolType]
91
- public static class OrderTools
92
- {
93
- [McpServerTool, Description("Returns the current status of an order given its ID")]
94
- public static async Task<string> GetOrderStatus(
95
- [Description("The order identifier")] string orderId,
96
- CancellationToken ct)
97
- {
98
- // Validação de input antes de qualquer I/O — ver seção Segurança
99
- if (string.IsNullOrWhiteSpace(orderId) || orderId.Length > 36)
100
- return "Error: invalid orderId format.";
101
-
102
- // lógica real do projeto aqui
103
- return $"Order {orderId}: Confirmed";
104
- }
105
- }
106
- ```
107
-
108
- > Tools por atributo podem ser instância (não-estáticas) — nesse caso o tipo é resolvido via DI,
109
- > permitindo injetar repositories/serviços no construtor. Métodos estáticos são o caso mais simples.
110
-
111
- ## Exemplo C# — agente MAF como tool (runtime)
112
-
113
- Quando a tool é um agente MAF, use `McpServerTool.Create` com `agent.AsAIFunction()`:
114
-
115
- ```csharp
116
- using Microsoft.Agents.AI;
117
- using Microsoft.Extensions.AI;
118
- using Microsoft.Extensions.DependencyInjection;
119
- using Microsoft.Extensions.Hosting;
120
- using ModelContextProtocol.Server;
121
-
122
- // _modelRegistry vem de ModelRegistry injetado (ai-agents-providers-model-registry)
123
- AIAgent queryAgent = _modelRegistry.GetChatClient("text-default")
124
- .AsAIAgent(
125
- instructions: "You answer questions about project data using the available tools.",
126
- name: "ProjectQueryAgent");
127
-
128
- McpServerTool agentTool = McpServerTool.Create(queryAgent.AsAIFunction());
129
-
130
- HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
131
-
132
- builder.Services
133
- .AddMcpServer()
134
- .WithStdioServerTransport()
135
- .WithTools([agentTool]); // tool criada em runtime → WithTools, não WithToolsFromAssembly
136
-
137
- await builder.Build().RunAsync();
138
- ```
139
-
140
- ## Exemplo C# — transport HTTP
141
-
142
- Para expor o MCP server via HTTP (consumível pela rede), use `ModelContextProtocol.AspNetCore`:
143
-
144
- ```csharp
145
- using ModelContextProtocol.Server;
146
-
147
- var builder = WebApplication.CreateBuilder(args);
148
-
149
- builder.Services
150
- .AddMcpServer()
151
- .WithHttpTransport(options => options.Stateless = true) // stateless: escalável
152
- .WithToolsFromAssembly();
153
-
154
- var app = builder.Build();
155
-
156
- app.MapMcp(); // expõe o endpoint MCP (Streamable HTTP)
157
- app.Run();
158
- ```
159
-
160
- > `Stateless = true` é recomendado para servidores que não precisam de requests server-to-client
161
- > (sampling/elicitation) — escala melhor e dispensa gestão de sessão. Para HTTP em produção,
162
- > proteja `MapMcp()` com autenticação — ver seção Segurança.
163
-
164
- **Registrar no Claude Code (`settings.json` do projeto consumidor):**
165
-
166
- ```json
167
- {
168
- "mcpServers": {
169
- "my-project-tools": {
170
- "command": "dotnet",
171
- "args": ["run", "--project", "src/MyProject.McpServer"]
172
- }
173
- }
174
- }
175
- ```
176
-
177
- ---
178
-
179
- ## Tool nativa vs MCP server exposto
180
-
181
- | Dimensão | Tool nativa (`[Description]`) | MCP server exposto |
182
- |----------|------------------------------|--------------------|
183
- | **Consumidor** | Agentes do próprio projeto | Agentes externos (Claude Code, outros projetos) |
184
- | **Protocolo** | Chamada direta em processo | Protocolo MCP (stdio ou HTTP) |
185
- | **Descoberta** | Registro manual no agente | `ListTools` — autodescoberta |
186
- | **Quando usar** | Lógica interna do projeto | Capacidades que cruzam fronteiras de projeto/processo |
187
- | **Overhead** | Zero | Processo separado, IPC via stdio/HTTP |
188
- | **Testabilidade** | Unitária com xUnit/nSubstitute | Requer host em execução ou mock do transport |
189
-
190
- **Regra**: se o único consumidor é um agente do próprio projeto → tool nativa. Se o consumidor é externo → MCP server.
191
-
192
- ---
193
-
194
- ## Segurança
195
-
196
- Um MCP server exposto é uma **superfície de ataque real** — qualquer agente com acesso ao transporte pode invocar suas tools.
197
-
198
- **Obrigatório antes de expor:**
199
-
200
- - **Validação de input:** valide todos os parâmetros recebidos (IDs, datas, strings livres) antes de executar lógica de negócio. MCP não valida tipos por você.
201
- - **Escopo mínimo:** exponha apenas as tools necessárias. Não exponha operações de escrita se o consumidor só lê.
202
- - **Autenticação (HTTP transport):** se usar HTTP, exija bearer token ou API key via header. stdio é implicitamente restrito ao processo pai.
203
- - **Nunca expor secrets via tools:** tools não devem retornar API keys, tokens, ou dados de configuração interna.
204
- - **Rate limiting:** se o MCP server for exposto via HTTP em produção, adicione rate limiting na camada de transporte (reverse proxy / middleware ASP.NET).
205
-
206
- A validação de input é mostrada inline no exemplo `GetOrderStatus` acima — valide IDs/datas/strings
207
- **antes de qualquer I/O** e devolva uma mensagem de erro descritiva (o consumidor é um LLM, que
208
- corrige o argumento na próxima iteração). Para tools por atributo que precisam de repositories,
209
- prefira o tipo de instância resolvido por DI a métodos estáticos com estado global.
210
-
211
- ---
212
-
213
- ## Anti-patterns
214
-
215
- | Anti-pattern | Problema | Solução |
216
- |-------------|---------|---------|
217
- | Criar MCP server para tools que só os agentes do próprio projeto usam | Overhead de processo + IPC sem benefício; mais difícil de testar | Tool nativa `[Description]` + `AIFunctionFactory.Create()` |
218
- | Expor tools sem validação de input | Agentes externos (ou alucinações de LLM) podem enviar dados malformados | Validar todos os parâmetros antes de qualquer I/O |
219
- | Tools sem escopo definido — expor tudo "por conveniência" | Superfície de ataque ampla; dificulta manutenção | Expor apenas o necessário; revisar a lista a cada release |
220
- | HTTP transport sem autenticação | Qualquer processo na rede pode invocar as tools | Bearer token / API key obrigatório em HTTP; stdio é suficiente para uso local |
221
- | Subir o MCP server no mesmo processo da aplicação principal | Acoplamento; falha no servidor MCP afeta a app | Projeto separado (`MyProject.McpServer`) com entrypoint próprio |
222
-
223
- ---
224
-
225
- ## Checklist (verifiable by morph-eval)
226
-
227
- - [ ] `ModelContextProtocol` e `Microsoft.Agents.AI` no `.csproj`; `ModelContextProtocol.AspNetCore` apenas se HTTP
228
- - [ ] Tools declaradas via `[McpServerToolType]` + `[McpServerTool]` (estáticas) ou `McpServerTool.Create(...)` (agente MAF / runtime)
229
- - [ ] `AddMcpServer()` com `WithStdioServerTransport()` (stdio) ou `WithHttpTransport(o => o.Stateless = true)` (HTTP)
230
- - [ ] `WithToolsFromAssembly()` para tools por atributo, ou `WithTools([...])` para tools de runtime
231
- - [ ] Entrypoint: `await builder.Build().RunAsync()` (stdio) ou `app.MapMcp(); app.Run()` (HTTP)
232
- - [ ] Agente criado via `_modelRegistry.GetChatClient("alias").AsAIAgent(...)` — provider-agnostic
233
- - [ ] Validação de input em todas as tools antes de executar lógica de negócio
234
- - [ ] Escopo mínimo: apenas tools necessárias para o consumidor externo
235
- - [ ] HTTP transport (se usado) protegido por autenticação
236
- - [ ] Nenhum `Guid.NewGuid()` — usar `Guid.CreateVersion7()` se IDs são necessários
237
-
238
- ---
239
-
240
- ## References
241
-
242
- - `ai-agents-setup` — pacotes base MAF, DI, quick start
243
- - `ai-agents-mcp-tools` — consumir MCP servers externos em um agente MAF
244
- - `ai-agents-production` — middleware pipeline, `ResilientToolMiddleware`, segurança
245
- - [ModelContextProtocol C# SDK](https://github.com/modelcontextprotocol/csharp-sdk)
246
- - [Expose Agent as MCP Server — MAF docs](https://learn.microsoft.com/en-us/agent-framework/agents/tools/local-mcp-tools)
247
-
248
- ---
249
-
250
- *MORPH-SPEC by Polymorphism Tech — ai-agents/mcp-server.md v1.0 (2026-05-19)*
1
+ # MCP Server — Exposing project capabilities as MCP
2
+
3
+ > **Scope:** stacks=["dotnet"]
4
+ > **Layer:** 2 (on-keyword)
5
+ > **Keywords:** mcp server, expose mcp, build mcp server, mcp host, publish tools, McpServerTool, AddMcpServer
6
+ > **Read by Claude in:** implement (quando um projeto expõe capacidades como MCP server para consumo externo)
7
+
8
+ **Verified against:** MAF 1.0 GA + ModelContextProtocol C# SDK server-side (`[McpServerToolType]`/`[McpServerTool]`, `WithStdioServerTransport`/`WithHttpTransport`, `ModelContextProtocol.AspNetCore`). Last-verified: 2026-05-19.
9
+
10
+ ---
11
+
12
+ ## Quando criar um MCP server
13
+
14
+ Crie um MCP server quando você quer **expor capacidades do projeto** de forma padronizada para **agentes ou ferramentas externas** consumirem. O protocolo MCP garante interoperabilidade: qualquer agente compatível (Claude Code, outro agent MAF, VS Code Copilot, etc.) pode descobrir e usar as tools do servidor.
15
+
16
+ **Crie um MCP server quando:**
17
+
18
+ - Claude Code (ou outro agente externo) precisa executar queries/ações neste projeto
19
+ - Outro projeto MAF precisa consumir lógica encapsulada aqui via protocolo padrão
20
+ - Você quer expor capacidades de negócio de forma descobrível via `ListTools`
21
+ - O projeto é um serviço de infraestrutura que deve ser consumível cross-framework
22
+
23
+ **NÃO crie um MCP server quando:**
24
+
25
+ - As tools são usadas apenas pelos agentes do próprio projeto → use tools nativas `[Description]`
26
+ - É uma lógica de um único endpoint interno → `AIFunctionFactory.Create()` é suficiente
27
+ - A integração é ponto-a-ponto com um único consumidor → DI direta ou A2A é mais simples
28
+
29
+ ---
30
+
31
+ ## A API
32
+
33
+ **Packages:**
34
+
35
+ ```xml
36
+ <!-- SDK cliente+servidor do protocolo MCP -->
37
+ <PackageReference Include="ModelContextProtocol" Version="0.1.*" />
38
+
39
+ <!-- Pacote base MAF (para AsAIAgent, AsAIFunction) -->
40
+ <PackageReference Include="Microsoft.Agents.AI" Version="1.0.*" />
41
+
42
+ <!-- Apenas se o transporte for HTTP (server-side) -->
43
+ <PackageReference Include="ModelContextProtocol.AspNetCore" Version="0.1.*" />
44
+ ```
45
+
46
+ > `ModelContextProtocol` versão 0.1.* (preview) — GA previsto. Verifique versão corrente no NuGet antes de travar.
47
+
48
+ **Dois jeitos de declarar tools:**
49
+
50
+ | Padrão | Quando usar |
51
+ |--------|-------------|
52
+ | Atributos `[McpServerToolType]` + `[McpServerTool]` | Tools são métodos estáticos do projeto — padrão canônico do SDK. Descoberta automática via `WithToolsFromAssembly()`. |
53
+ | `McpServerTool.Create(...)` | Embrulhar um agente MAF (`agent.AsAIFunction()`) ou um `AIFunction` construído em runtime como tool. |
54
+
55
+ **Padrão de servidor (stdio):**
56
+
57
+ ```
58
+ Tools ([McpServerTool] ou McpServerTool.Create)
59
+ → services.AddMcpServer() // registra o servidor
60
+ → .WithStdioServerTransport() // transporte: stdio (Claude Code, subprocesso)
61
+ → .WithToolsFromAssembly() // descobre [McpServerTool] no assembly
62
+ ou .WithTools([tool]) // registra tools criadas em runtime
63
+ → Host.Build().RunAsync() // sobe o servidor
64
+ ```
65
+
66
+ **Transport stdio** é o padrão para servidores locais (subprocessos, Claude Code tools). **HTTP server-side** usa o pacote `ModelContextProtocol.AspNetCore`: troque `WithStdioServerTransport()` por `WithHttpTransport(o => o.Stateless = true)` e exponha o endpoint com `app.MapMcp()` num `WebApplication`.
67
+
68
+ ---
69
+
70
+ ## Exemplo C# — tools por atributo (stdio)
71
+
72
+ Padrão canônico: tools são métodos estáticos decorados, descobertos por assembly.
73
+
74
+ ```csharp
75
+ using System.ComponentModel;
76
+ using Microsoft.Extensions.DependencyInjection;
77
+ using Microsoft.Extensions.Hosting;
78
+ using ModelContextProtocol.Server;
79
+
80
+ HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
81
+
82
+ builder.Services
83
+ .AddMcpServer()
84
+ .WithStdioServerTransport() // stdio: Claude Code / subprocesso
85
+ .WithToolsFromAssembly(); // descobre [McpServerToolType] neste assembly
86
+
87
+ await builder.Build().RunAsync();
88
+
89
+ // ─── Tool exposta via atributo ──────────────────────────────────────────────
90
+ [McpServerToolType]
91
+ public static class OrderTools
92
+ {
93
+ [McpServerTool, Description("Returns the current status of an order given its ID")]
94
+ public static async Task<string> GetOrderStatus(
95
+ [Description("The order identifier")] string orderId,
96
+ CancellationToken ct)
97
+ {
98
+ // Validação de input antes de qualquer I/O — ver seção Segurança
99
+ if (string.IsNullOrWhiteSpace(orderId) || orderId.Length > 36)
100
+ return "Error: invalid orderId format.";
101
+
102
+ // lógica real do projeto aqui
103
+ return $"Order {orderId}: Confirmed";
104
+ }
105
+ }
106
+ ```
107
+
108
+ > Tools por atributo podem ser instância (não-estáticas) — nesse caso o tipo é resolvido via DI,
109
+ > permitindo injetar repositories/serviços no construtor. Métodos estáticos são o caso mais simples.
110
+
111
+ ## Exemplo C# — agente MAF como tool (runtime)
112
+
113
+ Quando a tool é um agente MAF, use `McpServerTool.Create` com `agent.AsAIFunction()`:
114
+
115
+ ```csharp
116
+ using Microsoft.Agents.AI;
117
+ using Microsoft.Extensions.AI;
118
+ using Microsoft.Extensions.DependencyInjection;
119
+ using Microsoft.Extensions.Hosting;
120
+ using ModelContextProtocol.Server;
121
+
122
+ // _modelRegistry vem de ModelRegistry injetado (ai-agents-providers-model-registry)
123
+ AIAgent queryAgent = _modelRegistry.GetChatClient("text-default")
124
+ .AsAIAgent(
125
+ instructions: "You answer questions about project data using the available tools.",
126
+ name: "ProjectQueryAgent");
127
+
128
+ McpServerTool agentTool = McpServerTool.Create(queryAgent.AsAIFunction());
129
+
130
+ HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
131
+
132
+ builder.Services
133
+ .AddMcpServer()
134
+ .WithStdioServerTransport()
135
+ .WithTools([agentTool]); // tool criada em runtime → WithTools, não WithToolsFromAssembly
136
+
137
+ await builder.Build().RunAsync();
138
+ ```
139
+
140
+ ## Exemplo C# — transport HTTP
141
+
142
+ Para expor o MCP server via HTTP (consumível pela rede), use `ModelContextProtocol.AspNetCore`:
143
+
144
+ ```csharp
145
+ using ModelContextProtocol.Server;
146
+
147
+ var builder = WebApplication.CreateBuilder(args);
148
+
149
+ builder.Services
150
+ .AddMcpServer()
151
+ .WithHttpTransport(options => options.Stateless = true) // stateless: escalável
152
+ .WithToolsFromAssembly();
153
+
154
+ var app = builder.Build();
155
+
156
+ app.MapMcp(); // expõe o endpoint MCP (Streamable HTTP)
157
+ app.Run();
158
+ ```
159
+
160
+ > `Stateless = true` é recomendado para servidores que não precisam de requests server-to-client
161
+ > (sampling/elicitation) — escala melhor e dispensa gestão de sessão. Para HTTP em produção,
162
+ > proteja `MapMcp()` com autenticação — ver seção Segurança.
163
+
164
+ **Registrar no Claude Code (`settings.json` do projeto consumidor):**
165
+
166
+ ```json
167
+ {
168
+ "mcpServers": {
169
+ "my-project-tools": {
170
+ "command": "dotnet",
171
+ "args": ["run", "--project", "src/MyProject.McpServer"]
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Tool nativa vs MCP server exposto
180
+
181
+ | Dimensão | Tool nativa (`[Description]`) | MCP server exposto |
182
+ |----------|------------------------------|--------------------|
183
+ | **Consumidor** | Agentes do próprio projeto | Agentes externos (Claude Code, outros projetos) |
184
+ | **Protocolo** | Chamada direta em processo | Protocolo MCP (stdio ou HTTP) |
185
+ | **Descoberta** | Registro manual no agente | `ListTools` — autodescoberta |
186
+ | **Quando usar** | Lógica interna do projeto | Capacidades que cruzam fronteiras de projeto/processo |
187
+ | **Overhead** | Zero | Processo separado, IPC via stdio/HTTP |
188
+ | **Testabilidade** | Unitária com xUnit/nSubstitute | Requer host em execução ou mock do transport |
189
+
190
+ **Regra**: se o único consumidor é um agente do próprio projeto → tool nativa. Se o consumidor é externo → MCP server.
191
+
192
+ ---
193
+
194
+ ## Segurança
195
+
196
+ Um MCP server exposto é uma **superfície de ataque real** — qualquer agente com acesso ao transporte pode invocar suas tools.
197
+
198
+ **Obrigatório antes de expor:**
199
+
200
+ - **Validação de input:** valide todos os parâmetros recebidos (IDs, datas, strings livres) antes de executar lógica de negócio. MCP não valida tipos por você.
201
+ - **Escopo mínimo:** exponha apenas as tools necessárias. Não exponha operações de escrita se o consumidor só lê.
202
+ - **Autenticação (HTTP transport):** se usar HTTP, exija bearer token ou API key via header. stdio é implicitamente restrito ao processo pai.
203
+ - **Nunca expor secrets via tools:** tools não devem retornar API keys, tokens, ou dados de configuração interna.
204
+ - **Rate limiting:** se o MCP server for exposto via HTTP em produção, adicione rate limiting na camada de transporte (reverse proxy / middleware ASP.NET).
205
+
206
+ A validação de input é mostrada inline no exemplo `GetOrderStatus` acima — valide IDs/datas/strings
207
+ **antes de qualquer I/O** e devolva uma mensagem de erro descritiva (o consumidor é um LLM, que
208
+ corrige o argumento na próxima iteração). Para tools por atributo que precisam de repositories,
209
+ prefira o tipo de instância resolvido por DI a métodos estáticos com estado global.
210
+
211
+ ---
212
+
213
+ ## Anti-patterns
214
+
215
+ | Anti-pattern | Problema | Solução |
216
+ |-------------|---------|---------|
217
+ | Criar MCP server para tools que só os agentes do próprio projeto usam | Overhead de processo + IPC sem benefício; mais difícil de testar | Tool nativa `[Description]` + `AIFunctionFactory.Create()` |
218
+ | Expor tools sem validação de input | Agentes externos (ou alucinações de LLM) podem enviar dados malformados | Validar todos os parâmetros antes de qualquer I/O |
219
+ | Tools sem escopo definido — expor tudo "por conveniência" | Superfície de ataque ampla; dificulta manutenção | Expor apenas o necessário; revisar a lista a cada release |
220
+ | HTTP transport sem autenticação | Qualquer processo na rede pode invocar as tools | Bearer token / API key obrigatório em HTTP; stdio é suficiente para uso local |
221
+ | Subir o MCP server no mesmo processo da aplicação principal | Acoplamento; falha no servidor MCP afeta a app | Projeto separado (`MyProject.McpServer`) com entrypoint próprio |
222
+
223
+ ---
224
+
225
+ ## Checklist (verifiable by morph-eval)
226
+
227
+ - [ ] `ModelContextProtocol` e `Microsoft.Agents.AI` no `.csproj`; `ModelContextProtocol.AspNetCore` apenas se HTTP
228
+ - [ ] Tools declaradas via `[McpServerToolType]` + `[McpServerTool]` (estáticas) ou `McpServerTool.Create(...)` (agente MAF / runtime)
229
+ - [ ] `AddMcpServer()` com `WithStdioServerTransport()` (stdio) ou `WithHttpTransport(o => o.Stateless = true)` (HTTP)
230
+ - [ ] `WithToolsFromAssembly()` para tools por atributo, ou `WithTools([...])` para tools de runtime
231
+ - [ ] Entrypoint: `await builder.Build().RunAsync()` (stdio) ou `app.MapMcp(); app.Run()` (HTTP)
232
+ - [ ] Agente criado via `_modelRegistry.GetChatClient("alias").AsAIAgent(...)` — provider-agnostic
233
+ - [ ] Validação de input em todas as tools antes de executar lógica de negócio
234
+ - [ ] Escopo mínimo: apenas tools necessárias para o consumidor externo
235
+ - [ ] HTTP transport (se usado) protegido por autenticação
236
+ - [ ] Nenhum `Guid.NewGuid()` — usar `Guid.CreateVersion7()` se IDs são necessários
237
+
238
+ ---
239
+
240
+ ## References
241
+
242
+ - `ai-agents-setup` — pacotes base MAF, DI, quick start
243
+ - `ai-agents-mcp-tools` — consumir MCP servers externos em um agente MAF
244
+ - `ai-agents-production` — middleware pipeline, `ResilientToolMiddleware`, segurança
245
+ - [ModelContextProtocol C# SDK](https://github.com/modelcontextprotocol/csharp-sdk)
246
+ - [Expose Agent as MCP Server — MAF docs](https://learn.microsoft.com/en-us/agent-framework/agents/tools/local-mcp-tools)
247
+
248
+ ---
249
+
250
+ *MORPH-SPEC by Polymorphism Tech — ai-agents/mcp-server.md v1.0 (2026-05-19)*