Studio in Claude Desktop: the local MCP server
Praeko Studio is normally operated by an agent with a terminal. @praeko/studio-mcp is an MCP server that runs on your machine and exposes the same steps as tools, so an agent without a terminal (Claude Desktop, for example) can create the episode, write the script, make the voice, render, make the cover and upload the video to Praeko. It runs the Studio CLI underneath, over stdio: no port is opened.
@praeko/studio-mcp (0.1.1, checked on 11/08/2026) is published: the commands below work as written. It does not replace your machine: it needs Node, Chrome/Remotion to render and your own keys, all on your computer.studio_upload and then create_post) and the one with a terminal.Two servers, two roles
| `praeko` (remote) | `praeko-studio` (local) | |
|---|---|---|
| Where it runs | https://praeko.app/mcp, in Praeko's cloud |
On your machine, over stdio (npx -y @praeko/studio-mcp) |
| Does | Channels, media, posts (create, schedule, edit, cancel), insights, docs | Create the episode, script, voice, compile, render, cover, check, package and upload the files |
| Publishes? | Yes, always in two steps (preview and confirm) |
Never. It creates no post, schedules nothing, has no queue and no account |
| Your key | OAuth sign-in or a key you put in the client | The Praeko and ElevenLabs keys stay on your machine (Keychain, secrets file or variable); the agent never sees them |
The names do not collide: the client prefixes each tool with the server name. You can keep both on at the same time.
The flow without a terminal
Create
studio_brief_read and studio_brief_write (brand and rules), studio_new_episode, studio_write_script, studio_voice in draft (silent and free voice), studio_compile and studio_check.
Render
studio_voice in final (spends ElevenLabs characters: preview and confirmation code), studio_render, studio_cover and studio_package. Slow steps become jobs: follow them with studio_job.
Upload
studio_upload sends the video (out/<episode>.mp4) and the cover (out/<episode>-cover.png) to your Praeko media library and returns only the mediaIds. In two steps: the first call shows the files, sizes and destination and gives a confirmation_code; only the second, with confirm, uploads. It creates no post and publishes nothing.
Publish (on the remote server)
With the remote praeko server on, the agent uses the mediaIds in create_post (or schedule_post): media: { video: <id>, cover: <id> }. That tool has its own preview and only publishes after your "yes".
Install
Create the project once (npx @praeko/studio init my-channel: the command ends by printing the two install lines of this server with the right folder). Then point the server at the project folder, the one with brand.json; use the absolute path.
claude mcp add praeko-studio -- npx -y @praeko/studio-mcp --project <folder>{
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}One block per client
The formats below were checked on the vendors' pages on 08/11/2026; where that was not possible, the page says so.
Claude Code
One command registers the server (the -- separates Claude's own options from the server command). By default it is saved for you only, in this project; --scope user applies to every project.
claude mcp add praeko-studio -- npx -y @praeko/studio-mcp --project <folder>{
"mcpServers": {
"praeko-studio": {
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}code.claude.com/docs/en/mcp: syntax claude mcp add [options] <name> -- <command> [args...]; an entry with no type in .mcp.json is read as a stdio server.Claude Desktop
In Settings, Developer tab, click Edit Config. The file is ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/.config/Claude/claude_desktop_config.json (Linux). Paste the block, quit Claude Desktop completely and open it again. Use the absolute path of the folder.
{
"mcpServers": {
"praeko-studio": {
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}modelcontextprotocol.io/docs/develop/connect-local-servers (the page uses Claude Desktop as its example). This is the local server path; the custom connector for the remote Praeko is a different thing.Cursor
In the project's .cursor/mcp.json, or in ~/.cursor/mcp.json for every project. A local server takes type: stdio.
{
"mcpServers": {
"praeko-studio": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}cursor.com/docs/context/mcp.Codex
One command (the -- separates the server command) or the [mcp_servers.<name>] table in ~/.codex/config.toml (or .codex/config.toml of a trusted project).
codex mcp add praeko-studio -- npx -y @praeko/studio-mcp --project <folder>[mcp_servers.praeko-studio]
command = "npx"
args = ["-y","@praeko/studio-mcp","--project","<folder>"]learn.chatgpt.com/docs/extend/mcp).Gemini CLI
In the project's .gemini/settings.json, or in ~/.gemini/settings.json for every project.
{
"mcpServers": {
"praeko-studio": {
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}geminicli.com/docs/tools/mcp-server, which says Gemini CLI was replaced by Antigravity CLI on Jun 18, 2026 for free and Google One accounts. The gemini mcp add command exists, but we do not show it: Gemini's own options and the server's arguments (-y) can get mixed up. For Antigravity: check the client's documentation.opencode
In opencode.json (or opencode.jsonc); a local server uses type: local and the whole command as a list.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"praeko-studio": {
"type": "local",
"command": [
"npx",
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}
}opencode.ai/docs/mcp-servers) shows servers inside mcp.servers; older versions used mcp.<name> directly. We could not check the exact file name or the version where the format changed: check the client's documentation, or use opencode mcp add.Other client (generic)
Any client that runs a local MCP server over stdio takes the same trio: command, arguments and (if needed) environment variables. Field names vary by client: check the client's documentation.
{
"mcpServers": {
"praeko-studio": {
"command": "npx",
"args": [
"-y",
"@praeko/studio-mcp",
"--project",
"<folder>"
]
}
}
}command: npx
args: ["-y","@praeko/studio-mcp","--project","<folder>"]
server: stdio (no port, no URL)The 14 tools
| Tool | What it does |
|---|---|
studio_status |
Checks the environment (Node, ffmpeg, Chrome, fonts, voice accounts without keys, license) and warns if the Praeko key is admin. |
studio_docs |
Lists or returns the Studio documentation topics. |
studio_brief_read, studio_brief_write |
Reads and writes brief.md, playbook.md and brand.json (validated, with .bak). |
studio_new_episode |
Creates episodes/<name>/. |
studio_write_script |
Writes script.txt or episode.yaml (the YAML is validated). |
studio_voice |
draft: silent voice, free. final: spends ElevenLabs characters and is two-step (a preview with the script characters, account and balance, a warning if the balance is not enough, and a confirmation_code). |
studio_compile, studio_check |
Compiles episode.yaml and checks the episode. |
studio_render, studio_cover, studio_package |
Background jobs (jobId): video, cover and publishing texts. For an image post (studio_new_episode with format: image), studio_render renders the slide to out/<episode>-slide-01.jpg (1080x1350, JPEG) and studio_cover is refused. |
studio_job |
Status, log or cancel of a job. One job at a time per project. |
studio_upload |
Uploads the episode's video and cover (or, for an image post, the JPEG as type: image) to the Praeko media library, in two steps, and returns only the mediaIds. It creates no post. |
write key, not adminstudio_upload uses your Praeko key (PRAEKO_KEY, the macOS Keychain or the secrets file, like the rest of Studio). It only needs to send files: create a key with the write scope for Studio under API keys. If the key found is admin, studio_status and praeko studio doctor show a warning (not an error). The service address does not come from brand.json, so text written by the agent can never redirect the key.Safety
| Guarantee | How |
|---|---|
| Stdio only | No port open, nothing reachable over the network. |
| No free-form command | The tools call the Studio CLI with fixed arguments; what the agent writes never becomes a command line. Episode names follow ^[a-z0-9][a-z0-9-]*$ and every path stays inside the project. |
| Keys | No answer, log or error shows a key: values are masked (sk_…3e). |
| Project text is data | script.txt, brief.md and CLI output come back marked untrusted: the server does not obey what is written in them. |
| Spending only with your yes | studio_voice final and studio_upload are two-step: the code is short, bound to the arguments (and the files), valid for 10 minutes and works once. |
| Resources | One job at a time per project, a maximum time per job, cancellation. No telemetry. |
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| The server does not show up in the client | The client was not restarted, or the JSON has an error. | Quit and reopen the client completely, check the JSON and run the command by hand in a terminal. |
has no brand.json |
--project does not point at the project folder. |
Use the absolute path of the folder with brand.json and src/index.ts. |
no Praeko key found |
studio_upload did not find the key. |
Save a write key (PRAEKO_KEY in the server's environment, or praeko studio schedule --via praeko --key in a terminal). Never paste the key in the chat. |
reason: expired, unknown_code or arguments_changed |
10 minutes passed, the code was already used, the server restarted, or the file/script changed after the preview. | Ask for a new preview and confirm without changing anything. |
INSUFFICIENT BALANCE in the voice preview |
No account with a key has enough characters for the script. | Add credit or another account (praeko studio voice account add) and ask for the preview again. |