Overview
Versioned prompts, resolved at runtime.
Theo Prompts manages your agent's prompts as versioned, immutable
revisions and resolves them at runtime — over REST, a TypeScript SDK, or MCP.
A prompt is identified by name and has N revisions; you point environment
labels (prod, staging) at a revision and promote by moving the label,
so the next resolution reflects the new prompt with no redeploy. All three
interfaces delegate to the same core (Postgres source of truth, optional Redis
cache), and {{var}} templating renders client-side so variable values never
leave your process.
Pre-1.0, in active development. The packages (@usetheo/promptly-sdk,
@usetheo/promptly-api, @usetheo/promptly-mcp) are not yet published to
npm — they run inside the workspace for now. API-key auth is required.
Quick start
import { PromptlyClient } from '@usetheo/promptly-sdk';
const client = new PromptlyClient({
baseUrl: 'http://localhost:3000',
apiKey: process.env.THEOPROMPTLY_API_KEY!, // required — blank throws at construction
cacheTtlSeconds: 60,
});
await client.createPrompt('greet', 'hi {{name}}'); // registers revision v1
await client.assignLabel('greet', 'prod', 1); // point prod → v1
const p = await client.getPrompt('greet', { label: 'prod', vars: { name: 'Theo' } });
p.content; // 'hi Theo' — rendered SDK-side; the value never reaches the server
// Later: promote to v2 with no app rebuild
await client.assignLabel('greet', 'prod', 2);The REST API exposes the same surface (POST /prompts,
GET /prompts/:name?label=prod, PUT /prompts/:name/labels/:label,
POST /prompts/:name/rollback, GET /openapi.json), and the MCP server exposes
get_prompt, list_revisions, and list_labels as agent tools.
Core concepts
Immutable revisions
Every write creates a new revision (version = max + 1). History is append-only and auditable — `createPrompt(name, content)` / `listRevisions(name)`.
Labels + promotion
Labels like `prod` / `staging` are pointers to revisions. Promoting = moving the pointer (`assignLabel(name, label, version)`) — no redeploy.
`{{var}}` templating, client-side
The zero-dep template primitive substitutes `{{identifier}}` in the SDK/MCP. Variable values never reach the REST server; a missing var throws `MissingPromptVariableError`.
Append-only rollback
`rollback(name, toVersion)` creates a new revision cloning older content — history is never rewritten.
One core, three interfaces
REST, SDK, and MCP delegate to the same use cases; a contract test asserts REST == SDK == MCP parity.
API keys + tenancy + tracing
`promptly_live_…` keys (only the SHA-256 hash is stored) with `read`/`write`/`admin` scopes, per-workspace isolation, and one `prompt.resolve` OTel span per resolution.