Viktor MCP Server
Connect an MCP-compatible agent to Viktor with streamable HTTP and a scoped Viktor API key.
The Viktor MCP server lets any MCP-compatible agent delegate work to Viktor. It exposes the same threads, runs, results, and files as the Viktor Public API, with two agent-friendly tools that can start a task and wait for its result in one call.
- Server URL:
https://api.viktor.com/mcp - Transport: Streamable HTTP
- Authentication: Viktor API key on every request
- Session model: Stateless
Connect
1. Create a scoped API key
Open Settings → API Keys and generate a personal or team key. For the simplest ask_viktor workflow, grant:
threads:createruns:createruns:read
Add other scopes only when the MCP client needs the corresponding tools. The server advertises only tools allowed by the key's current scopes.
2. Add the remote server to your MCP client
Every client needs the same two pieces of information: the server URL and an authentication header. Either header style works:
Authorization: Bearer <VIKTOR_API_KEY>x-api-key: <VIKTOR_API_KEY>
Claude Code
claude mcp add --transport http viktor https://api.viktor.com/mcp \
--header "Authorization: Bearer $VIKTOR_API_KEY"Cursor
Add the server to ~/.cursor/mcp.json (or the project's .cursor/mcp.json):
{
"mcpServers": {
"viktor": {
"url": "https://api.viktor.com/mcp",
"headers": {
"Authorization": "Bearer <VIKTOR_API_KEY>"
}
}
}
}Other clients
Most MCP clients accept the same mcpServers JSON shape as the Cursor example, or offer a settings screen where you enter the URL and header. If your client asks for a transport, choose Streamable HTTP, not the legacy SSE transport.
Use your client's secret or environment-variable support instead of saving a live key directly in a shared configuration file.
3. Verify the connection
Call whoami. It requires no scope and returns the key type, granted scopes, and active rate limits. If other tools are missing, update the key's scopes in the Viktor dashboard and refresh the client's tool list.
Recommended workflow
For a one-off task, call ask_viktor with a message:
{
"message": "Analyze this month's revenue and summarize the biggest changes.",
"speed": "smarter",
"timeout_seconds": 120,
"idempotency_key": "monthly-revenue-2026-07"
}ask_viktor creates a thread, starts a run, waits up to timeout_seconds, and returns the result when it is ready. Results can contain Markdown, structured JSON, and file artifacts.
If the wait ends first, the response includes wait_timed_out: true and the run_id. Call wait_for_run with that ID. Do not call ask_viktor again, because that can start duplicate work unless the same idempotency key is reused.
For long-running or interactive workflows:
- Call
create_threadto queue work without waiting. - Call
wait_for_runorget_runwith the returned run ID. - Call
send_messageon the same thread to continue the conversation with its history. - Use
get_file_download_urlfor any artifact IDs returned in the result.
Tool reference
| Tool | What it does | Required scopes |
ask_viktor | Start a new thread and wait for its result | threads:create, runs:create, runs:read |
create_thread | Start a new thread and queue a run without waiting | threads:create, runs:create |
send_message | Continue an existing thread and queue a run | messages:create, runs:create |
wait_for_run | Wait for a run to finish and return its result | runs:read |
get_run | Read a run's current status | runs:read |
get_run_result | Fetch a terminal run's result | runs:read |
cancel_run | Request cancellation of an in-flight run | runs:create |
list_threads | List the key's threads, newest first | threads:read |
get_thread | Get a thread's status | threads:read |
list_messages | List user-visible messages in a thread | messages:read |
list_runs | List a thread's runs, newest first | runs:read |
get_file_download_url | Exchange an artifact token for a short-lived URL | files:read |
whoami | Identify the key, scopes, and rate limits | None |
Structured output
ask_viktor, create_thread, and send_message accept the same response_format JSON Schema as the REST API. When supplied, the completed result includes a validated json value. See the Public API guide.
Timeouts, progress, and retries
ask_viktor and wait_for_run perform bounded server-side polling. Clients that send an MCP progress token receive best-effort progress notifications while waiting.
Every tool call is rate limited against the same policy as its REST equivalent. If a wait times out, call wait_for_run again with the same run ID. Use idempotency_key whenever a tool starts a run so reconnects and retries cannot duplicate work.
Errors
Authentication failures are plain HTTP 401 or 403 responses so MCP clients can recognize credential problems. Tool failures are machine-readable JSON strings with an error and message, and may include http_status, scope, or rate-limit details.
Common fixes:
- No tools appear: verify the key with
whoami, then grant the required scopes. - `insufficient_scope`: add the named scope to the key or choose a different tool.
- `wait_timed_out`: call
wait_for_runagain with the returned run ID. - `thread_busy`: wait for the active run before sending another message to that thread.
- `rate_limit_exceeded`: wait for the retry interval before calling again.