# specpack **Lint and generate the files your AI coding agent reads** — `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, Cursor rules — and turn a project description into a full build spec. CLI, library and MCP server. ```bash npx specpack audit # bloat score for the agent files in this repo (offline) npx specpack init # write a lean AGENTS.md from your manifests (offline) npx specpack spec --describe "Booking app for dog groomers with deposits and SMS reminders" ``` [![npm](https://img.shields.io/npm/v/specpack.svg)](https://www.npmjs.com/package/specpack) [![CI](https://github.com/THE-KIPDEV/specpack/actions/workflows/ci.yml/badge.svg)](https://github.com/THE-KIPDEV/specpack/actions/workflows/ci.yml) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) `CLAUDE.md` / `AGENTS.md` are loaded into the agent's context **on every session**. Every line that restates `package.json`, pastes a file tree or tells the model to "write clean code" costs tokens and competes with the two rules that actually matter. `specpack audit` finds those lines; `specpack init` starts you at the trimmed end. Node ≥ 18. No account needed. `audit` and `init` never touch the network. --- ## `specpack audit` — how much of your memory file does nothing? Each line is classified **keep**, **cut** (removing it changes nothing: role-play preamble, generic advice, restated manifests, duplicates, emphasis inflation, prose) or **offload** (true but situational: file trees, schema dumps, endpoint lists, long code blocks, setup/deploy sections — move them to their own file and reference them with `@docs/…`). Same rules as the browser tool at [prompt-generator-website.com/claude-md-audit](https://prompt-generator-website.com/claude-md-audit). Real output on a typical file: ```text $ npx specpack audit CLAUDE.md CLAUDE.md 59% bloat · 44 lines · ~341 tokens every session 10 keep · 12 cut · 15 offload of 37 non-empty lines · ceiling 200, trimmed files land near 60 Over half of this file is doing nothing. It is not neutral weight — it is what your real rules are competing against. 3 cut You are an expert senior full-stack developer with 10 years of experience. ↳ role-play preamble: CLAUDE.md is project memory, not a system prompt. "You are an expert…" costs tokens and changes nothing about the code produced. 4 cut Please always write clean, readable and maintainable code. ↳ default behaviour: Removing this line does not make the model write worse code — it already tries to do this. It only dilutes the lines that matter. 5 cut IMPORTANT: follow best practices at all times. … 12 cut - Next.js 15.1 ↳ restates a manifest: package.json / composer.json / requirements.txt already state this, and the agent reads them. Keep it only if the version pin has a non-obvious reason. … 18 offload ## Database schema ↳ situational section: Only a fraction of your sessions need this. Move the section to its own file and point at it with @docs/… so it loads when the task asks for it. … 31 offload src/ ↳ file tree: Root of a pasted directory tree. The agent can run ls and get the real one — a copy goes stale after the first refactor. … Trimmed copy (8 lines): specpack audit CLAUDE.md --trimmed ``` Without arguments it audits every agent file in the current directory: `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.windsurfrules`, `.github/copilot-instructions.md`, `CLAUDE.local.md`, `.cursor/rules/*.mdc`. `-` reads stdin. | Option | | |---|---| | `--trimmed` | print only the keep-only version (`> CLAUDE.trimmed.md`) | | `--json` | every line with verdict, rule and reason, plus stats and the trimmed file | | `--all` | also list the kept lines and why | | `--max-bloat ` | exit code 1 when a file is above the threshold | ### In CI ```yaml # .github/workflows/agent-files.yml name: Agent files on: [pull_request] jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npx -y specpack audit --max-bloat 30 ``` ## `specpack init` — a lean AGENTS.md from what the repo already says Reads `package.json` (scripts, lockfile → package manager, framework), `tsconfig.json`, the Prisma schema, `pyproject.toml` / `requirements*.txt` (uv, Poetry), `composer.json`, `go.mod`, `Cargo.toml`, `Gemfile`, `Makefile`, Docker Compose, `.nvmrc`, `.env.example`, `.claude/commands`. Only what a file states is written: nothing is guessed, no patch versions, no "You are an expert" preamble. Sections with nothing detected are left out. Real output on a Next.js + Prisma repository: ```text $ npx specpack init ✓ Wrote AGENTS.md (37 lines, 0% bloat) Scanned from package.json, tsconfig.json, prisma/schema.prisma, .nvmrc, docker-compose.yml, .env.example, .gitignore, .claude/commands/. ``` ```markdown # AGENTS.md — ledgerly Invoicing app for freelancers. A web application. ## Stack - Next.js (App Router) - Tailwind CSS - Zod - Stripe - Vitest - Playwright - ESLint - TypeScript (strict) - Prisma + PostgreSQL (schema: prisma/schema.prisma) - Local services via Docker Compose (docker-compose.yml): db ## Commands - `pnpm dev` — `next dev --turbopack -p 3001` (port 3001) - `pnpm build` — `next build` - `pnpm start` — `next start` - `pnpm test` — `vitest run` - `pnpm test:e2e` — `playwright test` - `pnpm lint` — `next lint` - `pnpm db:migrate` — `prisma migrate dev` - `pnpm db:seed` — `tsx prisma/seed.ts` - `docker compose up -d` ## Project rules These are things the agent cannot guess from the code. Follow them exactly. - Use pnpm (pnpm-lock.yaml), not npm or yarn — another package manager ignores the lockfile. - Runtime: Node 20 (.nvmrc). - Environment variables are listed in `.env.example`; the real `.env` is git-ignored — do not commit it. ``` Then add the rules only you know under **Project rules** — that is the part that matters. | Option | | |---|---| | `--format agents` | `AGENTS.md` (default) | | `--format claude` | `CLAUDE.md` — imports `@AGENTS.md` when it exists, plus Claude Code specifics (slash commands, `.mcp.json` servers) | | `--format cursor` | `.cursor/rules/project.mdc` (always-applied rule) | | `--format all` | the three | | `--dry-run` / `--force` | preview / overwrite (existing files are never overwritten otherwise) | ## `specpack spec` — a full build spec for a new project For a project that does not exist yet, [prompt-generator-website.com](https://prompt-generator-website.com) turns a questionnaire (7 project types: SaaS, e-commerce, business site, marketplace, blog, web app, landing page) into a complete specification — stack, database schema, authentication, type-specific features, pages, design, SEO, security, legal, deployment, file structure — plus `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/project.mdc`, `.cursorrules`, `.windsurfrules` and `.github/copilot-instructions.md` that keep the agent on-spec for the whole build. ```bash # AI drafts the answers from a description (10–40 s), then the spec is generated npx specpack spec --describe "Booking app for dog groomers with deposits and SMS reminders" --out ./groombook # your own answers (see GET /questions in the API) npx specpack spec --answers answers.json --type saas # or answer the questionnaire in the terminal npx specpack spec ``` The spec engine is deterministic: the same answers always give the same bytes. Free without an account: **2 specs and 3 AI drafts**. More: a 7-day Pass or Pro at [prompt-generator-website.com/pricing](https://prompt-generator-website.com/pricing); then `specpack login pgw_…` (or `SPECPACK_API_KEY`). `specpack whoami` shows what is left. ## MCP server Seven tools for Claude Code, Cursor, Windsurf, VS Code and any MCP client: | Tool | Where it runs | | |---|---|---| | `audit_agent_file` | local | bloat score, lines to cut/offload with reasons, trimmed copy | | `draft_agent_file` | local | lean AGENTS.md / CLAUDE.md / Cursor rule from the manifests (returns it, writes nothing) | | `list_project_types` | API | the 7 project types | | `get_questionnaire` | API | every question for a type; **the agent fills it from the conversation and the repo** | | `generate_spec` | API | spec + agent files, written to `output_dir` if given (`files` picks which). No AI on the server | | `draft_answers` | API | AI fills the questionnaire from a description (uses an AI draft) | | `get_usage` | API | plan and what is left | **Claude Code** ```bash claude mcp add specpack -- npx -y specpack mcp ``` **Cursor** (`.cursor/mcp.json`), **Windsurf**, **Claude Desktop** ```json { "mcpServers": { "specpack": { "command": "npx", "args": ["-y", "specpack", "mcp"], "env": { "SPECPACK_API_KEY": "" } } } } ``` **Remote, nothing to install** (streamable HTTP; `audit_agent_file` and `draft_agent_file` read local files, so they only exist in the local server): `https://prompt-generator-website.com/mcp` — optional header `Authorization: Bearer pgw_…`. ```bash claude mcp add --transport http specpack https://prompt-generator-website.com/mcp ``` ## Library ```ts import { audit, scanProject, renderAgentsMd, SpecpackClient } from "specpack"; const { stats, lines, trimmed } = audit(fs.readFileSync("CLAUDE.md", "utf8")); console.log(`${stats.bloat}% bloat`, lines.filter((l) => l.verdict === "cut").length, "lines to cut"); const agentsMd = renderAgentsMd(scanProject(".")); const client = new SpecpackClient({ apiKey: process.env.SPECPACK_API_KEY }); const draft = await client.draft("A booking app for dog groomers"); const spec = await client.createSpec(draft.type, draft.answers); // spec.spec, spec.files["AGENTS.md"]… ``` `createMcpServer()` is exported from `specpack/mcp`. API errors are `SpecpackError` with `code` (`quota_exceeded`, `unauthorized`, `invalid_request`, …), `status` and `upgradeUrl`. ## Reference - Exit codes: `0` ok · `1` failure, or `--max-bloat` exceeded · `2` usage error or quota exceeded. - Environment: `SPECPACK_API_KEY`, `SPECPACK_API_URL` (testing), `NO_COLOR`. - Key storage: `~/.config/specpack/config.json` (`$XDG_CONFIG_HOME` honoured), mode 600. - HTTP API: [API-V1.md](https://prompt-generator-website.com/API-V1.md). - Privacy: `audit` and `init` read local files and send nothing. `spec` sends your answers or description to prompt-generator-website.com. ## License MIT © Kipdev