@dewtech/dare-cli 3.3.0 → 3.4.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.
- package/LICENSE +21 -0
- package/README.md +764 -764
- package/dist/__tests__/confidence.test.js +13 -13
- package/dist/__tests__/dag-converter.test.js +56 -56
- package/dist/__tests__/mcp-server/server.test.js +3 -16
- package/dist/__tests__/mcp-server/server.test.js.map +1 -1
- package/dist/__tests__/project-generator.test.js +2 -2
- package/dist/__tests__/project-generator.test.js.map +1 -1
- package/dist/__tests__/refine.test.js +49 -49
- package/dist/__tests__/reverse-collection.test.js +6 -6
- package/dist/__tests__/review.test.js +38 -38
- package/dist/__tests__/security-hardening.test.d.ts +2 -0
- package/dist/__tests__/security-hardening.test.d.ts.map +1 -0
- package/dist/__tests__/security-hardening.test.js +101 -0
- package/dist/__tests__/security-hardening.test.js.map +1 -0
- package/dist/__tests__/validate.test.js +65 -65
- package/dist/bin/dare.js +0 -0
- package/dist/commands/__tests__/init-validation.test.d.ts +2 -0
- package/dist/commands/__tests__/init-validation.test.d.ts.map +1 -0
- package/dist/commands/__tests__/init-validation.test.js +81 -0
- package/dist/commands/__tests__/init-validation.test.js.map +1 -0
- package/dist/commands/__tests__/init.integration.spec.js +6 -4
- package/dist/commands/__tests__/init.integration.spec.js.map +1 -1
- package/dist/commands/__tests__/init.spec.d.ts +2 -0
- package/dist/commands/__tests__/init.spec.d.ts.map +1 -0
- package/dist/commands/__tests__/init.spec.js +88 -0
- package/dist/commands/__tests__/init.spec.js.map +1 -0
- package/dist/commands/blueprint.js +122 -122
- package/dist/commands/design.js +20 -20
- package/dist/commands/init-validation.d.ts +22 -0
- package/dist/commands/init-validation.d.ts.map +1 -0
- package/dist/commands/init-validation.js +54 -0
- package/dist/commands/init-validation.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +26 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/graphrag/graph-rag.js +24 -24
- package/dist/mcp-server/__tests__/auth.test.d.ts +2 -0
- package/dist/mcp-server/__tests__/auth.test.d.ts.map +1 -0
- package/dist/mcp-server/__tests__/auth.test.js +72 -0
- package/dist/mcp-server/__tests__/auth.test.js.map +1 -0
- package/dist/mcp-server/__tests__/boot-config.test.d.ts +2 -0
- package/dist/mcp-server/__tests__/boot-config.test.d.ts.map +1 -0
- package/dist/mcp-server/__tests__/boot-config.test.js +29 -0
- package/dist/mcp-server/__tests__/boot-config.test.js.map +1 -0
- package/dist/mcp-server/__tests__/error-sanitize.test.d.ts +2 -0
- package/dist/mcp-server/__tests__/error-sanitize.test.d.ts.map +1 -0
- package/dist/mcp-server/__tests__/error-sanitize.test.js +66 -0
- package/dist/mcp-server/__tests__/error-sanitize.test.js.map +1 -0
- package/dist/mcp-server/__tests__/path-confinement.test.d.ts +2 -0
- package/dist/mcp-server/__tests__/path-confinement.test.d.ts.map +1 -0
- package/dist/mcp-server/__tests__/path-confinement.test.js +135 -0
- package/dist/mcp-server/__tests__/path-confinement.test.js.map +1 -0
- package/dist/mcp-server/bin/server.js +18 -6
- package/dist/mcp-server/bin/server.js.map +1 -1
- package/dist/mcp-server/boot-config.d.ts +6 -0
- package/dist/mcp-server/boot-config.d.ts.map +1 -0
- package/dist/mcp-server/boot-config.js +17 -0
- package/dist/mcp-server/boot-config.js.map +1 -0
- package/dist/mcp-server/middleware/auth.d.ts +10 -0
- package/dist/mcp-server/middleware/auth.d.ts.map +1 -0
- package/dist/mcp-server/middleware/auth.js +44 -0
- package/dist/mcp-server/middleware/auth.js.map +1 -0
- package/dist/mcp-server/middleware/cors.d.ts +6 -0
- package/dist/mcp-server/middleware/cors.d.ts.map +1 -0
- package/dist/mcp-server/middleware/cors.js +30 -0
- package/dist/mcp-server/middleware/cors.js.map +1 -0
- package/dist/mcp-server/middleware/error-handler.d.ts +11 -0
- package/dist/mcp-server/middleware/error-handler.d.ts.map +1 -0
- package/dist/mcp-server/middleware/error-handler.js +14 -0
- package/dist/mcp-server/middleware/error-handler.js.map +1 -0
- package/dist/mcp-server/server.d.ts +7 -2
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +185 -105
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/skills/registry-mock.json +109 -109
- package/dist/skills/tests/manifest.spec.js +20 -20
- package/dist/stacks/__tests__/dna-emitter.spec.js +6 -6
- package/dist/stacks/dna-emitter.js +69 -69
- package/dist/stacks/ruby-rails-8/scaffold.js +15 -15
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +254 -252
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/stack-bootstrap.js +371 -371
- package/dist/utils/templates.js +394 -394
- package/dist/verification/__tests__/anti-tamper.test.js +13 -13
- package/package.json +96 -93
- package/templates/DARE-dag-example.yaml +280 -280
- package/templates/UPDATE-MANIFEST.json +68 -68
- package/templates/backend/node-nestjs/.env.example +9 -9
- package/templates/backend/node-nestjs/nest-cli.json +8 -8
- package/templates/backend/node-nestjs/package.json +50 -50
- package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
- package/templates/backend/node-nestjs/src/app.module.ts +15 -15
- package/templates/backend/node-nestjs/src/app.service.ts +8 -8
- package/templates/backend/node-nestjs/src/main.ts +24 -24
- package/templates/backend/node-nestjs/tsconfig.json +21 -21
- package/templates/backend/php-laravel/.env.example +22 -22
- package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
- package/templates/backend/php-laravel/composer.json +40 -40
- package/templates/backend/python-fastapi/.env.example +4 -4
- package/templates/backend/python-fastapi/app/api/router.py +8 -8
- package/templates/backend/python-fastapi/app/core/config.py +20 -20
- package/templates/backend/python-fastapi/main.py +35 -35
- package/templates/backend/python-fastapi/requirements.txt +13 -13
- package/templates/backend/rust-axum/.env.example +3 -3
- package/templates/backend/rust-axum/Cargo.toml +23 -23
- package/templates/backend/rust-axum/src/errors.rs +30 -30
- package/templates/backend/rust-axum/src/main.rs +32 -32
- package/templates/backend/rust-axum/src/routes.rs +6 -6
- package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
- package/templates/frontend/leptos-csr/Cargo.toml +16 -16
- package/templates/frontend/leptos-csr/Trunk.toml +10 -10
- package/templates/frontend/leptos-csr/index.html +11 -11
- package/templates/frontend/leptos-csr/src/lib.rs +20 -20
- package/templates/frontend/leptos-csr/style/main.scss +19 -19
- package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
- package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
- package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
- package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
- package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
- package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
- package/templates/frontend/react/index.html +12 -12
- package/templates/frontend/react/package.json +35 -35
- package/templates/frontend/react/src/App.tsx +25 -25
- package/templates/frontend/react/src/main.tsx +9 -9
- package/templates/frontend/vue/package.json +32 -32
- package/templates/frontend/vue/src/App.vue +7 -7
- package/templates/frontend/vue/src/main.ts +10 -10
- package/templates/frontend/vue/src/router/index.ts +14 -14
- package/templates/frontend/vue/src/views/HomeView.vue +6 -6
- package/templates/hooks/pre-commit-dare-validate +24 -24
- package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -152
- package/templates/ide/antigravity/.agents/skills/dare-bench/SKILL.md +21 -21
- package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +368 -368
- package/templates/ide/antigravity/.agents/skills/dare-bootstrap/SKILL.md +32 -32
- package/templates/ide/antigravity/.agents/skills/dare-bugfix-design/SKILL.md +76 -76
- package/templates/ide/antigravity/.agents/skills/dare-dag/SKILL.md +32 -32
- package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -154
- package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -130
- package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
- package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +180 -180
- package/templates/ide/antigravity/.agents/skills/dare-discover/SKILL.md +33 -33
- package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -63
- package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -315
- package/templates/ide/antigravity/.agents/skills/dare-execute/SKILL.md +264 -264
- package/templates/ide/antigravity/.agents/skills/dare-feature-design/SKILL.md +74 -74
- package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -192
- package/templates/ide/antigravity/.agents/skills/dare-graph/SKILL.md +35 -35
- package/templates/ide/antigravity/.agents/skills/dare-info/SKILL.md +31 -31
- package/templates/ide/antigravity/.agents/skills/dare-init/SKILL.md +35 -35
- package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -337
- package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -166
- package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -217
- package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -61
- package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -187
- package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -217
- package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -114
- package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -108
- package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -111
- package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -263
- package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
- package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -274
- package/templates/ide/antigravity/.agents/skills/dare-skill/SKILL.md +35 -35
- package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -265
- package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -188
- package/templates/ide/antigravity/.agents/skills/dare-update/SKILL.md +33 -33
- package/templates/ide/antigravity/.agents/skills/dare-validate/SKILL.md +33 -33
- package/templates/ide/antigravity/.agents/skills/dare-welcome/SKILL.md +30 -30
- package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -343
- package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -377
- package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -382
- package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -326
- package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -393
- package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
- package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -141
- package/templates/ide/antigravity/templates/TASKS-template.md +26 -26
- package/templates/ide/antigravity/templates/TELEMETRY-template.md +125 -125
- package/templates/ide/claude/.claude/commands/dare-ax.md +131 -131
- package/templates/ide/claude/.claude/commands/dare-bench.md +18 -18
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -134
- package/templates/ide/claude/.claude/commands/dare-bootstrap.md +27 -27
- package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -119
- package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -151
- package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
- package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -117
- package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
- package/templates/ide/claude/.claude/commands/dare-dag.md +27 -27
- package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
- package/templates/ide/claude/.claude/commands/dare-discover.md +28 -28
- package/templates/ide/claude/.claude/commands/dare-dna.md +75 -75
- package/templates/ide/claude/.claude/commands/dare-docker.md +207 -207
- package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
- package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -147
- package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -149
- package/templates/ide/claude/.claude/commands/dare-graph.md +30 -30
- package/templates/ide/claude/.claude/commands/dare-info.md +26 -26
- package/templates/ide/claude/.claude/commands/dare-init.md +30 -30
- package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -211
- package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -124
- package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -148
- package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -72
- package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -166
- package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -159
- package/templates/ide/claude/.claude/commands/dare-refine.md +145 -145
- package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -139
- package/templates/ide/claude/.claude/commands/dare-review.md +113 -113
- package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
- package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
- package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
- package/templates/ide/claude/.claude/commands/dare-skill.md +30 -30
- package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
- package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -132
- package/templates/ide/claude/.claude/commands/dare-update.md +28 -28
- package/templates/ide/claude/.claude/commands/dare-validate.md +28 -28
- package/templates/ide/claude/.claude/commands/dare-welcome.md +25 -25
- package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -205
- package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -232
- package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -228
- package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -210
- package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -236
- package/templates/ide/claude/.claude/settings.example.json +35 -35
- package/templates/ide/claude/CLAUDE.md +146 -146
- package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/claude/templates/DESIGN-template.md +129 -129
- package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -141
- package/templates/ide/claude/templates/TASKS-template.md +26 -26
- package/templates/ide/claude/templates/TELEMETRY-template.md +125 -125
- package/templates/ide/cursor/.cursor/commands/dare-bench.md +18 -18
- package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +86 -86
- package/templates/ide/cursor/.cursor/commands/dare-bootstrap.md +27 -27
- package/templates/ide/cursor/.cursor/commands/dare-bugfix-design.md +64 -64
- package/templates/ide/cursor/.cursor/commands/dare-dag-run.md +110 -110
- package/templates/ide/cursor/.cursor/commands/dare-dag-viz.md +139 -139
- package/templates/ide/cursor/.cursor/commands/dare-dag.md +27 -27
- package/templates/ide/cursor/.cursor/commands/dare-design.md +35 -35
- package/templates/ide/cursor/.cursor/commands/dare-discover.md +28 -28
- package/templates/ide/cursor/.cursor/commands/dare-dna.md +75 -75
- package/templates/ide/cursor/.cursor/commands/dare-docker-compose.md +18 -18
- package/templates/ide/cursor/.cursor/commands/dare-dockerfile.md +17 -17
- package/templates/ide/cursor/.cursor/commands/dare-execute.md +19 -19
- package/templates/ide/cursor/.cursor/commands/dare-feature-design.md +64 -64
- package/templates/ide/cursor/.cursor/commands/dare-graph.md +30 -30
- package/templates/ide/cursor/.cursor/commands/dare-info.md +26 -26
- package/templates/ide/cursor/.cursor/commands/dare-init.md +30 -30
- package/templates/ide/cursor/.cursor/commands/dare-migrate.md +72 -72
- package/templates/ide/cursor/.cursor/commands/dare-refine.md +107 -107
- package/templates/ide/cursor/.cursor/commands/dare-reverse.md +139 -139
- package/templates/ide/cursor/.cursor/commands/dare-review.md +91 -91
- package/templates/ide/cursor/.cursor/commands/dare-skill.md +30 -30
- package/templates/ide/cursor/.cursor/commands/dare-tasks.md +184 -184
- package/templates/ide/cursor/.cursor/commands/dare-telemetry.md +42 -42
- package/templates/ide/cursor/.cursor/commands/dare-update.md +28 -28
- package/templates/ide/cursor/.cursor/commands/dare-validate.md +28 -28
- package/templates/ide/cursor/.cursor/commands/dare-welcome.md +25 -25
- package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -263
- package/templates/ide/cursor/.cursor/rules/skill-bugfix-design.mdc +51 -51
- package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -173
- package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -134
- package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
- package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -63
- package/templates/ide/cursor/.cursor/rules/skill-docker.mdc +33 -33
- package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -352
- package/templates/ide/cursor/.cursor/rules/skill-feature-design.mdc +43 -43
- package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -244
- package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -371
- package/templates/ide/cursor/.cursor/rules/skill-laravel-api.mdc +44 -44
- package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -266
- package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -295
- package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -367
- package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -58
- package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -346
- package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -248
- package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -400
- package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -262
- package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -107
- package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -281
- package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
- package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
- package/templates/ide/cursor/.cursor/rules/skill-telemetry.mdc +156 -156
- package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
- package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -141
- package/templates/ide/cursor/templates/TASKS-template.md +26 -26
- package/templates/ide/cursor/templates/TELEMETRY-template.md +125 -125
- package/templates/shared/docker-compose.yml +41 -41
- package/templates/stacks/go-gin/.dare/skills.yml +11 -11
- package/templates/stacks/go-gin/.env.example +24 -24
- package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -42
- package/templates/stacks/go-gin/README.md.tpl +38 -38
- package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -78
- package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -2
- package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -12
- package/templates/stacks/go-gin/db/queries/users.sql +23 -23
- package/templates/stacks/go-gin/gitignore +7 -7
- package/templates/stacks/go-gin/go.mod.tpl +17 -17
- package/templates/stacks/go-gin/internal/config/config.go +41 -41
- package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -25
- package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -72
- package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -72
- package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -37
- package/templates/stacks/go-gin/internal/llm/dummy.go +14 -14
- package/templates/stacks/go-gin/internal/llm/provider.go +8 -8
- package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -58
- package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -55
- package/templates/stacks/go-gin/internal/model/user.go +17 -17
- package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -79
- package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -55
- package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -53
- package/templates/stacks/go-gin/llms.txt.tpl +54 -54
- package/templates/stacks/go-gin/openapi.json.tpl +46 -46
- package/templates/stacks/go-gin/sqlc.yaml +14 -14
- package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -22
- package/templates/stacks/go-stdlib/.dare/skills.yml +11 -11
- package/templates/stacks/go-stdlib/.env.example +24 -24
- package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -42
- package/templates/stacks/go-stdlib/README.md.tpl +41 -41
- package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -82
- package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -2
- package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -12
- package/templates/stacks/go-stdlib/db/queries/users.sql +23 -23
- package/templates/stacks/go-stdlib/gitignore +6 -6
- package/templates/stacks/go-stdlib/go.mod.tpl +15 -15
- package/templates/stacks/go-stdlib/internal/config/config.go +41 -41
- package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -24
- package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -71
- package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -84
- package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -36
- package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -32
- package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -14
- package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -8
- package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -21
- package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -27
- package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -51
- package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -81
- package/templates/stacks/go-stdlib/internal/model/user.go +17 -17
- package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -75
- package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -55
- package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -53
- package/templates/stacks/go-stdlib/llms.txt.tpl +60 -60
- package/templates/stacks/go-stdlib/openapi.json.tpl +46 -46
- package/templates/stacks/go-stdlib/sqlc.yaml +14 -14
- package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -45
- package/templates/stacks/mcp-go/.dare/skills.yml +8 -8
- package/templates/stacks/mcp-go/.env.example +14 -14
- package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -42
- package/templates/stacks/mcp-go/README.md.tpl +50 -50
- package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -62
- package/templates/stacks/mcp-go/gitignore +6 -6
- package/templates/stacks/mcp-go/go.mod.tpl +9 -9
- package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -9
- package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -80
- package/templates/stacks/mcp-go/internal/tools/echo.go +15 -15
- package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -21
- package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -17
- package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -14
- package/templates/stacks/mcp-go/llms.txt.tpl +60 -60
- package/templates/stacks/mcp-go/openapi.json.tpl +31 -31
- package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -37
- package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -8
- package/templates/stacks/mcp-node-ts/.env.example +16 -16
- package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -54
- package/templates/stacks/mcp-node-ts/README.md.hbs +49 -49
- package/templates/stacks/mcp-node-ts/gitignore +7 -7
- package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -61
- package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -39
- package/templates/stacks/mcp-node-ts/package.json.hbs +35 -35
- package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -71
- package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -36
- package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -45
- package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -23
- package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -18
- package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -68
- package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -58
- package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -5
- package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -50
- package/templates/stacks/mcp-node-ts/tsconfig.json +17 -17
- package/templates/stacks/mcp-python/.dare/skills.yml +8 -8
- package/templates/stacks/mcp-python/.env.example +14 -14
- package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -42
- package/templates/stacks/mcp-python/README.md.j2 +49 -49
- package/templates/stacks/mcp-python/gitignore +12 -12
- package/templates/stacks/mcp-python/llms.txt.j2 +56 -56
- package/templates/stacks/mcp-python/openapi.json.j2 +33 -33
- package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -37
- package/templates/stacks/mcp-python/src/cli.py.j2 +68 -68
- package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -10
- package/templates/stacks/mcp-python/src/server.py.j2 +28 -28
- package/templates/stacks/mcp-python/src/tools/echo.py +12 -12
- package/templates/stacks/mcp-python/src/transports/http.py +12 -12
- package/templates/stacks/mcp-python/src/transports/sse.py +13 -13
- package/templates/stacks/mcp-python/src/transports/stdio.py +6 -6
- package/templates/stacks/mcp-python/tests/test_echo.py +28 -28
- package/templates/stacks/mcp-rust/.dare/skills.yml +8 -8
- package/templates/stacks/mcp-rust/.env.example +14 -14
- package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -38
- package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -35
- package/templates/stacks/mcp-rust/README.md.tera +50 -50
- package/templates/stacks/mcp-rust/gitignore +5 -5
- package/templates/stacks/mcp-rust/llms.txt.tera +60 -60
- package/templates/stacks/mcp-rust/openapi.json.tera +31 -31
- package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -33
- package/templates/stacks/mcp-rust/src/lib.rs +6 -6
- package/templates/stacks/mcp-rust/src/main.rs.tera +30 -30
- package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -1
- package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -5
- package/templates/stacks/mcp-rust/src/server.rs.tera +38 -38
- package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -18
- package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -22
- package/templates/stacks/mcp-rust/src/transports/http.rs +27 -27
- package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -3
- package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -33
- package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -14
- package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -27
- package/templates/stacks/node-nestjs/.dare/skills.yml +11 -11
- package/templates/stacks/node-nestjs/.env.example +21 -21
- package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -54
- package/templates/stacks/node-nestjs/README.md.hbs +35 -35
- package/templates/stacks/node-nestjs/gitignore +7 -7
- package/templates/stacks/node-nestjs/llms.txt.hbs +47 -47
- package/templates/stacks/node-nestjs/nest-cli.json +16 -16
- package/templates/stacks/node-nestjs/openapi.json.hbs +75 -75
- package/templates/stacks/node-nestjs/package.json.hbs +57 -57
- package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -25
- package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -25
- package/templates/stacks/node-nestjs/src/app.module.ts +39 -39
- package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -29
- package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -25
- package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -36
- package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -9
- package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -17
- package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -25
- package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -38
- package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -13
- package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -44
- package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -9
- package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -9
- package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -22
- package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -15
- package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -41
- package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -11
- package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -38
- package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -38
- package/templates/stacks/node-nestjs/tsconfig.build.json +4 -4
- package/templates/stacks/node-nestjs/tsconfig.json +28 -28
- package/templates/stacks/php-laravel/.dare/skills.yml +11 -11
- package/templates/stacks/php-laravel/.env.example +41 -41
- package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -43
- package/templates/stacks/php-laravel/README.md.hbs +36 -36
- package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -36
- package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -33
- package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -26
- package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -34
- package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -12
- package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -13
- package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -33
- package/templates/stacks/php-laravel/app/Models/User.php +44 -44
- package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -32
- package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -37
- package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -57
- package/templates/stacks/php-laravel/artisan +12 -12
- package/templates/stacks/php-laravel/bootstrap/app.php +29 -29
- package/templates/stacks/php-laravel/bootstrap/providers.php +5 -5
- package/templates/stacks/php-laravel/composer.json.hbs +58 -58
- package/templates/stacks/php-laravel/config/l5-swagger.php +41 -41
- package/templates/stacks/php-laravel/config/reverb.php +34 -34
- package/templates/stacks/php-laravel/config/sanctum.php +15 -15
- package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -27
- package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -21
- package/templates/stacks/php-laravel/gitignore +23 -23
- package/templates/stacks/php-laravel/llms.txt.hbs +53 -53
- package/templates/stacks/php-laravel/openapi.json.hbs +43 -43
- package/templates/stacks/php-laravel/phpstan.neon +9 -9
- package/templates/stacks/php-laravel/routes/api.php +13 -13
- package/templates/stacks/php-laravel/routes/channels.php +7 -7
- package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -35
- package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -30
- package/templates/stacks/php-laravel/tests/Pest.php +5 -5
- package/templates/stacks/python-fastapi/.dare/skills.yml +11 -11
- package/templates/stacks/python-fastapi/.env.example +21 -21
- package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -43
- package/templates/stacks/python-fastapi/README.md.j2 +35 -35
- package/templates/stacks/python-fastapi/alembic/env.py +46 -46
- package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -26
- package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -37
- package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -39
- package/templates/stacks/python-fastapi/app/core/config.py +24 -24
- package/templates/stacks/python-fastapi/app/core/security.py +34 -34
- package/templates/stacks/python-fastapi/app/db/session.py +22 -22
- package/templates/stacks/python-fastapi/app/main.py.j2 +36 -36
- package/templates/stacks/python-fastapi/app/models/__init__.py +3 -3
- package/templates/stacks/python-fastapi/app/models/user.py +30 -30
- package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -34
- package/templates/stacks/python-fastapi/app/routers/auth.py +37 -37
- package/templates/stacks/python-fastapi/app/routers/users.py +46 -46
- package/templates/stacks/python-fastapi/app/schemas/user.py +56 -56
- package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -22
- package/templates/stacks/python-fastapi/app/services/user_service.py +31 -31
- package/templates/stacks/python-fastapi/gitignore +12 -12
- package/templates/stacks/python-fastapi/llms.txt.j2 +53 -53
- package/templates/stacks/python-fastapi/openapi.json.j2 +43 -43
- package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -45
- package/templates/stacks/python-fastapi/tests/test_auth.py +22 -22
- package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -50
- package/templates/stacks/ruby-rails-8/.env.example +20 -20
- package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -112
- package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -61
- package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -11
- package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -34
- package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -18
- package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -23
- package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -44
- package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -93
- package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -33
- package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -68
- package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -44
- package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -54
- package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -12
- package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -35
- package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -67
- package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -62
- package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -82
- package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -21
- package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -52
- package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -36
- package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -48
- package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -57
- package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -73
- package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -67
- package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -53
- package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -57
- package/templates/stacks/ruby-rails-8/config/dare.yml +42 -42
- package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -31
- package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -64
- package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -12
- package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -159
- package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -69
- package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -56
- package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -72
- package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -61
- package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -56
- package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -27
- package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -88
- package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -31
- package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -88
- package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -142
- package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -73
- package/templates/stacks/rust-axum/.dare/skills.yml +11 -11
- package/templates/stacks/rust-axum/.env.example +26 -26
- package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -40
- package/templates/stacks/rust-axum/Cargo.toml.tera +53 -53
- package/templates/stacks/rust-axum/README.md.tera +37 -37
- package/templates/stacks/rust-axum/gitignore +5 -5
- package/templates/stacks/rust-axum/llms.txt.tera +54 -54
- package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -13
- package/templates/stacks/rust-axum/openapi.json.tera +46 -46
- package/templates/stacks/rust-axum/src/config.rs +45 -45
- package/templates/stacks/rust-axum/src/errors.rs +48 -48
- package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -48
- package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -3
- package/templates/stacks/rust-axum/src/handlers/users.rs +81 -81
- package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -24
- package/templates/stacks/rust-axum/src/lib.rs +19 -19
- package/templates/stacks/rust-axum/src/llm/mod.rs +1 -1
- package/templates/stacks/rust-axum/src/llm/provider.rs +48 -48
- package/templates/stacks/rust-axum/src/main.rs.tera +64 -64
- package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -20
- package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -2
- package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -27
- package/templates/stacks/rust-axum/src/models/mod.rs +1 -1
- package/templates/stacks/rust-axum/src/models/user.rs +13 -13
- package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -1
- package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -62
- package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -50
- package/templates/stacks/rust-axum/src/services/mod.rs +2 -2
- package/templates/stacks/rust-axum/src/services/user_service.rs +53 -53
- package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -13
- package/dist/commands/new.d.ts +0 -16
- package/dist/commands/new.d.ts.map +0 -1
- package/dist/commands/new.js +0 -104
- package/dist/commands/new.js.map +0 -1
|
@@ -1,382 +1,382 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: skill-mcp-server
|
|
3
|
-
description: Padrões DARE para servidores MCP (Model Context Protocol) em TypeScript ou Python. Define tools, resources, prompts; suporta transports stdio, SSE e HTTP; validação Zod/Pydantic; autorização por tool; tracing estruturado; testes; publicação no MCP registry.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# DARE MCP Server Skill
|
|
7
|
-
|
|
8
|
-
Você é um especialista em servidores MCP (Model Context Protocol da Anthropic). Seu papel é gerar servidores MCP **bem estruturados, seguros, testáveis e publicáveis**, expondo tools/resources/prompts via stdio, SSE ou HTTP.
|
|
9
|
-
|
|
10
|
-
## Quando usar
|
|
11
|
-
|
|
12
|
-
- Você precisa expor capacidades para Claude Code, Cursor ou outro cliente MCP
|
|
13
|
-
- Você quer integrar uma API externa (Linear, GitHub, banco interno) como tool MCP
|
|
14
|
-
- Você está auditando um servidor MCP existente
|
|
15
|
-
|
|
16
|
-
## O que é MCP em 30 segundos
|
|
17
|
-
|
|
18
|
-
MCP (Model Context Protocol) é um protocolo aberto da Anthropic para conectar agentes a fontes de dados e ações externas. Um servidor MCP expõe:
|
|
19
|
-
|
|
20
|
-
- **Tools** — funções chamáveis pelo agente (ex: `create_issue`, `query_db`)
|
|
21
|
-
- **Resources** — dados leitáveis (ex: documentos, schemas)
|
|
22
|
-
- **Prompts** — templates parametrizados
|
|
23
|
-
|
|
24
|
-
Transports suportados:
|
|
25
|
-
- **stdio** — agente spawnea processo local, comunica via stdin/stdout (mais simples)
|
|
26
|
-
- **SSE** — server remoto, agente conecta via Server-Sent Events
|
|
27
|
-
- **HTTP** — server remoto stateless
|
|
28
|
-
|
|
29
|
-
## Stack canônica (TypeScript)
|
|
30
|
-
|
|
31
|
-
- **Node 20+** com TypeScript 5.5+
|
|
32
|
-
- **@modelcontextprotocol/sdk** SDK oficial
|
|
33
|
-
- **Zod** para validação de input/output de tools
|
|
34
|
-
- **vitest** para testes
|
|
35
|
-
- **eslint + prettier**
|
|
36
|
-
|
|
37
|
-
## Stack canônica (Python)
|
|
38
|
-
|
|
39
|
-
- **Python 3.11+**
|
|
40
|
-
- **mcp** SDK oficial (`pip install mcp`)
|
|
41
|
-
- **Pydantic v2** para schemas
|
|
42
|
-
- **pytest + pytest-asyncio**
|
|
43
|
-
- **ruff + mypy**
|
|
44
|
-
|
|
45
|
-
## Estrutura recomendada (TypeScript)
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
mcp-meu-server/
|
|
49
|
-
├── package.json
|
|
50
|
-
├── tsconfig.json
|
|
51
|
-
├── src/
|
|
52
|
-
│ ├── index.ts ← entrypoint (stdio)
|
|
53
|
-
│ ├── server.ts ← criação do MCP Server
|
|
54
|
-
│ ├── tools/
|
|
55
|
-
│ │ ├── create_issue.ts
|
|
56
|
-
│ │ └── search_issues.ts
|
|
57
|
-
│ ├── resources/
|
|
58
|
-
│ │ └── schema.ts
|
|
59
|
-
│ ├── prompts/
|
|
60
|
-
│ │ └── issue_template.ts
|
|
61
|
-
│ ├── schemas/ ← Zod schemas
|
|
62
|
-
│ └── lib/
|
|
63
|
-
│ └── linear-client.ts ← cliente da API externa
|
|
64
|
-
└── tests/
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Exemplo: server stdio TypeScript
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// src/index.ts
|
|
71
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
72
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
73
|
-
import { registerTools } from './tools/index.js';
|
|
74
|
-
import { registerResources } from './resources/index.js';
|
|
75
|
-
|
|
76
|
-
const server = new Server(
|
|
77
|
-
{ name: 'meu-mcp-server', version: '1.0.0' },
|
|
78
|
-
{ capabilities: { tools: {}, resources: {}, prompts: {} } }
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
registerTools(server);
|
|
82
|
-
registerResources(server);
|
|
83
|
-
|
|
84
|
-
const transport = new StdioServerTransport();
|
|
85
|
-
await server.connect(transport);
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Definindo uma tool
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
// src/tools/create_issue.ts
|
|
92
|
-
import { z } from 'zod';
|
|
93
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
94
|
-
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
95
|
-
|
|
96
|
-
const CreateIssueInput = z.object({
|
|
97
|
-
title: z.string().min(1).max(255),
|
|
98
|
-
description: z.string().optional(),
|
|
99
|
-
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
100
|
-
team_id: z.string().uuid(),
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const CreateIssueOutput = z.object({
|
|
104
|
-
id: z.string(),
|
|
105
|
-
url: z.string().url(),
|
|
106
|
-
number: z.number(),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
export function register(server: Server) {
|
|
110
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
111
|
-
tools: [{
|
|
112
|
-
name: 'create_issue',
|
|
113
|
-
description: 'Create a new issue in Linear',
|
|
114
|
-
inputSchema: CreateIssueInput.shape, // ou gerar via zod-to-json-schema
|
|
115
|
-
}],
|
|
116
|
-
}));
|
|
117
|
-
|
|
118
|
-
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
119
|
-
if (req.params.name !== 'create_issue') {
|
|
120
|
-
throw new Error('unknown tool');
|
|
121
|
-
}
|
|
122
|
-
const input = CreateIssueInput.parse(req.params.arguments);
|
|
123
|
-
const result = await linearClient.createIssue(input);
|
|
124
|
-
const output = CreateIssueOutput.parse({
|
|
125
|
-
id: result.id,
|
|
126
|
-
url: result.url,
|
|
127
|
-
number: result.number,
|
|
128
|
-
});
|
|
129
|
-
return { content: [{ type: 'text', text: JSON.stringify(output) }] };
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Exemplo: server stdio Python
|
|
135
|
-
|
|
136
|
-
```python
|
|
137
|
-
# server.py
|
|
138
|
-
import asyncio
|
|
139
|
-
from mcp.server import Server
|
|
140
|
-
from mcp.server.stdio import stdio_server
|
|
141
|
-
from mcp.types import Tool, TextContent
|
|
142
|
-
from pydantic import BaseModel, Field
|
|
143
|
-
|
|
144
|
-
app = Server("meu-mcp-server")
|
|
145
|
-
|
|
146
|
-
class CreateIssueInput(BaseModel):
|
|
147
|
-
title: str = Field(min_length=1, max_length=255)
|
|
148
|
-
description: str | None = None
|
|
149
|
-
priority: str = Field(default="medium", pattern="^(low|medium|high)$")
|
|
150
|
-
team_id: str
|
|
151
|
-
|
|
152
|
-
@app.list_tools()
|
|
153
|
-
async def list_tools() -> list[Tool]:
|
|
154
|
-
return [
|
|
155
|
-
Tool(
|
|
156
|
-
name="create_issue",
|
|
157
|
-
description="Create a new issue in Linear",
|
|
158
|
-
inputSchema=CreateIssueInput.model_json_schema(),
|
|
159
|
-
)
|
|
160
|
-
]
|
|
161
|
-
|
|
162
|
-
@app.call_tool()
|
|
163
|
-
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
164
|
-
if name != "create_issue":
|
|
165
|
-
raise ValueError(f"unknown tool: {name}")
|
|
166
|
-
input_data = CreateIssueInput.model_validate(arguments)
|
|
167
|
-
result = await linear_client.create_issue(input_data)
|
|
168
|
-
return [TextContent(type="text", text=result.model_dump_json())]
|
|
169
|
-
|
|
170
|
-
async def main():
|
|
171
|
-
async with stdio_server() as (read, write):
|
|
172
|
-
await app.run(read, write, app.create_initialization_options())
|
|
173
|
-
|
|
174
|
-
if __name__ == "__main__":
|
|
175
|
-
asyncio.run(main())
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Resources
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
import { ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
182
|
-
|
|
183
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
184
|
-
resources: [{
|
|
185
|
-
uri: 'linear://schema',
|
|
186
|
-
name: 'Linear Issue Schema',
|
|
187
|
-
mimeType: 'application/json',
|
|
188
|
-
}],
|
|
189
|
-
}));
|
|
190
|
-
|
|
191
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
|
|
192
|
-
if (req.params.uri === 'linear://schema') {
|
|
193
|
-
return { contents: [{ uri: req.params.uri, mimeType: 'application/json', text: JSON.stringify(schema) }] };
|
|
194
|
-
}
|
|
195
|
-
throw new Error('unknown resource');
|
|
196
|
-
});
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## Prompts
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
import { ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
203
|
-
|
|
204
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
205
|
-
prompts: [{
|
|
206
|
-
name: 'triage_issue',
|
|
207
|
-
description: 'Triage an issue and assign priority',
|
|
208
|
-
arguments: [
|
|
209
|
-
{ name: 'description', description: 'Issue description', required: true },
|
|
210
|
-
],
|
|
211
|
-
}],
|
|
212
|
-
}));
|
|
213
|
-
|
|
214
|
-
server.setRequestHandler(GetPromptRequestSchema, async (req) => ({
|
|
215
|
-
messages: [{
|
|
216
|
-
role: 'user',
|
|
217
|
-
content: { type: 'text', text: `Triage this issue and suggest a priority:\n\n${req.params.arguments?.description}` },
|
|
218
|
-
}],
|
|
219
|
-
}));
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
## Transports
|
|
223
|
-
|
|
224
|
-
| Transport | Quando usar | Setup |
|
|
225
|
-
|---|---|---|
|
|
226
|
-
| **stdio** | Server local, agente spawnea processo | `StdioServerTransport` |
|
|
227
|
-
| **SSE** | Server remoto, streaming bidirectional | `SSEServerTransport` + Express/Fastify |
|
|
228
|
-
| **HTTP** | Server remoto stateless | endpoint POST que devolve JSON |
|
|
229
|
-
|
|
230
|
-
## Autorização por tool
|
|
231
|
-
|
|
232
|
-
Toda tool deve declarar:
|
|
233
|
-
- **Quem pode chamar** — escopo ou role
|
|
234
|
-
- **Quais argumentos validar** — não confiar no client
|
|
235
|
-
- **Side effects** — destrutivo? idempotente?
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
// tool destrutiva exige confirmação ou role admin
|
|
239
|
-
if (input.confirm !== 'YES_I_AM_SURE') {
|
|
240
|
-
throw new Error('this tool requires confirmation');
|
|
241
|
-
}
|
|
242
|
-
if (!callerHasRole('admin')) {
|
|
243
|
-
throw new Error('admin only');
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## Observabilidade
|
|
248
|
-
|
|
249
|
-
Logue cada tool call (sem dados sensíveis):
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
console.error(JSON.stringify({
|
|
253
|
-
ts: new Date().toISOString(),
|
|
254
|
-
tool: req.params.name,
|
|
255
|
-
duration_ms: Date.now() - start,
|
|
256
|
-
success: true,
|
|
257
|
-
// sem args (PII), sem result (PII)
|
|
258
|
-
}));
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
> stdio usa stdout para protocolo MCP — **logs sempre em stderr**.
|
|
262
|
-
|
|
263
|
-
## Testes
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
// tests/create_issue.test.ts
|
|
267
|
-
import { test, expect, vi } from 'vitest';
|
|
268
|
-
import { CreateIssueInput } from '../src/tools/create_issue.js';
|
|
269
|
-
|
|
270
|
-
test('valida input correto', () => {
|
|
271
|
-
const valid = CreateIssueInput.parse({
|
|
272
|
-
title: 'Test',
|
|
273
|
-
team_id: '550e8400-e29b-41d4-a716-446655440000',
|
|
274
|
-
});
|
|
275
|
-
expect(valid.priority).toBe('medium'); // default
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
test('rejeita team_id inválido', () => {
|
|
279
|
-
expect(() => CreateIssueInput.parse({
|
|
280
|
-
title: 'Test',
|
|
281
|
-
team_id: 'not-a-uuid',
|
|
282
|
-
})).toThrow();
|
|
283
|
-
});
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
E2E com cliente MCP de teste:
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
290
|
-
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
291
|
-
|
|
292
|
-
const transport = new StdioClientTransport({ command: 'node', args: ['dist/index.js'] });
|
|
293
|
-
const client = new Client({ name: 'test', version: '0.0.0' }, { capabilities: {} });
|
|
294
|
-
await client.connect(transport);
|
|
295
|
-
|
|
296
|
-
const tools = await client.listTools();
|
|
297
|
-
expect(tools.tools.map(t => t.name)).toContain('create_issue');
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
## Antipatterns
|
|
301
|
-
|
|
302
|
-
| AP | Antipattern | Por quê |
|
|
303
|
-
|---|---|---|
|
|
304
|
-
| AP-01 | Logs no stdout (stdio) | Quebra o protocolo — sempre stderr |
|
|
305
|
-
| AP-02 | Tool sem schema de input | Cliente vai passar lixo |
|
|
306
|
-
| AP-03 | Sem validação no server | Confia no client (errado) |
|
|
307
|
-
| AP-04 | Tool destrutiva sem confirmação | Agente pode deletar dados sem querer |
|
|
308
|
-
| AP-05 | Secrets em código | Use env vars |
|
|
309
|
-
| AP-06 | Tool name não-descritivo (`do_thing`) | Agente não sabe quando usar |
|
|
310
|
-
| AP-07 | Description vago | Agente erra na escolha |
|
|
311
|
-
| AP-08 | Resource sem mimeType | Cliente não sabe parsear |
|
|
312
|
-
|
|
313
|
-
## Publicação
|
|
314
|
-
|
|
315
|
-
### Pré-requisitos para registry
|
|
316
|
-
|
|
317
|
-
- README.md com:
|
|
318
|
-
- Como instalar/configurar
|
|
319
|
-
- Lista de tools/resources/prompts
|
|
320
|
-
- Variáveis de ambiente necessárias
|
|
321
|
-
- Exemplo de `claude_desktop_config.json` (stdio)
|
|
322
|
-
- LICENSE (MIT recomendado)
|
|
323
|
-
- `package.json` ou `pyproject.toml` versionado
|
|
324
|
-
- Schema JSON exposto (vem das definições Zod/Pydantic)
|
|
325
|
-
|
|
326
|
-
### Distribuição
|
|
327
|
-
|
|
328
|
-
- **npm** — `npm publish` para servers TS
|
|
329
|
-
- **PyPI** — `python -m build && twine upload` para Python
|
|
330
|
-
- **Docker** — para SSE/HTTP servers (multi-stage build)
|
|
331
|
-
|
|
332
|
-
## Configuração no cliente (exemplo Claude Desktop)
|
|
333
|
-
|
|
334
|
-
```json
|
|
335
|
-
{
|
|
336
|
-
"mcpServers": {
|
|
337
|
-
"meu-server": {
|
|
338
|
-
"command": "node",
|
|
339
|
-
"args": ["/abs/path/to/dist/index.js"],
|
|
340
|
-
"env": {
|
|
341
|
-
"LINEAR_API_KEY": "lin_api_..."
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
## Como aplicar
|
|
349
|
-
|
|
350
|
-
### Passo 1: Decidir transport
|
|
351
|
-
|
|
352
|
-
Local + uso pessoal → **stdio**. Multi-usuário ou cloud → **SSE/HTTP**.
|
|
353
|
-
|
|
354
|
-
### Passo 2: Listar tools/resources/prompts
|
|
355
|
-
|
|
356
|
-
Inventarie no DESIGN.md o que vai expor. Cada tool: nome, descrição clara, input schema, output schema.
|
|
357
|
-
|
|
358
|
-
### Passo 3: Scaffold
|
|
359
|
-
|
|
360
|
-
Use SDK oficial. Estruture em `tools/`, `resources/`, `prompts/`.
|
|
361
|
-
|
|
362
|
-
### Passo 4: Schemas Zod/Pydantic
|
|
363
|
-
|
|
364
|
-
Toda tool tem schema de input. Output validado antes de retornar.
|
|
365
|
-
|
|
366
|
-
### Passo 5: Logs em stderr + observabilidade
|
|
367
|
-
|
|
368
|
-
`console.error` (stdio) com JSON estruturado.
|
|
369
|
-
|
|
370
|
-
### Passo 6: Testes + publicação
|
|
371
|
-
|
|
372
|
-
Vitest/pytest. README + LICENSE MIT. Publicar npm/PyPI.
|
|
373
|
-
|
|
374
|
-
## Dicas
|
|
375
|
-
|
|
376
|
-
- **Combine** com `dare-llm-integration` se o server chama LLM
|
|
377
|
-
- **Use** `dare-security` para auditar dependências
|
|
378
|
-
- **Para tools destrutivas**, exija confirm flag explícito
|
|
379
|
-
|
|
380
|
-
---
|
|
381
|
-
|
|
382
|
-
Esta skill é parte do DARE Method e está sob licença MIT.
|
|
1
|
+
---
|
|
2
|
+
name: skill-mcp-server
|
|
3
|
+
description: Padrões DARE para servidores MCP (Model Context Protocol) em TypeScript ou Python. Define tools, resources, prompts; suporta transports stdio, SSE e HTTP; validação Zod/Pydantic; autorização por tool; tracing estruturado; testes; publicação no MCP registry.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DARE MCP Server Skill
|
|
7
|
+
|
|
8
|
+
Você é um especialista em servidores MCP (Model Context Protocol da Anthropic). Seu papel é gerar servidores MCP **bem estruturados, seguros, testáveis e publicáveis**, expondo tools/resources/prompts via stdio, SSE ou HTTP.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Você precisa expor capacidades para Claude Code, Cursor ou outro cliente MCP
|
|
13
|
+
- Você quer integrar uma API externa (Linear, GitHub, banco interno) como tool MCP
|
|
14
|
+
- Você está auditando um servidor MCP existente
|
|
15
|
+
|
|
16
|
+
## O que é MCP em 30 segundos
|
|
17
|
+
|
|
18
|
+
MCP (Model Context Protocol) é um protocolo aberto da Anthropic para conectar agentes a fontes de dados e ações externas. Um servidor MCP expõe:
|
|
19
|
+
|
|
20
|
+
- **Tools** — funções chamáveis pelo agente (ex: `create_issue`, `query_db`)
|
|
21
|
+
- **Resources** — dados leitáveis (ex: documentos, schemas)
|
|
22
|
+
- **Prompts** — templates parametrizados
|
|
23
|
+
|
|
24
|
+
Transports suportados:
|
|
25
|
+
- **stdio** — agente spawnea processo local, comunica via stdin/stdout (mais simples)
|
|
26
|
+
- **SSE** — server remoto, agente conecta via Server-Sent Events
|
|
27
|
+
- **HTTP** — server remoto stateless
|
|
28
|
+
|
|
29
|
+
## Stack canônica (TypeScript)
|
|
30
|
+
|
|
31
|
+
- **Node 20+** com TypeScript 5.5+
|
|
32
|
+
- **@modelcontextprotocol/sdk** SDK oficial
|
|
33
|
+
- **Zod** para validação de input/output de tools
|
|
34
|
+
- **vitest** para testes
|
|
35
|
+
- **eslint + prettier**
|
|
36
|
+
|
|
37
|
+
## Stack canônica (Python)
|
|
38
|
+
|
|
39
|
+
- **Python 3.11+**
|
|
40
|
+
- **mcp** SDK oficial (`pip install mcp`)
|
|
41
|
+
- **Pydantic v2** para schemas
|
|
42
|
+
- **pytest + pytest-asyncio**
|
|
43
|
+
- **ruff + mypy**
|
|
44
|
+
|
|
45
|
+
## Estrutura recomendada (TypeScript)
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
mcp-meu-server/
|
|
49
|
+
├── package.json
|
|
50
|
+
├── tsconfig.json
|
|
51
|
+
├── src/
|
|
52
|
+
│ ├── index.ts ← entrypoint (stdio)
|
|
53
|
+
│ ├── server.ts ← criação do MCP Server
|
|
54
|
+
│ ├── tools/
|
|
55
|
+
│ │ ├── create_issue.ts
|
|
56
|
+
│ │ └── search_issues.ts
|
|
57
|
+
│ ├── resources/
|
|
58
|
+
│ │ └── schema.ts
|
|
59
|
+
│ ├── prompts/
|
|
60
|
+
│ │ └── issue_template.ts
|
|
61
|
+
│ ├── schemas/ ← Zod schemas
|
|
62
|
+
│ └── lib/
|
|
63
|
+
│ └── linear-client.ts ← cliente da API externa
|
|
64
|
+
└── tests/
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Exemplo: server stdio TypeScript
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// src/index.ts
|
|
71
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
72
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
73
|
+
import { registerTools } from './tools/index.js';
|
|
74
|
+
import { registerResources } from './resources/index.js';
|
|
75
|
+
|
|
76
|
+
const server = new Server(
|
|
77
|
+
{ name: 'meu-mcp-server', version: '1.0.0' },
|
|
78
|
+
{ capabilities: { tools: {}, resources: {}, prompts: {} } }
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
registerTools(server);
|
|
82
|
+
registerResources(server);
|
|
83
|
+
|
|
84
|
+
const transport = new StdioServerTransport();
|
|
85
|
+
await server.connect(transport);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Definindo uma tool
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// src/tools/create_issue.ts
|
|
92
|
+
import { z } from 'zod';
|
|
93
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
94
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
95
|
+
|
|
96
|
+
const CreateIssueInput = z.object({
|
|
97
|
+
title: z.string().min(1).max(255),
|
|
98
|
+
description: z.string().optional(),
|
|
99
|
+
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
100
|
+
team_id: z.string().uuid(),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const CreateIssueOutput = z.object({
|
|
104
|
+
id: z.string(),
|
|
105
|
+
url: z.string().url(),
|
|
106
|
+
number: z.number(),
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export function register(server: Server) {
|
|
110
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
111
|
+
tools: [{
|
|
112
|
+
name: 'create_issue',
|
|
113
|
+
description: 'Create a new issue in Linear',
|
|
114
|
+
inputSchema: CreateIssueInput.shape, // ou gerar via zod-to-json-schema
|
|
115
|
+
}],
|
|
116
|
+
}));
|
|
117
|
+
|
|
118
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
119
|
+
if (req.params.name !== 'create_issue') {
|
|
120
|
+
throw new Error('unknown tool');
|
|
121
|
+
}
|
|
122
|
+
const input = CreateIssueInput.parse(req.params.arguments);
|
|
123
|
+
const result = await linearClient.createIssue(input);
|
|
124
|
+
const output = CreateIssueOutput.parse({
|
|
125
|
+
id: result.id,
|
|
126
|
+
url: result.url,
|
|
127
|
+
number: result.number,
|
|
128
|
+
});
|
|
129
|
+
return { content: [{ type: 'text', text: JSON.stringify(output) }] };
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Exemplo: server stdio Python
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
# server.py
|
|
138
|
+
import asyncio
|
|
139
|
+
from mcp.server import Server
|
|
140
|
+
from mcp.server.stdio import stdio_server
|
|
141
|
+
from mcp.types import Tool, TextContent
|
|
142
|
+
from pydantic import BaseModel, Field
|
|
143
|
+
|
|
144
|
+
app = Server("meu-mcp-server")
|
|
145
|
+
|
|
146
|
+
class CreateIssueInput(BaseModel):
|
|
147
|
+
title: str = Field(min_length=1, max_length=255)
|
|
148
|
+
description: str | None = None
|
|
149
|
+
priority: str = Field(default="medium", pattern="^(low|medium|high)$")
|
|
150
|
+
team_id: str
|
|
151
|
+
|
|
152
|
+
@app.list_tools()
|
|
153
|
+
async def list_tools() -> list[Tool]:
|
|
154
|
+
return [
|
|
155
|
+
Tool(
|
|
156
|
+
name="create_issue",
|
|
157
|
+
description="Create a new issue in Linear",
|
|
158
|
+
inputSchema=CreateIssueInput.model_json_schema(),
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
@app.call_tool()
|
|
163
|
+
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
164
|
+
if name != "create_issue":
|
|
165
|
+
raise ValueError(f"unknown tool: {name}")
|
|
166
|
+
input_data = CreateIssueInput.model_validate(arguments)
|
|
167
|
+
result = await linear_client.create_issue(input_data)
|
|
168
|
+
return [TextContent(type="text", text=result.model_dump_json())]
|
|
169
|
+
|
|
170
|
+
async def main():
|
|
171
|
+
async with stdio_server() as (read, write):
|
|
172
|
+
await app.run(read, write, app.create_initialization_options())
|
|
173
|
+
|
|
174
|
+
if __name__ == "__main__":
|
|
175
|
+
asyncio.run(main())
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Resources
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
182
|
+
|
|
183
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
184
|
+
resources: [{
|
|
185
|
+
uri: 'linear://schema',
|
|
186
|
+
name: 'Linear Issue Schema',
|
|
187
|
+
mimeType: 'application/json',
|
|
188
|
+
}],
|
|
189
|
+
}));
|
|
190
|
+
|
|
191
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
|
|
192
|
+
if (req.params.uri === 'linear://schema') {
|
|
193
|
+
return { contents: [{ uri: req.params.uri, mimeType: 'application/json', text: JSON.stringify(schema) }] };
|
|
194
|
+
}
|
|
195
|
+
throw new Error('unknown resource');
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Prompts
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
203
|
+
|
|
204
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
205
|
+
prompts: [{
|
|
206
|
+
name: 'triage_issue',
|
|
207
|
+
description: 'Triage an issue and assign priority',
|
|
208
|
+
arguments: [
|
|
209
|
+
{ name: 'description', description: 'Issue description', required: true },
|
|
210
|
+
],
|
|
211
|
+
}],
|
|
212
|
+
}));
|
|
213
|
+
|
|
214
|
+
server.setRequestHandler(GetPromptRequestSchema, async (req) => ({
|
|
215
|
+
messages: [{
|
|
216
|
+
role: 'user',
|
|
217
|
+
content: { type: 'text', text: `Triage this issue and suggest a priority:\n\n${req.params.arguments?.description}` },
|
|
218
|
+
}],
|
|
219
|
+
}));
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Transports
|
|
223
|
+
|
|
224
|
+
| Transport | Quando usar | Setup |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| **stdio** | Server local, agente spawnea processo | `StdioServerTransport` |
|
|
227
|
+
| **SSE** | Server remoto, streaming bidirectional | `SSEServerTransport` + Express/Fastify |
|
|
228
|
+
| **HTTP** | Server remoto stateless | endpoint POST que devolve JSON |
|
|
229
|
+
|
|
230
|
+
## Autorização por tool
|
|
231
|
+
|
|
232
|
+
Toda tool deve declarar:
|
|
233
|
+
- **Quem pode chamar** — escopo ou role
|
|
234
|
+
- **Quais argumentos validar** — não confiar no client
|
|
235
|
+
- **Side effects** — destrutivo? idempotente?
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// tool destrutiva exige confirmação ou role admin
|
|
239
|
+
if (input.confirm !== 'YES_I_AM_SURE') {
|
|
240
|
+
throw new Error('this tool requires confirmation');
|
|
241
|
+
}
|
|
242
|
+
if (!callerHasRole('admin')) {
|
|
243
|
+
throw new Error('admin only');
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Observabilidade
|
|
248
|
+
|
|
249
|
+
Logue cada tool call (sem dados sensíveis):
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
console.error(JSON.stringify({
|
|
253
|
+
ts: new Date().toISOString(),
|
|
254
|
+
tool: req.params.name,
|
|
255
|
+
duration_ms: Date.now() - start,
|
|
256
|
+
success: true,
|
|
257
|
+
// sem args (PII), sem result (PII)
|
|
258
|
+
}));
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
> stdio usa stdout para protocolo MCP — **logs sempre em stderr**.
|
|
262
|
+
|
|
263
|
+
## Testes
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// tests/create_issue.test.ts
|
|
267
|
+
import { test, expect, vi } from 'vitest';
|
|
268
|
+
import { CreateIssueInput } from '../src/tools/create_issue.js';
|
|
269
|
+
|
|
270
|
+
test('valida input correto', () => {
|
|
271
|
+
const valid = CreateIssueInput.parse({
|
|
272
|
+
title: 'Test',
|
|
273
|
+
team_id: '550e8400-e29b-41d4-a716-446655440000',
|
|
274
|
+
});
|
|
275
|
+
expect(valid.priority).toBe('medium'); // default
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test('rejeita team_id inválido', () => {
|
|
279
|
+
expect(() => CreateIssueInput.parse({
|
|
280
|
+
title: 'Test',
|
|
281
|
+
team_id: 'not-a-uuid',
|
|
282
|
+
})).toThrow();
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
E2E com cliente MCP de teste:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
290
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
291
|
+
|
|
292
|
+
const transport = new StdioClientTransport({ command: 'node', args: ['dist/index.js'] });
|
|
293
|
+
const client = new Client({ name: 'test', version: '0.0.0' }, { capabilities: {} });
|
|
294
|
+
await client.connect(transport);
|
|
295
|
+
|
|
296
|
+
const tools = await client.listTools();
|
|
297
|
+
expect(tools.tools.map(t => t.name)).toContain('create_issue');
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Antipatterns
|
|
301
|
+
|
|
302
|
+
| AP | Antipattern | Por quê |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| AP-01 | Logs no stdout (stdio) | Quebra o protocolo — sempre stderr |
|
|
305
|
+
| AP-02 | Tool sem schema de input | Cliente vai passar lixo |
|
|
306
|
+
| AP-03 | Sem validação no server | Confia no client (errado) |
|
|
307
|
+
| AP-04 | Tool destrutiva sem confirmação | Agente pode deletar dados sem querer |
|
|
308
|
+
| AP-05 | Secrets em código | Use env vars |
|
|
309
|
+
| AP-06 | Tool name não-descritivo (`do_thing`) | Agente não sabe quando usar |
|
|
310
|
+
| AP-07 | Description vago | Agente erra na escolha |
|
|
311
|
+
| AP-08 | Resource sem mimeType | Cliente não sabe parsear |
|
|
312
|
+
|
|
313
|
+
## Publicação
|
|
314
|
+
|
|
315
|
+
### Pré-requisitos para registry
|
|
316
|
+
|
|
317
|
+
- README.md com:
|
|
318
|
+
- Como instalar/configurar
|
|
319
|
+
- Lista de tools/resources/prompts
|
|
320
|
+
- Variáveis de ambiente necessárias
|
|
321
|
+
- Exemplo de `claude_desktop_config.json` (stdio)
|
|
322
|
+
- LICENSE (MIT recomendado)
|
|
323
|
+
- `package.json` ou `pyproject.toml` versionado
|
|
324
|
+
- Schema JSON exposto (vem das definições Zod/Pydantic)
|
|
325
|
+
|
|
326
|
+
### Distribuição
|
|
327
|
+
|
|
328
|
+
- **npm** — `npm publish` para servers TS
|
|
329
|
+
- **PyPI** — `python -m build && twine upload` para Python
|
|
330
|
+
- **Docker** — para SSE/HTTP servers (multi-stage build)
|
|
331
|
+
|
|
332
|
+
## Configuração no cliente (exemplo Claude Desktop)
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"mcpServers": {
|
|
337
|
+
"meu-server": {
|
|
338
|
+
"command": "node",
|
|
339
|
+
"args": ["/abs/path/to/dist/index.js"],
|
|
340
|
+
"env": {
|
|
341
|
+
"LINEAR_API_KEY": "lin_api_..."
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Como aplicar
|
|
349
|
+
|
|
350
|
+
### Passo 1: Decidir transport
|
|
351
|
+
|
|
352
|
+
Local + uso pessoal → **stdio**. Multi-usuário ou cloud → **SSE/HTTP**.
|
|
353
|
+
|
|
354
|
+
### Passo 2: Listar tools/resources/prompts
|
|
355
|
+
|
|
356
|
+
Inventarie no DESIGN.md o que vai expor. Cada tool: nome, descrição clara, input schema, output schema.
|
|
357
|
+
|
|
358
|
+
### Passo 3: Scaffold
|
|
359
|
+
|
|
360
|
+
Use SDK oficial. Estruture em `tools/`, `resources/`, `prompts/`.
|
|
361
|
+
|
|
362
|
+
### Passo 4: Schemas Zod/Pydantic
|
|
363
|
+
|
|
364
|
+
Toda tool tem schema de input. Output validado antes de retornar.
|
|
365
|
+
|
|
366
|
+
### Passo 5: Logs em stderr + observabilidade
|
|
367
|
+
|
|
368
|
+
`console.error` (stdio) com JSON estruturado.
|
|
369
|
+
|
|
370
|
+
### Passo 6: Testes + publicação
|
|
371
|
+
|
|
372
|
+
Vitest/pytest. README + LICENSE MIT. Publicar npm/PyPI.
|
|
373
|
+
|
|
374
|
+
## Dicas
|
|
375
|
+
|
|
376
|
+
- **Combine** com `dare-llm-integration` se o server chama LLM
|
|
377
|
+
- **Use** `dare-security` para auditar dependências
|
|
378
|
+
- **Para tools destrutivas**, exija confirm flag explícito
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
Esta skill é parte do DARE Method e está sob licença MIT.
|