Rewrites coding-assistant prompts using strategies from awesome-agentic-patterns. Paste a prompt, PromptForge classifies the task, selects the best agentic patterns from a catalog of 22, and asks your configured LLM to rewrite it.
Also generates complete project repositories from a plain-language objective —
paste a goal, get a downloadable .zip of a runnable project.
Available as a web app and an MCP server (stdio + HTTP). Same enhancer pipeline behind both surfaces.
| Local providers | Cloud providers |
|---|---|
| Ollama (port 11434) | OpenAI API |
| Lemonade (port 13305) | Anthropic API (native /v1/messages) |
| llama.cpp server (port 8080) |
- Vitest + Playwright suites green across 7 workspace packages — run
make testfor the current count. - Typecheck + build clean.
- biome lint configured.
- CI workflow at
.github/workflows/ci.yml. - Architecture: see ARCHITECTURE.md. Doc-vs-code drift: see DRIFT.md (regenerated by
/audit).
pnpm install # bootstraps the workspaceOptional: install one of Ollama,
Lemonade, or llama.cpp's llama-server
locally if you want to drive the rewriter with a local model.
make dev
# or: pnpm --filter @prompt-forge/web devOpen http://localhost:3000.
- Click Settings in the header.
- Pick a provider (ollama / lemonade / llamacpp / openai / anthropic), fill in baseUrl + model + (for openai/anthropic) apiKey, click Save.
- Click Test connection under the saved provider — confirms the endpoint accepts a tiny "ping" chat.
- Pick the active provider with the radio.
- Back at
/, paste your raw prompt and click Rewrite prompt. - Navigate to
/repoto generate a full project from an objective.
Config is stored in localStorage under the key promptforge:config —
nothing leaves your browser except the chat call to your configured
provider.
Navigate to http://localhost:3000/repo. Enter a project objective (e.g.,
"simple Express.js REST API for todos with TypeScript"), click Generate.
PromptForge sends a single LLM call and parses the returned file blocks into
a downloadable .zip. No server-side storage — generation and zip assembly
happen in the browser.
make dev-mcp-http
# or: pnpm --filter @prompt-forge/mcp start:http
# listens on http://127.0.0.1:8787/mcp (set PORT to override)Send any JSON-RPC 2.0 request with content-type: application/json. Try:
curl -s -X POST http://127.0.0.1:8787/mcp \
-H 'content-type: application/json' -d '{
"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{
"name":"enhance_prompt",
"arguments":{
"rawPrompt":"refactor the auth module to use react hooks and add tests",
"reflect":true,
"provider":{"kind":"ollama","baseUrl":"http://localhost:11434","model":"llama3.1:8b"}
}
}
}'HTTP behavior:
- Methods:
tools/list,tools/call,resources/list,resources/read,initialize OPTIONS /mcpreturns CORS preflight (origin:*by default)- POST body limit: 256 KiB (returns 413 on overflow)
- Notifications (no
id) return 204 with empty body - Streamable HTTP (MCP 2025-03-26 spec): POST with
Accept: text/event-streamreturns the response as a single SSE event. GET/mcpwith the same Accept header opens an SSE channel with aMcp-Session-Idheader and keep-alives (default 15 s). - Bearer auth (optional): set
PROMPTFORGE_MCP_TOKEN=<secret>to requireAuthorization: Bearer <secret>on all POST/GET requests. Without the env var, no auth is required (back-compat). OPTIONS preflight is never gated. - Bind address: set
HOST=0.0.0.0to expose on the LAN. Never do that withoutPROMPTFORGE_MCP_TOKENset.
make dev-mcp-stdio
# or: pnpm --filter @prompt-forge/mcp start:stdioClaude Desktop config:
{
"mcpServers": {
"promptforge": {
"command": "pnpm",
"args": ["--filter", "@prompt-forge/mcp", "exec", "tsx", "src/stdio.ts"],
"cwd": "/absolute/path/to/this/repo"
}
}
}Or, if you've installed the package globally (or via a bin path):
{
"mcpServers": {
"promptforge": {
"command": "node",
"args": ["/absolute/path/to/apps/mcp/bin/stdio.mjs"]
}
}
}Server advertises { tools: {}, resources: {} }.
Input:
| Field | Type | Required | Notes |
|---|---|---|---|
rawPrompt |
string (≥10 chars) | yes | The prompt to rewrite |
provider |
object | yes | {kind, baseUrl, model, apiKey?, timeoutMs?} |
taskKind |
enum | no | Override the heuristic classifier |
maxPatterns |
int 1–10 | no | Default 3 |
pinnedSlugs |
string[] | no | Force these patterns into the rewrite |
excludedSlugs |
string[] | no | Exclude these |
reflect |
boolean | no | Run a second LLM pass to revise the draft |
temperature |
number 0–2 | no | Forwarded to the chat call |
Returns text content with the rewritten prompt plus a header line listing the inferred taskKind and selected patterns.
Each of the 22 catalog patterns is exposed at
promptforge://patterns/<slug> with mime type text/markdown. Use
resources/list to enumerate, resources/read to fetch the directive.
| Command | What it does |
|---|---|
./start.sh |
Start web app (:3000) + MCP HTTP server (:8787) in one shot |
./start.sh --dev |
Same but with next dev hot-reload (skips build) |
./start.sh --web-only |
Web app only |
./start.sh --mcp-only |
MCP HTTP server only |
./setup-mcp.sh |
Auto-detect AI coding tools and write MCP config |
make install |
pnpm install |
make dev |
Start the Next.js web app on :3000 |
make dev-mcp-http |
Start MCP HTTP transport on :8787 |
make dev-mcp-stdio |
Start MCP stdio transport |
make test |
Run every package's vitest suite (hermetic) |
make test-live |
Env-gated tests against real LLMs (see below) |
make test-e2e-install |
Install Playwright's chromium binary (one time) |
make test-e2e |
Run Playwright e2e against the built web app |
make typecheck |
tsc --noEmit across the workspace |
make build |
Build all packages and the web app |
make lint |
biome check . |
make format |
biome format --write . |
make clean |
Wipe node_modules / dist / .next / coverage / test-results |
make ci |
install + typecheck + lint + test + build |
LIVE_OLLAMA=1 make test-live
LIVE_OPENAI=1 OPENAI_API_KEY=sk-... make test-live
LIVE_ANTHROPIC=1 ANTHROPIC_API_KEY=sk-ant-... make test-liveSkipped silently when the matching LIVE_* env var is unset, so make test stays hermetic.
make test-e2e-install # one time: pulls Playwright's chromium binary
make build # e2e runs against the production build
make test-e2e4 happy-path tests covering home, form gating, end-to-end rewrite (mocked /api/enhance), and the settings page.
prompt-forge/
├── apps/
│ ├── web/ Next.js 15 app (/ + /repo + /settings + /api/enhance + /api/repo + /api/providers/test)
│ └── mcp/ MCP server — JSON-RPC handler, stdio + HTTP transports, body limit, CORS
├── packages/
│ ├── core/ Result, AppError, Zod schemas, structured logger
│ ├── config/ AppConfig + memory/localStorage stores + pure helpers
│ ├── patterns/ 22-entry catalog + classifier + selector
│ ├── providers/ ProviderClient: Ollama + OpenAI-compat + native Anthropic
│ ├── enhancer/ Pipeline: classify -> select -> chat -> (optional reflect) -> extract
│ └── repo-gen/ Single-pass repo generator: prompt builder + file-block parser
├── docs/ Architecture, packages, providers, patterns, TDD strategy
├── start.sh One-shot launcher: web app + MCP HTTP server
└── setup-mcp.sh Auto-detect AI tools and write MCP server config
- Add the kind literal to
ProviderKindSchemainpackages/core/src/types.ts. - Create
packages/providers/src/<kind>.tsexportingcreate<Kind>Client(config, fetchImpl?). - Route the kind in
packages/providers/src/factory.ts. - Add a default base URL to
DEFAULT_BASE_URLS. - Write the test with
scriptedFetch. - Add the kind to
PROVIDER_KINDSinapps/web/src/components/provider-settings.tsx.
Apache-2.0.