build-clean-mcp-architecture
Use if structuring or auditing TypeScript mcp-use/server code for Clean Architecture boundaries.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use if structuring or auditing TypeScript mcp-use/server code for Clean Architecture boundaries.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Use skill if you are exhaustively testing or release-gating martool CLI commands in a source checkout or deployed Coolify container over SSH, without local Docker or provider spend.
Use if driving agent-browser for Chrome/CDP automation, @ref snapshots, tabs, or verification.
Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage.
Use if supervising Jean agents through MCP and Computer Use for monitoring, recovery, or closure.
Use if auditing or designing a CLI for agent/LLM use — JSON output, exit codes, non-interactive.
Use if auditing or designing an MCP server for agent-readiness — framework, security, context.
基于 SOC 职业分类
| name | build-clean-mcp-architecture |
| description | Use if structuring or auditing TypeScript mcp-use/server code for Clean Architecture boundaries. |
Architectural standard for TypeScript MCP servers built with mcp-use/server. Decides where files live, what each layer may import, what bootstrap wires, and how the discipline is enforced. Mechanical recipes (exact APIs, auth, transports, widgets) live in build-mcp-use-server.
Trigger on phrases or contexts like:
src/tools/*.ts into clean layers"dependency-cruiser for an mcp-use server"mcp-use imported from domain/ or application/?"mcp-use/server repo with proper folders"process.env is being read all over the codebase — fix the seam"Do NOT use this skill when:
@modelcontextprotocol/sdk server mechanic — use build-mcp-server-sdk-v1, build-mcp-server-sdk-v2, or convert-mcp-sdk-v1-to-v2.mcp-use/server API recipe (tool helpers, auth, sessions, transports, widgets, CSP, Inspector, deploy) — use build-mcp-use-server.MCPAgent — use build-mcp-use-client or build-mcp-use-agent.If the task is structural placement inside an mcp-use/server repo, this skill owns it. If it is a mechanical recipe outside of placement, route out.
| Decision | Default |
|---|---|
| Stack | TypeScript mcp-use/server |
| Composition root | src/infrastructure/server/bootstrap.ts (or equivalent entry wrapper) |
| Config seam | src/infrastructure/config/runtime-config.ts |
| Env validation | Zod, in the config seam only |
| Tool input validation | Zod at the handler boundary |
| Use-case validation | None; use cases trust validated commands |
| Boundary gate | dependency-cruiser plus TypeScript/lint |
| Logger sink | JSON to stderr, never stdout |
| Response seam | ToolResponse in domain, McpPresenter in presenters |
Pick exactly one mode before editing. If evidence contradicts the picked mode, name the contradiction once and continue with the mode that matches the codebase.
| Mode | Trigger | First action |
|---|---|---|
| Greenfield | No src/ yet, or only a package stub exists | Read references/greenfield-walkthrough.md. |
| Refactor | Existing server has monolithic tools, missing application layer, scattered env reads, or protocol imports in business logic | Read references/refactor-playbook.md. |
| Review | Existing repo or PR needs a structural grade | Read references/audit-checklist.md; report P0/P1/P2 findings. |
| Implementing | Clean layered repo needs a tool, resource, prompt, or boundary component | Read references/define-tool-pattern.md and references/handler-context.md. |
| Ask | Advice only, no edits | Answer with the mode and route to the relevant references below. |
These rules are absolute. When a hard external constraint blocks one, report the constraint and the smallest compensating boundary — do not silently weaken the rule.
domain/ imports nothing outside itself. application/ imports only domain/ and shared/.mcp-use or SDK types in domain/ or application/. SDK shape churn must not ripple into business logic.MCPServer, registers tools/resources/prompts, and starts the server.runtime-config.ts is the only file that reads process.env; env validates with Zod there.mcp-use imports stay at the protocol edge. Allowed: handlers/, resources/, prompts/, presenters/ (response helpers), and infrastructure/.z.any()/z.unknown() at tool boundaries; use cases and domain do not revalidate.any, as any, @ts-ignore, or unjustified @ts-expect-error.import type. verbatimModuleSyntax: true required.strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitOverride, noImplicitReturns, noFallthroughCasesInSwitch, verbatimModuleSyntax, NodeNext/Node16 module settings.console.* forbidden under src/; stdout is the JSON-RPC wire under stdio.DomainError subclasses before crossing a port.# private fields; private is acceptable only with equivalent lint and as any blocks.index.ts barrels inside src/ cause cycles and cold-start regressions.src/
├── domain/ # pure entities, ports, errors, ToolResponse
├── application/ # use cases and pure transforms
├── handlers/ # tool schemas, defineTool(), handler factories
├── gateways/ # outbound adapter implementations and decorators
├── presenters/ # ToolResponse -> MCP CallToolResult
├── infrastructure/ # config, middleware, errors, auth, observability, bootstrap
├── resources/ # MCP resources, including server-side widget resources
├── prompts/ # MCP prompts
└── shared/ # structural types and cross-cutting helpers
Full naming rules, rationale, and per-folder AGENTS.md guidance: references/folder-layout.md.
| Layer | May import from | Must not import |
|---|---|---|
domain/ | same layer only | mcp-use, SDK, Zod, I/O, any outer layer |
application/ | domain/, shared/ | protocol APIs, concrete gateways, handlers, presenters, infrastructure, env |
handlers/ | domain/, application/, presenter port, Zod, protocol-edge types | concrete gateways, config reads, direct provider calls |
gateways/ | domain ports/errors, shared types, provider SDKs | application, handlers, presenters, mcp-use |
presenters/ | domain response objects, response helpers, shared types | application, gateways, handlers |
infrastructure/ | all layers | reverse imports from inner layers |
resources/, prompts/ | domain, application, protocol-edge types | direct gateway construction, env |
shared/ | domain types only | side effects, business logic, framework imports |
Enforce as a CI-blocking gate; copy-paste config in references/dependency-rules.md.
| Primitive | Structural home (this skill) | Mechanical owner (route out) |
|---|---|---|
| Tool handler | handlers/<feature>/<tool>.handler.ts | build-mcp-use-server |
| Tool input schema | Inline in handler; shared fragments in handlers/schemas/ | build-mcp-use-server |
| Resource | resources/<resource>.ts or resources/<widget-name>/ | build-mcp-use-server |
| Prompt | prompts/registry.ts or prompts/<prompt>.ts | build-mcp-use-server |
| Response shaping | presenters/mcp-presenter.ts | build-mcp-use-server |
MCPServer construction | composition root only | build-mcp-use-server |
| Auth/session/transport wiring | infrastructure/ plus composition root | build-mcp-use-server |
ctx.elicit(), ctx.sample(), capability checks | handlers only | build-mcp-use-server |
Blended decisions split via references/coordinate-with-build-mcp-use-server.md.
MCP client
-> mcp-use server registered in bootstrap
-> handler parses schema and resolves request context
-> use case receives validated command and ports
-> gateway wraps external systems and classifies provider errors
-> use case returns ToolResponse or throws DomainError
-> presenter renders MCP response and sanitises output
-> mcp-use response returns to client
The handler is thin: parse, derive command, delegate, render. The use case is framework-free. The gateway hides providers. The presenter shapes data and redacts; it does not make business decisions.
Detect these before deep reading:
mcp-use imported from domain/, application/, gateways/, or shared/.process.env outside infrastructure/config/runtime-config.ts.server.tool( outside the composition root.src/tools/*.ts.new *Gateway(...) outside bootstrap.z.any() / z.unknown() in handler schemas.console.* under src/.index.ts barrels under application code.After the sweep, look up concrete examples and fix paths in references/anti-patterns.md.
Minimum gates for structural work:
python3 scripts/validate-skills.py when editing this skills pack.dependency-cruiser import-boundary gate.Bundled read-only audit helpers (run from the target MCP project root, or pass the project root as the first argument):
| Need | Script | Doc |
|---|---|---|
| Grep likely layer-import, env, console, and barrel violations | scripts/audit-layer-imports.sh | scripts/audit-layer-imports.md |
| Check canonical folders and expected seams | scripts/check-folder-layout.sh | scripts/check-folder-layout.md |
| Check likely Zod boundary violations | scripts/check-zod-boundary.sh | scripts/check-zod-boundary.md |
Claim only the verification rung actually reached.
Finish apply/review/refactor work with:
For Review mode, lead with findings ordered by severity and include replayable evidence.
| Read when | Reference | Decision it answers |
|---|---|---|
Need full tree, naming rules, folder rationale, or per-folder AGENTS.md guidance | references/folder-layout.md | Which folder owns a file and why it exists. |
Need copy-paste import rules or dependency-cruiser config | references/dependency-rules.md | Which imports are legal and how CI enforces them. |
| Need the single-root construction order or bootstrap skeleton | references/composition-root.md | What constructs where and in what order. |
| Designing or auditing ports, gateways, decorators, or provider error classification | references/gateways-and-ports.md | How external systems cross into the application. |
| Building response objects, presenters, sanitisation, or preview policy | references/presenter-and-tool-response.md | How domain responses become MCP envelopes. |
| Adding request identity, session id, request id, or cost tracking | references/request-context.md | What belongs in AsyncLocalStorage and how it is bound. |
Designing DomainError, JSON-RPC mapping, or recovery hints | references/error-contracts.md | How failures move from domain/gateway to MCP response. |
| Adding or auditing a tool handler factory | references/define-tool-pattern.md | What defineTool() returns and how handlers stay thin. |
| Designing handler dependency injection or capability-gated edge behavior | references/handler-context.md | What belongs in HandlerContext versus per-request MCP context. |
Splitting structural and mechanical ownership with build-mcp-use-server | references/coordinate-with-build-mcp-use-server.md | Which skill owns a blended decision. |
Checking TypeScript compiler flags, import type, branded IDs, or structural SDK mirrors | references/typescript-quality-bar.md | What the TypeScript gate requires. |
| Placing Zod schemas or auditing validation boundaries | references/zod-at-boundary.md | Where schemas live and where field mechanics route out. |
Narrowing unknown, generic port signatures, discriminated unions, or satisfies records | references/narrowing-and-generics.md | How types stay precise without any. |
| Applying Clean Code rules that materially affect MCP behavior | references/clean-code-rules-in-mcp-context.md | Which hygiene rules matter and why. |
Starting a new mcp-use/server repo from scratch | references/greenfield-walkthrough.md | Step-by-step scaffold and gates. |
| Repairing an existing drifted repo | references/refactor-playbook.md | The staged PR sequence and rollback path. |
| Reviewing an existing repo or PR | references/audit-checklist.md | P0/P1/P2 audit rubric and report shape. |
| Looking up concrete drift examples and fix paths | references/anti-patterns.md | How common violations appear and how to detect them. |