@sleeperhit/mcp-server
A Model Context Protocol server that exposes the
Sleeper Hit Studio B2B Story API (/api/v1) as MCP tools. Point any
MCP-capable agent — Claude Desktop, Claude Code, Cursor, etc. — at it and the
agent can build a podcast end-to-end: ingest sources, develop a Series Bible,
map a season with the user, generate coverage-gated episodes, and publish them
to a shareable RSS feed.
It is a thin, faithful wrapper over the REST API. Tool names and endpoint paths
track docs/agents/api-reference.md. For
the authoritative, live feature list, read the capabilities resource (it
fetches GET /api/v1/capabilities).
What an agent can do with this
The Story API is a pipeline. The tools mirror each stage:
- Sources —
add_source(typetext|markdown|url|pdf). Inline text isREADYimmediately;url/pdfare fetched asynchronously, so pollget_sourceuntilstatus: READY. Each source then runs a structured digest (digestStatus). - Series Bible — use
get_series_bible,save_series_bible, andgenerate_series_bibleto establish durable format, canon, cast, audio direction, thengenerate_series_bible_coverage/get_series_bible_coverageto pass the versioned foundational craft gate direction, and the complete episode map shared by the web, REST, CLI, and MCP surfaces. - Season map —
create_season_runimports the Bible episode map without generating anything. Discuss and confirm each brief withmap_season_episode, then show the complete map and callapprove_season_maponly after the user explicitly approves that exact map. - Season runner — reload with
get_season_run, take one durable step withadvance_season_run, and follow the returnednextAction. Every episode plan, revision/retry, production repair, and RSS publish hold remains explicit. Coverage and required music/SFX/voice effects fail closed before publishing. Episodes publish sequentially to the run's audio RSS series. - Plan — for one-off work, call
create_planagainst a project with atarget(audience / objective / outcome) and one or moreartifactRequests. Returns a credit quote and runs the planner asynchronously; pollget_plan. - Approve — show the exact plan to the user, then call
approve_planwithuserConfirmed: trueonce it reachesREQUIRES_APPROVAL(non-table-read plans may skip this by passingautoApprove: truetocreate_plan).reject_planis the terminal alternative. - Job —
create_jobfrom anAPPROVEDplan. This reserves Studio Credits and queues generation. Pollget_job(orlist_artifacts). For a known table-read cast, calllist_voicesfirst and set a completevoiceMapon the singletable_readartifact request; each entry requiresvoiceIdand may includevoiceName,gender, andprovider. - Artifact —
get_artifactreturns the manifest: share URLs for a table read, video status, etc.render_artifact_videotriggers the opt-in MP4 (separate charge). - Refine / finalize —
refine_artifact(natural-language instruction) andfinalize_artifact. These are live post-creation controls for table read artifacts: refine creates a new revision under the same artifact id and share URLs, while finalize renders a durable MP3 or MP4.
Discovery: read the capabilities resource (sleeperhit://capabilities)
first — it tells the agent which source types, artifact types, statuses, and
quote pricing are live right now.
Tool catalog
| Tool | Endpoint |
|---|---|
create_project | POST /story-projects |
list_projects | GET /story-projects |
get_series_bible | GET /story-projects/{projectId}/series-bible |
save_series_bible | PATCH /story-projects/{projectId}/series-bible |
generate_series_bible | POST /story-projects/{projectId}/series-bible |
get_series_bible_coverage | GET /story-projects/{projectId}/series-bible/coverage |
generate_series_bible_coverage | POST /story-projects/{projectId}/series-bible/coverage |
create_season_run | POST /story-projects/{projectId}/season-runs |
list_season_runs | GET /story-projects/{projectId}/season-runs |
get_season_run | GET /season-runs/{runId} |
map_season_episode | PATCH /season-runs/{runId}/episodes/{episodeId} |
approve_season_map | POST /season-runs/{runId}/approve |
advance_season_run | POST /season-runs/{runId}/advance |
add_source | POST /story-projects/{projectId}/sources |
get_source | GET /story-projects/{projectId}/sources/{sourceId} |
list_sources | GET /story-projects/{projectId}/sources |
create_plan | POST /story-projects/{projectId}/story-plans |
get_plan | GET /story-plans/{planId} |
resume_story_plan | POST /story-plans/{planId}/resume |
list_plans | GET /story-projects/{projectId}/story-plans |
approve_plan | POST /story-plans/{planId}/approve |
reject_plan | POST /story-plans/{planId}/reject |
create_job | POST /story-jobs |
get_job | GET /story-jobs/{jobId} |
list_jobs | GET /story-jobs |
cancel_job | POST /story-jobs/{jobId}/cancel |
list_artifacts | GET /story-jobs/{jobId}/artifacts |
get_artifact | GET /artifacts/{artifactId} |
render_artifact_video | POST /artifacts/{artifactId}/render-video |
refine_artifact | POST /artifacts/{artifactId}/refine |
replace_artifact_script | POST /artifacts/{artifactId}/script |
finalize_artifact | POST /artifacts/{artifactId}/finalize |
retry_artifact_finalize | POST /artifacts/{artifactId}/finalize/retry |
resume_story_job | POST /story-jobs/{jobId}/resume |
add_sfx | POST /artifacts/{artifactId}/sfx |
update_sfx | POST /artifacts/{artifactId}/sfx |
list_sfx | GET /artifacts/{artifactId}/sfx |
remove_sfx | POST /artifacts/{artifactId}/sfx |
capabilities (resource) | GET /capabilities |
Every tool returns JSON as text content: { "ok": true, ... } on success, or
{ "ok": false, "error": { code, message, status, requestId, details? } } with
isError: true on failure — the same { error: { code, ... } } envelope the
API returns, so agents can branch on error.code.
Install & build
From the monorepo root (pnpm workspace):
pnpm --filter @sleeperhit/mcp-server install pnpm --filter @sleeperhit/mcp-server build
This compiles src/ to dist/ and exposes the sleeperhit-mcp binary
(dist/index.js). To run it directly for a smoke test:
SLEEPERHIT_API_KEY=sh_... node packages/mcp-server/dist/index.js
Environment variables
| Variable | Required | Default | Notes |
|---|---|---|---|
SLEEPERHIT_API_KEY | yes | — | Customer API key sh_<18hex>_<64hex>. Create one at https://sleeperhit.studio/dashboard/api . Sent as Authorization: Bearer. The complete Bible-to-season-to-RSS flow needs story:read/write, source:read/write, artifact:read/publish, publishing:read/write/publish, and credits:read. |
SLEEPERHIT_BASE_URL | no | https://sleeperhit.studio | Override for staging/local. |
Credit-reserving and generation POSTs (sources, plans, jobs, season advances, render-video)
automatically attach a generated Idempotency-Key for safe retries.
MCP client config
Claude Desktop / Claude Code
Add to your MCP servers config (Claude Desktop:
claude_desktop_config.json; Claude Code: .mcp.json or
claude mcp add-generated config):
{ "mcpServers": { "sleeperhit": { "command": "sleeperhit-mcp", "env": { "SLEEPERHIT_API_KEY": "sh_...", "SLEEPERHIT_BASE_URL": "https://sleeperhit.studio" } } } }
If sleeperhit-mcp is not on your PATH (e.g. you built locally without a
global link), point command at the built file instead:
{ "mcpServers": { "sleeperhit": { "command": "node", "args": ["/absolute/path/to/packages/mcp-server/dist/index.js"], "env": { "SLEEPERHIT_API_KEY": "sh_...", "SLEEPERHIT_BASE_URL": "https://sleeperhit.studio" } } } }
Notes
- stdout is reserved for the MCP wire protocol; the server logs to stderr.
- The server validates
SLEEPERHIT_API_KEYat startup and exits non-zero if it is missing, so misconfiguration fails loudly.