Keytween

Get started

Connect your agent (MCP)

Keytween runs a remote Model Context Protocol server. Add it to your coding agent and the agent can generate images and video, check prices and your balance, read the prompting guides and manage what it made, all through tool calls.

Endpoint https://keytween.com/mcp
Transport Streamable HTTP (stateless; no session to keep alive)
Authentication Authorization: Bearer <your API key> on every request
Protocol versions 2026-07-28, and the 2025 revisions for older clients

1. Get an API key #

  1. Sign in and open Account.
  2. Create a key under API keys. Keys start with sk_test_ and are shown once. API keys unlock after your first credit purchase.
  3. Put the key in an environment variable so it stays out of files you commit:
export KEYTWEEN_API_KEY="sk_test_..."

A key acts as you and spends your credits. Revoke it on the Account page if it leaks.

2. Add the server #

Claude Code #

Project scope, shared with your team through .mcp.json in the project root:

{
  "mcpServers": {
    "keytween": {
      "type": "http",
      "url": "https://keytween.com/mcp",
      "headers": {
        "Authorization": "Bearer ${KEYTWEEN_API_KEY}"
      }
    }
  }
}

Or from the command line:

claude mcp add --transport http --scope project keytween https://keytween.com/mcp \
  --header "Authorization: Bearer $KEYTWEEN_API_KEY"
  • ${VAR} and ${VAR:-default} are expanded in url and headers.
  • Use --scope user to make it available in every project instead.
  • Check the connection with /mcp inside a session or claude mcp list.
  • Prompts appear as slash commands, for example /mcp__keytween__storyboard.

Cursor #

.cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project:

{
  "mcpServers": {
    "keytween": {
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer ${env:KEYTWEEN_API_KEY}" }
    }
  }
}

Cursor expands ${env:NAME}. The Cursor CLI reads the same files; agent mcp list shows the connection.

VS Code with GitHub Copilot #

.vscode/mcp.json (note the root key is servers). VS Code asks for the key once and stores it securely:

{
  "inputs": [
    { "type": "promptString", "id": "keytween-key", "description": "Keytween API key", "password": true }
  ],
  "servers": {
    "keytween": {
      "type": "http",
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer ${input:keytween-key}" }
    }
  }
}

Run MCP: List Servers from the command palette to start it and see its output.

GitHub Copilot CLI #

copilot mcp add --transport http --header "Authorization: Bearer $KEYTWEEN_API_KEY" keytween https://keytween.com/mcp

This writes ~/.copilot/mcp-config.json. A project can also carry .mcp.json or .github/mcp.json in the Claude Code format above. Check with /mcp show keytween.

OpenAI Codex #

~/.codex/config.toml (shared by the CLI and the IDE extension):

[mcp_servers.keytween]
url = "https://keytween.com/mcp"
bearer_token_env_var = "KEYTWEEN_API_KEY"
tool_timeout_sec = 120

Or codex mcp add keytween --url https://keytween.com/mcp --bearer-token-env-var KEYTWEEN_API_KEY. Codex ends tool calls after 60 seconds by default, which is enough for the default waits here; tool_timeout_sec gives longer waits room. Check with /mcp.

Gemini CLI #

~/.gemini/settings.json, or .gemini/settings.json in the project. Use httpUrl (plain url means the older SSE transport):

{
  "mcpServers": {
    "keytween": {
      "httpUrl": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer sk_test_..." }
    }
  }
}

Or gemini mcp add --transport http -H "Authorization: Bearer $KEYTWEEN_API_KEY" keytween https://keytween.com/mcp. Check with /mcp.

Windsurf #

~/.config/devin/mcp_config.json (macOS and Linux) or %APPDATA%\devin\mcp_config.json (Windows); older installs use ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "keytween": {
      "serverUrl": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer ${env:KEYTWEEN_API_KEY}" }
    }
  }
}

Cline #

Open the MCP Servers panel, choose Remote Servers, pick Streamable HTTP and enter the URL; or edit the config (~/.cline/mcp.json for the CLI):

{
  "mcpServers": {
    "keytween": {
      "type": "streamableHttp",
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer sk_test_..." }
    }
  }
}

Zed #

settings.json (zed: open settings file), under context_servers:

{
  "context_servers": {
    "keytween": {
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer sk_test_..." }
    }
  }
}

Keep the Authorization header: without it Zed starts an OAuth sign-in, which this server does not use.

OpenCode #

opencode.json in the project, or ~/.config/opencode/opencode.json:

{
  "mcp": {
    "keytween": {
      "type": "remote",
      "url": "https://keytween.com/mcp",
      "enabled": true,
      "oauth": false,
      "headers": { "Authorization": "Bearer {env:KEYTWEEN_API_KEY}" }
    }
  }
}

Set "oauth": false so OpenCode sends the header instead of starting an OAuth flow. Check with opencode mcp list.

Kilo Code #

kilo.jsonc in the project, or ~/.config/kilo/kilo.jsonc:

{
  "mcp": {
    "keytween": {
      "type": "remote",
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer {env:KEYTWEEN_API_KEY}" },
      "enabled": true,
      "timeout": 120000
    }
  }
}

Kilo Code's default timeout for remote servers is 15 seconds, so set timeout (milliseconds) as shown.

Amp #

.amp/settings.json in the workspace, or ~/.config/amp/settings.json:

{
  "amp.mcpServers": {
    "keytween": {
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer ${KEYTWEEN_API_KEY}" }
    }
  }
}

Workspace servers wait for amp mcp approve keytween. Check with amp mcp doctor.

Goose #

~/.config/goose/config.yaml:

extensions:
  keytween:
    type: streamable_http
    name: keytween
    enabled: true
    uri: "https://keytween.com/mcp"
    headers:
      Authorization: "Bearer sk_test_..."
    timeout: 300

Or run goose configure, choose Add Extension, then Remote Extension (Streamable HTTP).

Kiro #

.kiro/settings/mcp.json in the workspace, or ~/.kiro/settings/mcp.json:

{
  "mcpServers": {
    "keytween": {
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer ${KEYTWEEN_API_KEY}" }
    }
  }
}

Kiro only expands environment variables you have approved: add KEYTWEEN_API_KEY under the Mcp Approved Env Vars setting.

JetBrains Junie #

.junie/mcp/mcp.json in the project, or ~/.junie/mcp/mcp.json:

{
  "mcpServers": {
    "keytween": {
      "url": "https://keytween.com/mcp",
      "headers": { "Authorization": "Bearer sk_test_..." }
    }
  }
}

Factory Droid #

droid mcp add keytween https://keytween.com/mcp --type http --header "Authorization: Bearer $KEYTWEEN_API_KEY"

Continue #

A file in .continue/mcpServers/, or the mcpServers block of config.yaml. MCP tools are available in agent mode:

mcpServers:
  - name: keytween
    type: streamable-http
    url: https://keytween.com/mcp
    requestOptions:
      headers:
        Authorization: "Bearer ${{ secrets.KEYTWEEN_API_KEY }}"

Claude Desktop, JetBrains AI Assistant and other stdio-only clients #

Clients that can only launch local servers, or that cannot send a custom header to a remote one, reach the server through the mcp-remote bridge:

{
  "mcpServers": {
    "keytween": {
      "command": "npx",
      "args": ["mcp-remote", "https://keytween.com/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": { "AUTH_HEADER": "Bearer sk_test_..." }
    }
  }
}

In Claude Desktop this goes in claude_desktop_config.json (Settings, Developer, Edit Config). Claude Desktop can also add the server as a custom connector: Customize, Connectors, Add custom connector, enter https://keytween.com/mcp, choose No sign in, and add a request header named Authorization with the value Bearer sk_test_....

Anything else #

Any client that speaks MCP over Streamable HTTP works. It needs three things: the URL https://keytween.com/mcp, the HTTP transport (sometimes called http, streamable-http or remote), and the header Authorization: Bearer <key>. The server does not use OAuth, so turn OAuth discovery off if your client offers the choice.

3. Check that it works #

Ask the agent: "Use Keytween to check my credit balance." It should call get_account and report your credits.

From a terminal, without any agent:

curl -s https://keytween.com/mcp \
  -H "Authorization: Bearer $KEYTWEEN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Timeouts #

Generations are queued, and a video takes two to three minutes to render. The tools are built so that no single call has to stay open that long:

  • A generate call waits up to wait_seconds (45 by default) and then returns the job, finished or not.
  • wait_for_job waits again, up to timeout_seconds, and can be called as often as needed.
  • While a call is open the server streams progress and keep-alive frames, so proxies do not drop it.

The defaults stay under the 60-second tool timeout that several clients apply. If your client allows longer calls you can pass up to 300 seconds and finish a video in one call:

Client Default tool timeout Setting
Claude Code very long; calls with no progress for 5 minutes are stopped MCP_TOOL_TIMEOUT, or "timeout" per server (ms)
OpenAI Codex 60 s tool_timeout_sec
Gemini CLI 10 minutes "timeout" per server (ms)
Kilo Code 15 s "timeout" per server (ms)
Goose 300 s timeout (seconds)

What the agent gets #

  • Tools for generating, editing, waiting, managing sequences, pricing and account status. See the MCP tool reference.
  • Guides as MCP resources (keytween://guides/<topic>) and through the get_guide tool, so the agent can read the prompting guides before it writes a prompt.
  • Prompts (slash commands in clients that support them) for storyboarding a multi-shot video and for drafting image and video prompts.
  • Previews: finished images and videos come back with a small picture the model can look at, and a download link it can save with curl.

Troubleshooting #

Symptom Cause and fix
401 with invalid_api_key The key is wrong or revoked. An unexpanded ${...} variable also ends up here: check that the variable is set in the environment the agent runs in.
401 with unauthenticated No Authorization header arrived. Some clients drop headers unless the transport type is set to HTTP explicitly.
The client opens a browser to sign in It is trying OAuth. Disable OAuth for this server or make sure the header is configured.
Tool calls time out Lower wait_seconds / timeout_seconds, or raise the client's tool timeout (table above). The job keeps running either way; find it with list_jobs.
402 insufficient_credits Buy credits at https://keytween.com/buy.
429 too_many_jobs Wait for a running generation to finish; get_account shows the limit.

All docs