@oatbox/create-mcp-server
v0.1.2
Published
Scaffold a working MCP server (Streamable HTTP / JSON-RPC 2.0) in under 15 minutes. Drop-in template with 4 example tools showcasing sync, side-effect, progress-streaming, and async-job patterns.
Maintainers
Readme
@oatbox/create-mcp-server
Scaffold a working MCP server (Streamable HTTP / JSON-RPC 2.0) in under 15 minutes.
Drops a self-contained Node + TypeScript project on disk with four example tools showcasing every common MCP pattern (read-only sync, side-effecting with consent, progress-streaming, async-job), a Dockerfile + docker-compose.yaml, a vitest test suite, and an optional GitHub Actions CI workflow.
Usage
npx @oatbox/create-mcp-server my-server
cd my-server
npm install
npm run devOr non-interactively (for CI / programmatic use):
npx @oatbox/create-mcp-server my-server --yes --auth bearerFlags
| Flag | Default | Notes |
| --- | --- | --- |
| [name] (positional) | my-mcp-server | Server / folder name. |
| --name <str> | — | Same as positional. |
| --display <str> | title-case of --name | Display title for serverInfo. |
| --auth <none\|bearer\|oauth> | bearer | OAuth ships placeholder middleware — wire to your IdP. |
| --tools <csv> | all four | read-only,side-effecting,progress,async-job |
| --docker / --no-docker | yes | Include Dockerfile + docker-compose.yaml. |
| --ci / --no-ci | yes | Include .github/workflows/test.yml. |
| --port <n> | 3000 | Local listen port. |
| --output <dir> | ./<name> | Override target directory. |
| --force | — | Overwrite a non-empty target. |
| --yes, -y | — | Accept defaults / flag values; skip prompts. |
| --help, -h | — | Show help. |
What you get
my-server/
├── package.json
├── tsconfig.json
├── Dockerfile
├── docker-compose.yaml
├── .env.example
├── .gitignore
├── .github/workflows/test.yml
├── README.md
├── src/
│ ├── server.ts # Streamable HTTP server (~280 LOC, no deps)
│ ├── tools.ts # tool registry
│ └── tools/
│ ├── lookup-widget.ts
│ ├── flag-widget-issue.ts
│ ├── long-running-export.ts
│ └── async-widget-job.ts
└── tests/
└── tools.test.ts # 5+ vitest cases (handshake + per-tool)The generated server speaks the same JSON-RPC 2.0 transport as oatbox's built-in demo MCP server at /api/mcp/demo, so it plugs into an oatbox workspace via MCP servers → Connect a server with zero adapter code.
How it works
- CLI prompts collect answers (or
--yesaccepts defaults). - The scaffolder copies
templates/default/into the target directory. - Placeholders are substituted in-place — server name, port, auth type, the tool registry, README content.
- Per-tool files are filtered: only the selected
--toolsare copied. - Conditional files (Docker, CI workflow) are skipped if disabled.
Programmatic API
import { scaffold } from "@oatbox/create-mcp-server"
await scaffold({
targetDir: "/tmp/my-server",
answers: {
serverName: "my-server",
displayName: "My Server",
toolKits: ["read-only", "async-job"],
authType: "bearer",
includeDocker: false,
includeCi: false,
port: 4000,
},
})This is used by oatbox Wave 12 (AI-assisted MCP authoring) to generate a server in-memory from an OpenAPI spec.
Publishing checklist
This package is not published to npm by default. To publish a release:
- Bump
versioninpackage.json. npm run lint && npm test && npm run build— all green.- Verify
dist/bin/cli.jshas a#!/usr/bin/env nodeshebang (TypeScript preserves it viabin/cli.ts). npm packand inspect the tarball — confirmtemplates/ships underfiles.npm publish --access public.- Smoke-test the published artifact:
npx -y @oatbox/create-mcp-server@latest test-it --yes cd test-it && npm install && npm test
Until publish: callers can run the CLI from the monorepo with node packages/create-oatbox-mcp-server/dist/bin/cli.js.
Security
This package does not execute any code at install time, has zero runtime dependencies, and creates a self-contained project on disk with no opaque generated code. The scaffolded server has only tsx / typescript / vitest as dev dependencies.
Report security issues privately to [email protected] — see the Security Policy.
Changelog
See CHANGELOG.md.
License
MIT.
