Skip to main content
Glama
README.md
# mcpnew

[![Test](https://github.com/stealth-alpha/mcpnew/actions/workflows/test.yml/badge.svg)](https://github.com/stealth-alpha/mcpnew/actions/workflows/test.yml)

**Scaffold secure-by-default MCP servers** — TypeScript or JavaScript, with deny-all permissions, typed tool stubs, and audit hooks pre-wired.

## The problem

Every hand-rolled MCP server starts the same way: copy a demo from the docs, register tools as you go, and hope nobody asks "wait, can that tool read my home directory?" Permissions end up allow-all by accident. Audit logging is a TODO. Input schemas drift from handlers.

`mcpnew` inverts the default. Every capability your server exposes starts **denied**, every tool call flows through an **audit hook**, and every tool stub is **typed once** at the schema level.

## Install

```bash
npm install -g mcpnewcli
```

Zero runtime dependencies. Node 18+.

## 30-second quickstart

```bash
# 1. Scaffold (JavaScript default; add --lang ts for TypeScript)
mcpnew create my-server && cd my-server && npm install

# 2. Add a typed tool stub — it lands DENIED in mcp.permissions.json
npx mcpnewcli add-tool search-files

# 3. Review, implement, then explicitly allow:
#    "tools": { "search-files": "allow" }

# 4. Keep yourself honest
npx mcpnewcli audit
```

That's it. `mcpnew audit` fails non-zero if the manifest stops being deny-all, if any registered tool lacks its `requireAllowed()` gate, or if audit hooks are unwired — wire it into CI and stay secure by construction.

## Wire it into CI

Drop this into the scaffolded server's repo (`.github/workflows/audit.yml`):

```yaml
name: mcp-security-audit
on: [push, pull_request]
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npx --yes mcpnewcli audit
```

Any finding — a loosened default, an ungated tool, an unwired hook — exits
non-zero and fails the check before it can merge.

## What you get

```
my-server/
├── src/server.js          # MCP server: typed tool stubs + permission gates + audit hooks
├── src/audit.js           # JSONL audit trail → logs/audit.jsonl (gitignored)
├── src/manifest.js        # manifest loader (+ TS types on --lang ts)
├── test/server.test.js    # tests asserting the deny-all posture holds
└── mcp.permissions.json   # deny-all permission manifest — the source of truth
```

- **Deny-all permissions** — tools, resources, prompts, network, filesystem: everything defaults to `deny`. Wildcards are rejected outright.
- **Typed tool stubs** — `mcpnew add-tool <name>` inserts a zod-schema'd stub wired through the gate and the audit hook. You write the body; the scaffolding is already correct.
- **Audit hooks pre-wired** — every call logs timestamp, tool, args, outcome, and duration to `logs/audit.jsonl`.

## Config

The generated `mcp.permissions.json`:

```json
{
  "version": 1,
  "default": "deny",
  "tools": { "ping": "deny" },
  "resources": { "default": "deny" },
  "prompts": { "default": "deny" },
  "network": { "default": "deny", "allowlist": [] },
  "filesystem": { "default": "deny", "paths": [] }
}
```

Flip entries to `"allow"` deliberately, one at a time, after reading what the tool does. `mcpnew audit` verifies you haven't loosened more than you meant to.

## Pro

Shipping MCP servers to production teams? **mcpnew Pro** ($9/mo) adds policy-as-code review workflows: pull-request diffs of permission manifests with required sign-off before any `deny` flips to `allow`, org-wide audit-log shipping (Splunk/Datadog/Loki), and a compliance report mapping each tool grant to its approval record. One tier, no seat math. License via Gumroad — link placeholder.

## License

MIT

---

Part of the [stealth-alpha toolkit](https://stealth-alpha.github.io/toolkit/) — eight zero-dependency CLIs for release automation, agent security, and repo hygiene.

Maintenance

ActivityMaintained
ResponsivenessNo issues