npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

promptdiet

v0.3.0

Published

Token-optimizing MCP server for Cursor. Give your AI IDE access to specialized code agents backed by AST skeletonization and Eco-Telemetry.

Readme

PromptDiet

Token-optimizing MCP server for Cursor. Give your AI IDE access to specialized code agents that review, refactor, generate, and test your code — without burning tokens on routing decisions or shipping full file contents to the API.

No API keys or external LLM calls — PromptDiet builds token-efficient skeleton + git context locally; use that output with Cursor or any model you choose.

npm version License: MIT


The Problem

Every time you paste code into ChatGPT or Claude to refactor, review, or explain it, you pay twice:

  1. Routing cost — The model spends tokens figuring out what kind of task this is
  2. Context cost — Your entire file(s) get sent, including comments, whitespace, and boilerplate the model doesn't need

A single 500-line TypeScript file can burn 15,000–50,000 tokens per turn. Repeated across a sprint, that's real money and real latency.

The Solution

PromptDiet is an MCP server that:

  • Zero-token routing — Cursor's AI parses your intent and calls the correct tool directly. No LLM is consulted for routing.
  • AST skeletonization — Only class/function signatures, imports, and docstrings are sent (~85% token reduction)
  • SQLite Agile board — Persistent Kanban state in .promptdiet/state.db (sql.js, pure WebAssembly)
  • Depth-1 dependency traversal — Local imports are skeletonized to prevent LLM hallucinations about your data models
  • Eco-Telemetry — Every call returns a token audit: naive vs. optimized count, cost savings, and water offset

Architecture

The Model Context Protocol (MCP) fundamentally changes how PromptDiet works. Instead of a CLI that parses commands, PromptDiet is a server that Cursor's AI talks to directly.

┌─────────────────────────────────────────────┐
│  CURSOR IDE                                 │
│                                             │
│  @promptdiet refactor src/auth/middleware.ts │
└────────────────┬────────────────────────────┘
                 │
                 │  JSON-RPC (stdio)
                 ▼
┌─────────────────────────────────────────────┐
│  PROMPTDIET MCP SERVER                      │
│                                             │
│  • Cursor sends natural language request     │
│  • PromptDiet skeletonizes the code         │
│  • PromptDiet assembles skeleton + git context │
│  • PromptDiet returns markdown handoff + eco-telemetry │
└────────────────┬────────────────────────────┘
                 │
                 │  JSON-RPC Response
                 ▼
┌─────────────────────────────────────────────┐
│  CURSOR IDE (Native Rendering)              │
│                                             │
│  • Use handoff in chat (no server apply)   │
│  • Markdown explanation in chat             │
│  • Eco-Telemetry table in chat              │
└─────────────────────────────────────────────┘

Installation

npm install -g promptdiet

Requirements: Node.js ≥ 18

Cursor Setup

  1. Open Cursor Settings → MCP
  2. Add a new MCP server:
    {
      "mcpServers": {
        "promptdiet": {
          "command": "npx",
          "args": ["-y", "promptdiet"]
        }
      }
    }

Usage

In Cursor Chat

Recommended: use flow for one freeform request; PromptDiet infers agent and operation (rule-based), assembles a markdown handoff (agent persona, repo rules, skeleton, git, telemetry), and optionally your job-board ticket. apply is ignored — PromptDiet never writes patches; you implement changes in Cursor.

@promptdiet flow --request "Refactor this for security" --target_path src/auth/middleware.ts
@promptdiet flow --request "Audit this" --ticket_id <uuid> --target_path src/auth/middleware.ts
@promptdiet run_agent --agent code-reviewer --target src/auth/middleware.ts --operation review
@promptdiet get_board_state
@promptdiet list_agents
@promptdiet init_board
@promptdiet create_ticket --type epic --title "My Epic" --description "Description" --tags auth,security
@promptdiet update_ticket --ticket_id <id> --type story --state IN_PROGRESS
@promptdiet delete_ticket --ticket_id <id> --type epic

MCP Tools

flow

Recommended Cursor entrypoint: one freeform request, optional target_path, optional ticket_id, optional apply (legacy, ignored).

  • Target path: use target_path, or include a path in request (e.g. src/foo.ts). If no path exists yet, greenfield mode still returns a handoff with a placeholder skeleton.
  • Ticket: if ticket_id is set, loads epic/story from .promptdiet/state.db; tags drive agent selection; title, description, and acceptance criteria are appended to instructions (truncated to ~2500 characters).
  • Routing: keyword/tag heuristics pick agent_id and operation — no routing LLM.
  • Ambiguity: if multiple agents tie, the tool returns a fenced question signal (JSON: status, reason, options, instruction). Use Cursor’s question UI to clarify, then call flow again.
  • Apply: always ignored; no filesystem writes from PromptDiet.
{
  "request": "Refactor this module for clarity and add edge-case tests",
  "target_path": "src/auth/middleware.ts",
  "ticket_id": "optional-uuid",
  "apply": false
}

run_agent

Lower-level tool: explicit operation and path. Agent is auto-selected based on ticket_id tags if not specified.

Returns a markdown handoff (full systemPrompt, repo rules, skeleton, optional extra context from context_paths, git) plus eco-telemetry. apply is ignored. Use include_dependencies: true for depth-1 import skeletons on the primary file.

{
  "agent_id": "code-reviewer",
  "ticket_id": "optional-ticket-id",
  "target_path": "src/auth/middleware.ts",
  "operation": "review",
  "instructions": "Focus on security vulnerabilities",
  "greenfield": false,
  "context_paths": ["src/types/auth.ts"],
  "include_dependencies": false,
  "apply": false
}

Typical response shape:

  • explanation — Full handoff markdown for Cursor’s model
  • eco_telemetry — Token savings report (embedded in the markdown table)

init_board

Initialize a new PromptDiet Agile board in the current directory.

{
  "force": false
}

create_ticket

Create a new Epic or Story in the PromptDiet Agile board.

{
  "type": "epic",
  "title": "JWT Authentication",
  "description": "Implement JWT-based authentication",
  "tags": ["auth", "security"],
  "effort_points": 5
}

update_ticket

Update an existing Epic or Story.

{
  "ticket_id": "<uuid>",
  "type": "story",
  "state": "IN_PROGRESS",
  "tags": ["auth", "review"]
}

delete_ticket

Delete an Epic or Story.

{
  "ticket_id": "<uuid>",
  "type": "epic"
}

get_board_state

Read the current Agile board state.

{
  "epic_id": "optional-filter-id",
  "view": "kanban"
}

Views: kanban (default), list, sprint

goal_orchestrate

Rule-based goal breakdown (keyword templates, no external LLM). Returns ordered epic/story plan as markdown. Set persist: true to create tickets in .promptdiet/state.db (requires init_board first).

{
  "goal": "Ship a small calculator web app with tests",
  "persist": false
}

list_agents

List all available agents.

{}

Core Concepts

Zero-Token Routing

Cursor's AI parses your intent. For most tasks, call the flow tool with a natural-language request; PromptDiet infers agent_id and operation locally. For explicit control, use run_agent with fixed arguments. No LLM is consulted for routing — zero tokens burned.

Tag-Based Agent Routing

When using ticket_id without agent_id, PromptDiet automatically selects the best agent based on ticket tags:

| Ticket Tags | Auto-Selected Agent | |-------------|---------------------| | auth, security, review, audit | code-reviewer | | refactor, restructure, optimize | refactorer | | tests, coverage, quality | test-writer | | security, audit, compliance | security-scanner | | perf, optimize, performance | perf-optimizer |

AST Skeletonization

Instead of sending full file contents:

// FULL FILE (what you'd paste into ChatGPT)
async function authenticateUser(req, res) {
  // 50 lines of implementation, comments, etc.
  // ...
}

// SKELETON (what PromptDiet sends)
async function authenticateUser(
  req: Request,
  res: Response
): Promise<AuthResult> { /* ... */ }

Only signatures, parameter types, return types, decorators, and docstrings are extracted. Function bodies are excluded.

Depth-1 Dependency Traversal

For TypeScript/JavaScript files, PromptDiet also traverses local relative imports one hop deep:

src/auth/middleware.ts
  └── imports ./models/User  →  parses src/models/User.ts
                                extracts: interface User { id, email, role }
                                blocks:   node_modules, react, express

Conventional Commit Git Context

Only meaningful commits are injected:

// Kept: feat:, fix:, refactor:, perf:
// Dropped: chore:, style:, docs:, ci:

gitContext = {
  recentRelevantTags: ["feat: add JWT middleware", "refactor: extract auth util"],
  modifiedFiles: [{ status: "M", path: "src/auth/middleware.ts" }]
}

Eco-Telemetry

Every successful call returns a token audit rendered by Cursor in the chat:

═══════════════════════════════════════════
 PromptDiet Eco-Telemetry
═══════════════════════════════════════════
 Naive token estimate     31,204 tokens
 Optimized token count    4,812 tokens
 Tokens saved            26,392 tokens  (84.6%)
 Estimated cost saved    $0.0023        (ref. $0.10/1K)
 Water offset            0.087 mL       (WUE: 0.0033 mL/token)
═══════════════════════════════════════════
 *WUE heuristic based on Li et al. (2023) average datacenter metrics.
═══════════════════════════════════════════

WUE Citation: Water offset is computed using the baseline from Li et al. (2023), "Making AI Less Thirsty: Characterizing and Estimating Data Center Water Usage for Large Language Models". The 0.0033 mL/token heuristic reflects average datacenter Water Usage Effectiveness (WUE) across Google's fleet.


Agent Catalog

Five agents ship by default:

| ID | Name | Tags | Operations | |----|------|------|------------| | code-reviewer | Code Reviewer | auth, security, review, audit | review, audit | | refactorer | Refactorer | refactor, restructure, optimize | refactor, optimize | | test-writer | Test Writer | tests, coverage, quality | write-tests | | security-scanner | Security Scanner | security, audit, compliance | audit, security-scan | | perf-optimizer | Performance Optimizer | perf, optimize, performance | optimize, profile |

Each agent is defined in agents.yaml with a systemPrompt, supportedOperations, and tags[].


Configuration

.promptdiet/ directory structure:

.promptdiet/
├── state.db           # SQLite database (sql.js WebAssembly)
├── agents.yaml        # Agent definitions (systemPrompt, tags, operations)
├── instructions.md    # Optional — merged into handoffs (see repo rules)
└── .gitignore         # (created by init)

Repo rules (handoff): first file found among .promptdiet/instructions.md, PROMPTDIET_RULES.md (repo root), .cursorrules.

Environment variables:

PROMPTDIET_NO_ECHO=1                   # Suppress eco-telemetry
PROMPTDIET_GIT_LOG_N=20                # Commits scanned for relevant messages (1–100, default 20)
PROMPTDIET_COMMIT_TAGS=feat:,fix:      # Comma-separated lowercase prefixes to treat as “relevant” commits

Development

See DEV_TESTING.md for detailed testing instructions.

Quick Test

npm run build          # Compile TypeScript
npm run start:dev      # Run dev mode test

Build

npm run build    # Compile TypeScript
npm start        # Run the MCP server

Architecture (Internal)

MCP Server (src/server.ts)
    │
    ├── MCP Handlers (src/mcp/handlers.ts)
    │     ├── flow() ──▶ rule routing + run_agent handoff
    │     ├── run_agent() ──▶ buildHandoffPrompt() (src/gemini/client.ts) — markdown only, no HTTP
    │     │                      ├── loadRepoRules() (src/promptdiet/repo-rules.ts)
    │     │                      ├── skeletonizeFile / skeletonizeWithDependencies (src/skeleton/)
    │     │                      ├── getGitContext() (src/git/)
    │     │                      └── calculateEcoTelemetry() (src/telemetry/)
    │     ├── goal_orchestrate() ──▶ rule-based plan (src/mcp/goal-orchestrate.ts)
    │     │
    │     ├── init_board() ──▶ SQLite via sql.js
    │     ├── create_ticket() ──▶ SQLite via sql.js
    │     ├── update_ticket() ──▶ SQLite via sql.js
    │     ├── delete_ticket() ──▶ SQLite via sql.js
    │     ├── get_board_state() ──▶ SQLite via sql.js
    │     │
    │     └── list_agents() ──▶ agents.yaml parser (src/agents/)
    │
    └── MCP Resources (src/mcp/resources.ts)
          ├── file://.promptdiet/state.db
          └── file://.promptdiet/agents.yaml

Exit Codes

| Code | Meaning | |------|---------| | 0 | Success | | 1 | Non-retryable failure during agent run | | 2 | Parse error (invalid file, unsupported language) | | 3 | Ticket not found | | 4 | Agent not found |


License

MIT