@dewtech/dare-cli 3.0.0 → 3.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.
- package/README.md +45 -39
- package/dist/bin/dare.js +1 -3
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/__tests__/init.integration.spec.d.ts +2 -0
- package/dist/commands/__tests__/init.integration.spec.d.ts.map +1 -0
- package/dist/commands/__tests__/init.integration.spec.js +134 -0
- package/dist/commands/__tests__/init.integration.spec.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +84 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +2 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/mcp-server/bin/server.js +0 -0
- package/dist/stacks/__tests__/dna-emitter.spec.d.ts +2 -0
- package/dist/stacks/__tests__/dna-emitter.spec.d.ts.map +1 -0
- package/dist/stacks/__tests__/dna-emitter.spec.js +207 -0
- package/dist/stacks/__tests__/dna-emitter.spec.js.map +1 -0
- package/dist/stacks/__tests__/dna.spec.d.ts +2 -0
- package/dist/stacks/__tests__/dna.spec.d.ts.map +1 -0
- package/dist/stacks/__tests__/dna.spec.js +211 -0
- package/dist/stacks/__tests__/dna.spec.js.map +1 -0
- package/dist/stacks/__tests__/parity-rails.fixture.json +228 -0
- package/dist/stacks/__tests__/parity-rails.spec.d.ts +2 -0
- package/dist/stacks/__tests__/parity-rails.spec.d.ts.map +1 -0
- package/dist/stacks/__tests__/parity-rails.spec.js +99 -0
- package/dist/stacks/__tests__/parity-rails.spec.js.map +1 -0
- package/dist/stacks/__tests__/registry.spec.d.ts +2 -0
- package/dist/stacks/__tests__/registry.spec.d.ts.map +1 -0
- package/dist/stacks/__tests__/registry.spec.js +101 -0
- package/dist/stacks/__tests__/registry.spec.js.map +1 -0
- package/dist/stacks/__tests__/template-engine.spec.d.ts +2 -0
- package/dist/stacks/__tests__/template-engine.spec.d.ts.map +1 -0
- package/dist/stacks/__tests__/template-engine.spec.js +149 -0
- package/dist/stacks/__tests__/template-engine.spec.js.map +1 -0
- package/dist/stacks/dna-emitter.d.ts +45 -0
- package/dist/stacks/dna-emitter.d.ts.map +1 -0
- package/dist/stacks/dna-emitter.js +267 -0
- package/dist/stacks/dna-emitter.js.map +1 -0
- package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/go-gin/__tests__/scaffold.spec.js +221 -0
- package/dist/stacks/go-gin/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/go-gin/scaffold.d.ts +3 -0
- package/dist/stacks/go-gin/scaffold.d.ts.map +1 -0
- package/dist/stacks/go-gin/scaffold.js +105 -0
- package/dist/stacks/go-gin/scaffold.js.map +1 -0
- package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js +215 -0
- package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/go-stdlib/scaffold.d.ts +3 -0
- package/dist/stacks/go-stdlib/scaffold.d.ts.map +1 -0
- package/dist/stacks/go-stdlib/scaffold.js +106 -0
- package/dist/stacks/go-stdlib/scaffold.js.map +1 -0
- package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/mcp-go/__tests__/scaffold.spec.js +203 -0
- package/dist/stacks/mcp-go/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/mcp-go/scaffold.d.ts +3 -0
- package/dist/stacks/mcp-go/scaffold.d.ts.map +1 -0
- package/dist/stacks/mcp-go/scaffold.js +94 -0
- package/dist/stacks/mcp-go/scaffold.js.map +1 -0
- package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js +236 -0
- package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/mcp-node-ts/scaffold.d.ts +3 -0
- package/dist/stacks/mcp-node-ts/scaffold.d.ts.map +1 -0
- package/dist/stacks/mcp-node-ts/scaffold.js +95 -0
- package/dist/stacks/mcp-node-ts/scaffold.js.map +1 -0
- package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/mcp-python/__tests__/scaffold.spec.js +228 -0
- package/dist/stacks/mcp-python/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/mcp-python/scaffold.d.ts +3 -0
- package/dist/stacks/mcp-python/scaffold.d.ts.map +1 -0
- package/dist/stacks/mcp-python/scaffold.js +98 -0
- package/dist/stacks/mcp-python/scaffold.js.map +1 -0
- package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js +213 -0
- package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/mcp-rust/scaffold.d.ts +3 -0
- package/dist/stacks/mcp-rust/scaffold.d.ts.map +1 -0
- package/dist/stacks/mcp-rust/scaffold.js +98 -0
- package/dist/stacks/mcp-rust/scaffold.js.map +1 -0
- package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js +172 -0
- package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/node-nestjs/scaffold.d.ts +3 -0
- package/dist/stacks/node-nestjs/scaffold.d.ts.map +1 -0
- package/dist/stacks/node-nestjs/scaffold.js +117 -0
- package/dist/stacks/node-nestjs/scaffold.js.map +1 -0
- package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/php-laravel/__tests__/scaffold.spec.js +205 -0
- package/dist/stacks/php-laravel/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/php-laravel/scaffold.d.ts +3 -0
- package/dist/stacks/php-laravel/scaffold.d.ts.map +1 -0
- package/dist/stacks/php-laravel/scaffold.js +109 -0
- package/dist/stacks/php-laravel/scaffold.js.map +1 -0
- package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js +168 -0
- package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/python-fastapi/scaffold.d.ts +3 -0
- package/dist/stacks/python-fastapi/scaffold.d.ts.map +1 -0
- package/dist/stacks/python-fastapi/scaffold.js +108 -0
- package/dist/stacks/python-fastapi/scaffold.js.map +1 -0
- package/dist/stacks/registry.d.ts +38 -0
- package/dist/stacks/registry.d.ts.map +1 -0
- package/dist/stacks/registry.js +153 -0
- package/dist/stacks/registry.js.map +1 -0
- package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts +6 -0
- package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js +604 -0
- package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/ruby-rails-8/scaffold.d.ts +91 -0
- package/dist/stacks/ruby-rails-8/scaffold.d.ts.map +1 -0
- package/dist/stacks/ruby-rails-8/scaffold.js +410 -0
- package/dist/stacks/ruby-rails-8/scaffold.js.map +1 -0
- package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts +2 -0
- package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts.map +1 -0
- package/dist/stacks/rust-axum/__tests__/scaffold.spec.js +203 -0
- package/dist/stacks/rust-axum/__tests__/scaffold.spec.js.map +1 -0
- package/dist/stacks/rust-axum/scaffold.d.ts +3 -0
- package/dist/stacks/rust-axum/scaffold.d.ts.map +1 -0
- package/dist/stacks/rust-axum/scaffold.js +105 -0
- package/dist/stacks/rust-axum/scaffold.js.map +1 -0
- package/dist/stacks/template-engine.d.ts +38 -0
- package/dist/stacks/template-engine.d.ts.map +1 -0
- package/dist/stacks/template-engine.js +134 -0
- package/dist/stacks/template-engine.js.map +1 -0
- package/dist/stacks/types.d.ts +69 -0
- package/dist/stacks/types.d.ts.map +1 -0
- package/dist/stacks/types.js +29 -0
- package/dist/stacks/types.js.map +1 -0
- package/dist/utils/project-generator.d.ts +1 -1
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +16 -7
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/stack-bootstrap.d.ts +3 -2
- package/dist/utils/stack-bootstrap.d.ts.map +1 -1
- package/dist/utils/stack-bootstrap.js +46 -16
- package/dist/utils/stack-bootstrap.js.map +1 -1
- package/package.json +91 -87
- package/templates/stacks/go-gin/.dare/skills.yml +11 -0
- package/templates/stacks/go-gin/.env.example +24 -0
- package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -0
- package/templates/stacks/go-gin/README.md.tpl +38 -0
- package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -0
- package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -0
- package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -0
- package/templates/stacks/go-gin/db/queries/users.sql +23 -0
- package/templates/stacks/go-gin/gitignore +7 -0
- package/templates/stacks/go-gin/go.mod.tpl +17 -0
- package/templates/stacks/go-gin/internal/config/config.go +41 -0
- package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -0
- package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -0
- package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -0
- package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -0
- package/templates/stacks/go-gin/internal/llm/dummy.go +14 -0
- package/templates/stacks/go-gin/internal/llm/provider.go +8 -0
- package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -0
- package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -0
- package/templates/stacks/go-gin/internal/model/user.go +17 -0
- package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -0
- package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -0
- package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -0
- package/templates/stacks/go-gin/llms.txt.tpl +54 -0
- package/templates/stacks/go-gin/openapi.json.tpl +46 -0
- package/templates/stacks/go-gin/sqlc.yaml +14 -0
- package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -0
- package/templates/stacks/go-stdlib/.dare/skills.yml +11 -0
- package/templates/stacks/go-stdlib/.env.example +24 -0
- package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -0
- package/templates/stacks/go-stdlib/README.md.tpl +41 -0
- package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -0
- package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -0
- package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -0
- package/templates/stacks/go-stdlib/db/queries/users.sql +23 -0
- package/templates/stacks/go-stdlib/gitignore +6 -0
- package/templates/stacks/go-stdlib/go.mod.tpl +15 -0
- package/templates/stacks/go-stdlib/internal/config/config.go +41 -0
- package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -0
- package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -0
- package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -0
- package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -0
- package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -0
- package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -0
- package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -0
- package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -0
- package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -0
- package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -0
- package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -0
- package/templates/stacks/go-stdlib/internal/model/user.go +17 -0
- package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -0
- package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -0
- package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -0
- package/templates/stacks/go-stdlib/llms.txt.tpl +60 -0
- package/templates/stacks/go-stdlib/openapi.json.tpl +46 -0
- package/templates/stacks/go-stdlib/sqlc.yaml +14 -0
- package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -0
- package/templates/stacks/mcp-go/.dare/skills.yml +8 -0
- package/templates/stacks/mcp-go/.env.example +14 -0
- package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -0
- package/templates/stacks/mcp-go/README.md.tpl +50 -0
- package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -0
- package/templates/stacks/mcp-go/gitignore +6 -0
- package/templates/stacks/mcp-go/go.mod.tpl +9 -0
- package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -0
- package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -0
- package/templates/stacks/mcp-go/internal/tools/echo.go +15 -0
- package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -0
- package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -0
- package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -0
- package/templates/stacks/mcp-go/llms.txt.tpl +60 -0
- package/templates/stacks/mcp-go/openapi.json.tpl +31 -0
- package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -0
- package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -0
- package/templates/stacks/mcp-node-ts/.env.example +16 -0
- package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -0
- package/templates/stacks/mcp-node-ts/README.md.hbs +49 -0
- package/templates/stacks/mcp-node-ts/gitignore +7 -0
- package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -0
- package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -0
- package/templates/stacks/mcp-node-ts/package.json.hbs +35 -0
- package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -0
- package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -0
- package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -0
- package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -0
- package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -0
- package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -0
- package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -0
- package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -0
- package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -0
- package/templates/stacks/mcp-node-ts/tsconfig.json +17 -0
- package/templates/stacks/mcp-python/.dare/skills.yml +8 -0
- package/templates/stacks/mcp-python/.env.example +14 -0
- package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -0
- package/templates/stacks/mcp-python/README.md.j2 +49 -0
- package/templates/stacks/mcp-python/gitignore +12 -0
- package/templates/stacks/mcp-python/llms.txt.j2 +56 -0
- package/templates/stacks/mcp-python/openapi.json.j2 +33 -0
- package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -0
- package/templates/stacks/mcp-python/src/__init__.py +0 -0
- package/templates/stacks/mcp-python/src/cli.py.j2 +68 -0
- package/templates/stacks/mcp-python/src/prompts/__init__.py +0 -0
- package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -0
- package/templates/stacks/mcp-python/src/server.py.j2 +28 -0
- package/templates/stacks/mcp-python/src/tools/__init__.py +0 -0
- package/templates/stacks/mcp-python/src/tools/echo.py +12 -0
- package/templates/stacks/mcp-python/src/transports/__init__.py +0 -0
- package/templates/stacks/mcp-python/src/transports/http.py +12 -0
- package/templates/stacks/mcp-python/src/transports/sse.py +13 -0
- package/templates/stacks/mcp-python/src/transports/stdio.py +6 -0
- package/templates/stacks/mcp-python/tests/__init__.py +0 -0
- package/templates/stacks/mcp-python/tests/test_echo.py +28 -0
- package/templates/stacks/mcp-rust/.dare/skills.yml +8 -0
- package/templates/stacks/mcp-rust/.env.example +14 -0
- package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -0
- package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -0
- package/templates/stacks/mcp-rust/README.md.tera +50 -0
- package/templates/stacks/mcp-rust/gitignore +5 -0
- package/templates/stacks/mcp-rust/llms.txt.tera +60 -0
- package/templates/stacks/mcp-rust/openapi.json.tera +31 -0
- package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -0
- package/templates/stacks/mcp-rust/src/lib.rs +6 -0
- package/templates/stacks/mcp-rust/src/main.rs.tera +30 -0
- package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -0
- package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -0
- package/templates/stacks/mcp-rust/src/server.rs.tera +38 -0
- package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -0
- package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -0
- package/templates/stacks/mcp-rust/src/transports/http.rs +27 -0
- package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -0
- package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -0
- package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -0
- package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -0
- package/templates/stacks/node-nestjs/.dare/skills.yml +11 -0
- package/templates/stacks/node-nestjs/.env.example +21 -0
- package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -0
- package/templates/stacks/node-nestjs/README.md.hbs +35 -0
- package/templates/stacks/node-nestjs/gitignore +7 -0
- package/templates/stacks/node-nestjs/llms.txt.hbs +47 -0
- package/templates/stacks/node-nestjs/nest-cli.json +16 -0
- package/templates/stacks/node-nestjs/openapi.json.hbs +75 -0
- package/templates/stacks/node-nestjs/package.json.hbs +57 -0
- package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -0
- package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -0
- package/templates/stacks/node-nestjs/src/app.module.ts +39 -0
- package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -0
- package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -0
- package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -0
- package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -0
- package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -0
- package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -0
- package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -0
- package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -0
- package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -0
- package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -0
- package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -0
- package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -0
- package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -0
- package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -0
- package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -0
- package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -0
- package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -0
- package/templates/stacks/node-nestjs/tsconfig.build.json +4 -0
- package/templates/stacks/node-nestjs/tsconfig.json +28 -0
- package/templates/stacks/php-laravel/.dare/skills.yml +11 -0
- package/templates/stacks/php-laravel/.env.example +41 -0
- package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -0
- package/templates/stacks/php-laravel/README.md.hbs +36 -0
- package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -0
- package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -0
- package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -0
- package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -0
- package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -0
- package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -0
- package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -0
- package/templates/stacks/php-laravel/app/Models/User.php +44 -0
- package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -0
- package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -0
- package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -0
- package/templates/stacks/php-laravel/artisan +12 -0
- package/templates/stacks/php-laravel/bootstrap/app.php +29 -0
- package/templates/stacks/php-laravel/bootstrap/providers.php +5 -0
- package/templates/stacks/php-laravel/composer.json.hbs +58 -0
- package/templates/stacks/php-laravel/config/l5-swagger.php +41 -0
- package/templates/stacks/php-laravel/config/reverb.php +34 -0
- package/templates/stacks/php-laravel/config/sanctum.php +15 -0
- package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -0
- package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -0
- package/templates/stacks/php-laravel/gitignore +23 -0
- package/templates/stacks/php-laravel/llms.txt.hbs +53 -0
- package/templates/stacks/php-laravel/openapi.json.hbs +43 -0
- package/templates/stacks/php-laravel/phpstan.neon +9 -0
- package/templates/stacks/php-laravel/routes/api.php +13 -0
- package/templates/stacks/php-laravel/routes/channels.php +7 -0
- package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -0
- package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -0
- package/templates/stacks/php-laravel/tests/Pest.php +5 -0
- package/templates/stacks/python-fastapi/.dare/skills.yml +11 -0
- package/templates/stacks/python-fastapi/.env.example +21 -0
- package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -0
- package/templates/stacks/python-fastapi/README.md.j2 +35 -0
- package/templates/stacks/python-fastapi/alembic/env.py +46 -0
- package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -0
- package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -0
- package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -0
- package/templates/stacks/python-fastapi/app/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/core/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/core/config.py +24 -0
- package/templates/stacks/python-fastapi/app/core/security.py +34 -0
- package/templates/stacks/python-fastapi/app/db/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/db/session.py +22 -0
- package/templates/stacks/python-fastapi/app/main.py.j2 +36 -0
- package/templates/stacks/python-fastapi/app/models/__init__.py +3 -0
- package/templates/stacks/python-fastapi/app/models/user.py +30 -0
- package/templates/stacks/python-fastapi/app/repositories/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -0
- package/templates/stacks/python-fastapi/app/routers/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/routers/auth.py +37 -0
- package/templates/stacks/python-fastapi/app/routers/users.py +46 -0
- package/templates/stacks/python-fastapi/app/schemas/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/schemas/user.py +56 -0
- package/templates/stacks/python-fastapi/app/services/__init__.py +0 -0
- package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -0
- package/templates/stacks/python-fastapi/app/services/user_service.py +31 -0
- package/templates/stacks/python-fastapi/gitignore +12 -0
- package/templates/stacks/python-fastapi/llms.txt.j2 +53 -0
- package/templates/stacks/python-fastapi/openapi.json.j2 +43 -0
- package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -0
- package/templates/stacks/python-fastapi/tests/__init__.py +0 -0
- package/templates/stacks/python-fastapi/tests/test_auth.py +22 -0
- package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -0
- package/templates/stacks/ruby-rails-8/.env.example +20 -0
- package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -0
- package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -0
- package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -0
- package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -0
- package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -0
- package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -0
- package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -0
- package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -0
- package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -0
- package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -0
- package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -0
- package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -0
- package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -0
- package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -0
- package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -0
- package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -0
- package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -0
- package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -0
- package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -0
- package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -0
- package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -0
- package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -0
- package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -0
- package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -0
- package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -0
- package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -0
- package/templates/stacks/ruby-rails-8/config/dare.yml +42 -0
- package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -0
- package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -0
- package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -0
- package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -0
- package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -0
- package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -0
- package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -0
- package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -0
- package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -0
- package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -0
- package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -0
- package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -0
- package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -0
- package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -0
- package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -0
- package/templates/stacks/rust-axum/.dare/skills.yml +11 -0
- package/templates/stacks/rust-axum/.env.example +26 -0
- package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -0
- package/templates/stacks/rust-axum/Cargo.toml.tera +53 -0
- package/templates/stacks/rust-axum/README.md.tera +37 -0
- package/templates/stacks/rust-axum/gitignore +5 -0
- package/templates/stacks/rust-axum/llms.txt.tera +54 -0
- package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -0
- package/templates/stacks/rust-axum/openapi.json.tera +46 -0
- package/templates/stacks/rust-axum/src/config.rs +45 -0
- package/templates/stacks/rust-axum/src/errors.rs +48 -0
- package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -0
- package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -0
- package/templates/stacks/rust-axum/src/handlers/users.rs +81 -0
- package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -0
- package/templates/stacks/rust-axum/src/lib.rs +19 -0
- package/templates/stacks/rust-axum/src/llm/mod.rs +1 -0
- package/templates/stacks/rust-axum/src/llm/provider.rs +48 -0
- package/templates/stacks/rust-axum/src/main.rs.tera +64 -0
- package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -0
- package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -0
- package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -0
- package/templates/stacks/rust-axum/src/models/mod.rs +1 -0
- package/templates/stacks/rust-axum/src/models/user.rs +13 -0
- package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -0
- package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -0
- package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -0
- package/templates/stacks/rust-axum/src/services/mod.rs +2 -0
- package/templates/stacks/rust-axum/src/services/user_service.rs +53 -0
- package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# {{ projectName }}
|
|
2
|
+
|
|
3
|
+
DARE-shaped MCP server in Python 3.11+ using the FastMCP API.
|
|
4
|
+
Default transport: **{{ defaultTransport }}**.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
cp .env.example .env
|
|
10
|
+
python -m venv .venv
|
|
11
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
12
|
+
pip install -e ".[dev]"
|
|
13
|
+
python -m src.cli # uses {{ defaultTransport }} transport by default
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Test with MCP Inspector
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx @modelcontextprotocol/inspector python -m src.cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Tools
|
|
23
|
+
|
|
24
|
+
- `echo` — returns its input. Canonical smoke test.
|
|
25
|
+
|
|
26
|
+
## Prompts
|
|
27
|
+
|
|
28
|
+
- `summarize` — placeholder prompt template that takes a `text` argument.
|
|
29
|
+
|
|
30
|
+
## Transports
|
|
31
|
+
|
|
32
|
+
Pick at runtime via `--transport stdio|sse|http` or `MCP_TRANSPORT` env:
|
|
33
|
+
|
|
34
|
+
| Transport | When to use |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `stdio` (default) | Local CLI agents |
|
|
37
|
+
| `sse` | Web clients via Server-Sent Events |
|
|
38
|
+
| `http` | Streamable HTTP — newest MCP transport |
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
- `python -m src.cli` — start server
|
|
43
|
+
- `pytest` — run tests
|
|
44
|
+
- `ruff check .` — lint
|
|
45
|
+
- `pip-audit` — dependency audit
|
|
46
|
+
|
|
47
|
+
## DARE Method
|
|
48
|
+
|
|
49
|
+
See `.dare/skills.yml` and `llms.txt`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# {{ projectName }}
|
|
2
|
+
|
|
3
|
+
DARE-shaped MCP server (Python 3.11+). Default transport: **{{ defaultTransport }}**.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cp .env.example .env
|
|
9
|
+
python -m venv .venv
|
|
10
|
+
source .venv/bin/activate
|
|
11
|
+
pip install -e ".[dev]"
|
|
12
|
+
python -m src.cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
- `python -m src.cli` — start server (transport via --transport or MCP_TRANSPORT env)
|
|
18
|
+
- `pytest` — pytest suite
|
|
19
|
+
- `ruff check .` — lint
|
|
20
|
+
- `pip-audit` — dependency audit
|
|
21
|
+
- `npx @modelcontextprotocol/inspector python -m src.cli` — MCP Inspector
|
|
22
|
+
|
|
23
|
+
## Tools (registered in src/server.py via FastMCP)
|
|
24
|
+
|
|
25
|
+
| Name | Input | Output | Description |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| `echo` | `text: str` | `str` | Returns input verbatim. Smoke test. |
|
|
28
|
+
|
|
29
|
+
## Prompts
|
|
30
|
+
|
|
31
|
+
| Name | Args | Description |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `summarize` | `text` | Summarize the input text. Placeholder. |
|
|
34
|
+
|
|
35
|
+
## Transports
|
|
36
|
+
|
|
37
|
+
Choose with `--transport stdio|sse|http` or `MCP_TRANSPORT`:
|
|
38
|
+
|
|
39
|
+
- `stdio` (default) — local agents. No port.
|
|
40
|
+
- `sse` — SSE-over-HTTP on `MCP_PORT` (default 3001).
|
|
41
|
+
- `http` — Streamable HTTP on `MCP_PORT` (default 3001).
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
|
|
45
|
+
- `src/server.py` — FastMCP instance, tools and prompts registered with @mcp.tool() / @mcp.prompt().
|
|
46
|
+
- `src/cli.py` — argparse entrypoint, transport dispatch.
|
|
47
|
+
- `src/transports/` — wrappers around mcp.run() calls for the 3 transports.
|
|
48
|
+
- `src/tools/`, `src/prompts/` — module per tool/prompt for organization.
|
|
49
|
+
|
|
50
|
+
## CLI inventory
|
|
51
|
+
|
|
52
|
+
`python -m src.cli --json --list-tools` returns the tool registry as JSON (M-03).
|
|
53
|
+
|
|
54
|
+
## DARE skills
|
|
55
|
+
|
|
56
|
+
See `.dare/skills.yml`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "{{ projectName }}",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "MCP server JSON-RPC surface. MCP is not REST; this describes the HTTP/SSE transport envelopes only."
|
|
7
|
+
},
|
|
8
|
+
"paths": {
|
|
9
|
+
"/sse": {
|
|
10
|
+
"get": {
|
|
11
|
+
"summary": "SSE event stream",
|
|
12
|
+
"responses": { "200": { "description": "text/event-stream with MCP JSON-RPC frames" } }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"/messages": {
|
|
16
|
+
"post": {
|
|
17
|
+
"summary": "MCP JSON-RPC message (HTTP / SSE post-back)",
|
|
18
|
+
"requestBody": {
|
|
19
|
+
"required": true,
|
|
20
|
+
"content": {
|
|
21
|
+
"application/json": { "schema": { "type": "object" } }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"responses": {
|
|
25
|
+
"200": {
|
|
26
|
+
"description": "JSON-RPC 2.0 response",
|
|
27
|
+
"content": { "application/json": { "schema": { "type": "object" } } }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ projectName }}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "DARE-shaped MCP server (Python)"
|
|
5
|
+
requires-python = ">=3.11"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"mcp[cli]>=1.0.0,<2.0",
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
[project.optional-dependencies]
|
|
11
|
+
dev = [
|
|
12
|
+
"pytest>=8.2,<9.0",
|
|
13
|
+
"pytest-asyncio>=0.23,<1.0",
|
|
14
|
+
"ruff>=0.5,<1.0",
|
|
15
|
+
"pip-audit>=2.7,<3.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
{{ projectModule }} = "src.cli:main"
|
|
20
|
+
|
|
21
|
+
[build-system]
|
|
22
|
+
requires = ["hatchling"]
|
|
23
|
+
build-backend = "hatchling.build"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["src"]
|
|
27
|
+
|
|
28
|
+
[tool.ruff]
|
|
29
|
+
line-length = 100
|
|
30
|
+
target-version = "py311"
|
|
31
|
+
|
|
32
|
+
[tool.ruff.lint]
|
|
33
|
+
select = ["E", "F", "I", "B", "UP"]
|
|
34
|
+
ignore = ["E501"]
|
|
35
|
+
|
|
36
|
+
[tool.pytest.ini_options]
|
|
37
|
+
asyncio_mode = "auto"
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""CLI entrypoint — picks transport from --transport or MCP_TRANSPORT env."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from src.server import mcp
|
|
11
|
+
from src.transports import http as http_transport
|
|
12
|
+
from src.transports import sse as sse_transport
|
|
13
|
+
from src.transports import stdio as stdio_transport
|
|
14
|
+
|
|
15
|
+
Transport = Literal["stdio", "sse", "http"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def parse_args(argv: list[str]) -> tuple[Transport, bool]:
|
|
19
|
+
env_default = os.environ.get("MCP_TRANSPORT", "{{ defaultTransport }}")
|
|
20
|
+
parser = argparse.ArgumentParser(description="DARE-shaped MCP server")
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"--transport",
|
|
23
|
+
choices=["stdio", "sse", "http"],
|
|
24
|
+
default=env_default,
|
|
25
|
+
help="Transport (default: %(default)s)",
|
|
26
|
+
)
|
|
27
|
+
parser.add_argument("--json", action="store_true", help="Emit JSON output (use with --list-tools)")
|
|
28
|
+
parser.add_argument("--list-tools", action="store_true", help="List registered tools as JSON and exit")
|
|
29
|
+
ns = parser.parse_args(argv)
|
|
30
|
+
return ns.transport, bool(ns.json and ns.list_tools)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def list_tools_json() -> None:
|
|
34
|
+
# FastMCP keeps an in-memory registry; surface it as a stable JSON shape.
|
|
35
|
+
tools = [
|
|
36
|
+
{
|
|
37
|
+
"name": name,
|
|
38
|
+
"description": (t.description or "").strip(),
|
|
39
|
+
# FastMCP's Tool exposes the JSON schema as `parameters`.
|
|
40
|
+
"inputSchema": t.parameters,
|
|
41
|
+
}
|
|
42
|
+
for name, t in mcp._tool_manager._tools.items() # type: ignore[attr-defined]
|
|
43
|
+
]
|
|
44
|
+
sys.stdout.write(json.dumps({"tools": tools}, indent=2) + "\n")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def main(argv: list[str] | None = None) -> None:
|
|
48
|
+
transport, want_list = parse_args(sys.argv[1:] if argv is None else argv)
|
|
49
|
+
|
|
50
|
+
if want_list:
|
|
51
|
+
list_tools_json()
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
port = int(os.environ.get("MCP_PORT", "3001"))
|
|
55
|
+
host = os.environ.get("MCP_HOST", "0.0.0.0")
|
|
56
|
+
|
|
57
|
+
if transport == "stdio":
|
|
58
|
+
stdio_transport.run(mcp)
|
|
59
|
+
elif transport == "sse":
|
|
60
|
+
sse_transport.run(mcp, host=host, port=port)
|
|
61
|
+
elif transport == "http":
|
|
62
|
+
http_transport.run(mcp, host=host, port=port)
|
|
63
|
+
else: # pragma: no cover — argparse guarantees one of the above
|
|
64
|
+
raise SystemExit(f"invalid transport: {transport}")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Summarize prompt — returns a templated user message."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def summarize(text: str) -> str:
|
|
5
|
+
"""Returns the user message body for a summarize prompt.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
text: Text to summarize.
|
|
9
|
+
"""
|
|
10
|
+
return f"Summarize the following text in 1-2 sentences.\n\n{text}"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""FastMCP server — tools and prompts registered here."""
|
|
2
|
+
from mcp.server.fastmcp import FastMCP
|
|
3
|
+
|
|
4
|
+
from src.tools.echo import echo as echo_impl
|
|
5
|
+
from src.prompts.summarize import summarize as summarize_impl
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
mcp = FastMCP("{{ projectName }}")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@mcp.tool()
|
|
12
|
+
async def echo(text: str) -> str:
|
|
13
|
+
"""Returns its input. Canonical smoke test for an MCP server.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
text: Text to echo back (required, non-empty).
|
|
17
|
+
"""
|
|
18
|
+
return await echo_impl(text)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@mcp.prompt()
|
|
22
|
+
def summarize(text: str) -> str:
|
|
23
|
+
"""Summarize the given text in 1-2 sentences.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
text: Text to summarize.
|
|
27
|
+
"""
|
|
28
|
+
return summarize_impl(text)
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Echo tool implementation — testable as a plain function."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
async def echo(text: str) -> str:
|
|
5
|
+
"""Returns its input verbatim.
|
|
6
|
+
|
|
7
|
+
Raises:
|
|
8
|
+
ValueError: when text is empty or None.
|
|
9
|
+
"""
|
|
10
|
+
if not isinstance(text, str) or not text:
|
|
11
|
+
raise ValueError("text must be a non-empty string")
|
|
12
|
+
return text
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Streamable HTTP transport — modern MCP HTTP wire format.
|
|
2
|
+
|
|
3
|
+
Each client gets its own session keyed by the Mcp-Session-Id header,
|
|
4
|
+
generated on initialize. FastMCP wraps the uvicorn + Starlette plumbing.
|
|
5
|
+
"""
|
|
6
|
+
from mcp.server.fastmcp import FastMCP
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def run(mcp: FastMCP, host: str = "0.0.0.0", port: int = 3001) -> None:
|
|
10
|
+
mcp.settings.host = host
|
|
11
|
+
mcp.settings.port = port
|
|
12
|
+
mcp.run(transport="streamable-http")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""SSE-over-HTTP transport — legacy MCP HTTP wire format.
|
|
2
|
+
|
|
3
|
+
FastMCP launches a uvicorn server under the hood and exposes the SSE
|
|
4
|
+
endpoints. For new deployments prefer the streamable HTTP transport
|
|
5
|
+
(transports/http.py).
|
|
6
|
+
"""
|
|
7
|
+
from mcp.server.fastmcp import FastMCP
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def run(mcp: FastMCP, host: str = "0.0.0.0", port: int = 3001) -> None:
|
|
11
|
+
mcp.settings.host = host
|
|
12
|
+
mcp.settings.port = port
|
|
13
|
+
mcp.run(transport="sse")
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Smoke tests for echo tool and summarize prompt."""
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from src.prompts.summarize import summarize
|
|
5
|
+
from src.tools.echo import echo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.mark.asyncio
|
|
9
|
+
async def test_echo_returns_input():
|
|
10
|
+
assert await echo("hello") == "hello"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.asyncio
|
|
14
|
+
async def test_echo_rejects_empty():
|
|
15
|
+
with pytest.raises(ValueError):
|
|
16
|
+
await echo("")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.mark.asyncio
|
|
20
|
+
async def test_echo_rejects_non_string():
|
|
21
|
+
with pytest.raises(ValueError):
|
|
22
|
+
await echo(None) # type: ignore[arg-type]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_summarize_includes_input_text():
|
|
26
|
+
out = summarize("long text here")
|
|
27
|
+
assert "long text here" in out
|
|
28
|
+
assert "Summarize" in out
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
skills:
|
|
3
|
+
- id: skill-mcp-server
|
|
4
|
+
source: skill-mcp-server
|
|
5
|
+
description: MCP server patterns (tools, prompts, transports)
|
|
6
|
+
- id: dare-ax
|
|
7
|
+
source: dare-ax
|
|
8
|
+
description: Agent eXperience invariants (llms.txt, OpenAPI, --json --list-tools, rate limit)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# MCP transport — overrides --transport flag if set
|
|
2
|
+
# Valid: stdio | sse | http
|
|
3
|
+
MCP_TRANSPORT=stdio
|
|
4
|
+
|
|
5
|
+
# HTTP/SSE transport bind (ignored on stdio)
|
|
6
|
+
MCP_HOST=0.0.0.0
|
|
7
|
+
MCP_PORT=3001
|
|
8
|
+
|
|
9
|
+
# Logging
|
|
10
|
+
RUST_LOG=info
|
|
11
|
+
|
|
12
|
+
# LLM provider (optional)
|
|
13
|
+
LLM_PROVIDER=dummy
|
|
14
|
+
# OPENAI_API_KEY=
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: DARE CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
audit:
|
|
11
|
+
name: cargo audit
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
16
|
+
- uses: Swatinem/rust-cache@v2
|
|
17
|
+
- run: cargo install cargo-audit --locked
|
|
18
|
+
- run: cargo audit --deny warnings
|
|
19
|
+
|
|
20
|
+
lint:
|
|
21
|
+
name: clippy
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
26
|
+
with:
|
|
27
|
+
components: clippy
|
|
28
|
+
- uses: Swatinem/rust-cache@v2
|
|
29
|
+
- run: cargo clippy --all-targets -- -D warnings
|
|
30
|
+
|
|
31
|
+
test:
|
|
32
|
+
name: cargo test
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
37
|
+
- uses: Swatinem/rust-cache@v2
|
|
38
|
+
- run: cargo test
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "{{ crateName }}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
description = "DARE-shaped MCP server (Rust)"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
|
|
8
|
+
[dependencies]
|
|
9
|
+
# Official Rust MCP SDK. API still stabilizing — pin a rev if upstream breaks.
|
|
10
|
+
rmcp = { version = "0.1", features = ["server", "transport-io"] }
|
|
11
|
+
|
|
12
|
+
tokio = { version = "1", features = ["full"] }
|
|
13
|
+
serde = { version = "1", features = ["derive"] }
|
|
14
|
+
serde_json = "1"
|
|
15
|
+
|
|
16
|
+
# HTTP/SSE transports
|
|
17
|
+
axum = { version = "0.7", features = ["macros"] }
|
|
18
|
+
tower-http = { version = "0.6", features = ["cors"] }
|
|
19
|
+
|
|
20
|
+
# CLI args
|
|
21
|
+
clap = { version = "4", features = ["derive", "env"] }
|
|
22
|
+
|
|
23
|
+
# Logging
|
|
24
|
+
tracing = "0.1"
|
|
25
|
+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
26
|
+
|
|
27
|
+
anyhow = "1"
|
|
28
|
+
thiserror = "1"
|
|
29
|
+
|
|
30
|
+
[dev-dependencies]
|
|
31
|
+
tokio-test = "0.4"
|
|
32
|
+
|
|
33
|
+
[[bin]]
|
|
34
|
+
name = "{{ crateName }}"
|
|
35
|
+
path = "src/main.rs"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# {{ projectName }}
|
|
2
|
+
|
|
3
|
+
DARE-shaped MCP server in Rust using the `rmcp` SDK.
|
|
4
|
+
Default transport: **{{ defaultTransport }}**.
|
|
5
|
+
|
|
6
|
+
> ⚠️ **Beta.** The `rmcp` SDK API is still stabilizing. Pin a specific version
|
|
7
|
+
> or git rev in `Cargo.toml` if an upstream release breaks the build.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cp .env.example .env
|
|
13
|
+
cargo build
|
|
14
|
+
cargo run # uses {{ defaultTransport }} transport by default
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Test with MCP Inspector
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @modelcontextprotocol/inspector cargo run
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Tools
|
|
24
|
+
|
|
25
|
+
- `echo` — returns its input. Canonical smoke test.
|
|
26
|
+
|
|
27
|
+
## Prompts
|
|
28
|
+
|
|
29
|
+
- `summarize` — placeholder prompt template taking a `text` argument.
|
|
30
|
+
|
|
31
|
+
## Transports
|
|
32
|
+
|
|
33
|
+
Pick at runtime via `--transport stdio|sse|http` or `MCP_TRANSPORT`:
|
|
34
|
+
|
|
35
|
+
| Transport | When to use |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `stdio` (default) | Local CLI agents |
|
|
38
|
+
| `sse` | Web clients via SSE (axum) |
|
|
39
|
+
| `http` | Streamable HTTP (axum) |
|
|
40
|
+
|
|
41
|
+
## Commands
|
|
42
|
+
|
|
43
|
+
- `cargo run` — start server
|
|
44
|
+
- `cargo test` — tests
|
|
45
|
+
- `cargo clippy -- -D warnings` — lint
|
|
46
|
+
- `cargo audit` — dependency audit
|
|
47
|
+
|
|
48
|
+
## DARE Method
|
|
49
|
+
|
|
50
|
+
See `.dare/skills.yml` and `llms.txt`.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# {{ projectName }}
|
|
2
|
+
|
|
3
|
+
DARE-shaped MCP server (Rust, rmcp SDK). Default transport: **{{ defaultTransport }}**. BETA.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cp .env.example .env
|
|
9
|
+
cargo build
|
|
10
|
+
cargo run
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
- `cargo run` — start server (transport via --transport or MCP_TRANSPORT env)
|
|
16
|
+
- `cargo test` — tests
|
|
17
|
+
- `cargo clippy -- -D warnings` — lint
|
|
18
|
+
- `cargo audit` — RustSec advisory audit
|
|
19
|
+
- `npx @modelcontextprotocol/inspector cargo run` — MCP Inspector
|
|
20
|
+
|
|
21
|
+
## Tools (registered in src/server.rs)
|
|
22
|
+
|
|
23
|
+
| Name | Input | Output | Description |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| `echo` | `text: String` | `String` | Returns input verbatim. Smoke test. |
|
|
26
|
+
|
|
27
|
+
## Prompts
|
|
28
|
+
|
|
29
|
+
| Name | Args | Description |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `summarize` | `text` | Summarize the input text. Placeholder. |
|
|
32
|
+
|
|
33
|
+
## Transports
|
|
34
|
+
|
|
35
|
+
Choose with `--transport stdio|sse|http` or `MCP_TRANSPORT`:
|
|
36
|
+
|
|
37
|
+
- `stdio` (default) — local agents. No port.
|
|
38
|
+
- `sse` — SSE-over-HTTP on MCP_PORT (default 3001), served by axum.
|
|
39
|
+
- `http` — Streamable HTTP on MCP_PORT, served by axum.
|
|
40
|
+
|
|
41
|
+
## Architecture
|
|
42
|
+
|
|
43
|
+
- `src/main.rs` — tokio entrypoint, parses args, dispatches transport.
|
|
44
|
+
- `src/server.rs` — builds the rmcp service with tools + prompts.
|
|
45
|
+
- `src/cli.rs` — clap arg parser + Transport enum + --list-tools.
|
|
46
|
+
- `src/transports/{stdio,sse,http}.rs` — one runner per transport.
|
|
47
|
+
- `src/tools/`, `src/prompts/` — pure functions, unit-tested.
|
|
48
|
+
|
|
49
|
+
## CLI inventory
|
|
50
|
+
|
|
51
|
+
`cargo run -- --json --list-tools` prints the tool registry as JSON (M-03).
|
|
52
|
+
|
|
53
|
+
## Note on beta status
|
|
54
|
+
|
|
55
|
+
`rmcp` is the official Rust MCP SDK but its API is pre-1.0. If a `cargo build`
|
|
56
|
+
fails after a dependency update, pin `rmcp` to a known-good version in Cargo.toml.
|
|
57
|
+
|
|
58
|
+
## DARE skills
|
|
59
|
+
|
|
60
|
+
See `.dare/skills.yml`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "{{ projectName }}",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "MCP server JSON-RPC surface. MCP is not REST; this describes the HTTP/SSE transport envelopes only."
|
|
7
|
+
},
|
|
8
|
+
"paths": {
|
|
9
|
+
"/sse": {
|
|
10
|
+
"get": {
|
|
11
|
+
"summary": "SSE event stream",
|
|
12
|
+
"responses": { "200": { "description": "text/event-stream with MCP JSON-RPC frames" } }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"/messages": {
|
|
16
|
+
"post": {
|
|
17
|
+
"summary": "MCP JSON-RPC message (HTTP / SSE post-back)",
|
|
18
|
+
"requestBody": {
|
|
19
|
+
"required": true,
|
|
20
|
+
"content": { "application/json": { "schema": { "type": "object" } } }
|
|
21
|
+
},
|
|
22
|
+
"responses": {
|
|
23
|
+
"200": {
|
|
24
|
+
"description": "JSON-RPC 2.0 response",
|
|
25
|
+
"content": { "application/json": { "schema": { "type": "object" } } }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//! CLI argument parsing — transport selection + tool inventory.
|
|
2
|
+
use clap::{Parser, ValueEnum};
|
|
3
|
+
|
|
4
|
+
#[derive(Debug, Clone, Copy, ValueEnum)]
|
|
5
|
+
pub enum Transport {
|
|
6
|
+
Stdio,
|
|
7
|
+
Sse,
|
|
8
|
+
Http,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[derive(Debug, Parser)]
|
|
12
|
+
#[command(name = "{{ projectName }}", version, about = "DARE-shaped MCP server")]
|
|
13
|
+
pub struct Cli {
|
|
14
|
+
/// Transport to serve on. Overridden by MCP_TRANSPORT env if that is set.
|
|
15
|
+
#[arg(long, value_enum, default_value = "{{ defaultTransport }}", env = "MCP_TRANSPORT")]
|
|
16
|
+
pub transport: Transport,
|
|
17
|
+
|
|
18
|
+
/// Bind host for sse/http transports.
|
|
19
|
+
#[arg(long, default_value = "0.0.0.0", env = "MCP_HOST")]
|
|
20
|
+
pub host: String,
|
|
21
|
+
|
|
22
|
+
/// Bind port for sse/http transports.
|
|
23
|
+
#[arg(long, default_value_t = 3001, env = "MCP_PORT")]
|
|
24
|
+
pub port: u16,
|
|
25
|
+
|
|
26
|
+
/// Emit machine-readable JSON (use with --list-tools).
|
|
27
|
+
#[arg(long)]
|
|
28
|
+
pub json: bool,
|
|
29
|
+
|
|
30
|
+
/// List registered tools as JSON and exit (M-03).
|
|
31
|
+
#[arg(long)]
|
|
32
|
+
pub list_tools: bool,
|
|
33
|
+
}
|