---
title: MCP Server
description: Query and manage Kitaru executions, deployments, artifacts, stacks, and secret creation through Model Context Protocol tools
---

Kitaru ships an MCP server so assistants can query and manage executions,
deployments, artifacts, stacks, and project context with structured tool calls
instead of parsing CLI text output.

## Install MCP support

<Tabs items={["uv (recommended)", "pip"]}>
  <Tab value="uv (recommended)">
    ```bash
    uv add kitaru --extra mcp
    ```
  </Tab>
  <Tab value="pip">
    ```bash
    pip install "kitaru[mcp]"
    ```
  </Tab>
</Tabs>

If you also want agents to start and stop the local Kitaru server, install the
`local` extra too:

<Tabs items={["uv (recommended)", "pip"]}>
  <Tab value="uv (recommended)">
    ```bash
    uv add kitaru --extra mcp --extra local
    ```
  </Tab>
  <Tab value="pip">
    ```bash
    pip install "kitaru[mcp,local]"
    ```
  </Tab>
</Tabs>

## Start the server

```bash
kitaru-mcp
```

The server uses stdio transport by default.

## Configure in Claude Code

<Callout type="info">
  `kitaru-mcp` has to resolve to the Python environment where you installed
  `kitaru[mcp]`. Claude Code inherits the PATH of the shell that launched it,
  not whatever virtualenv you activate later — so either activate your venv
  *before* starting Claude, or point `command` at the absolute path to
  `kitaru-mcp` inside that venv (e.g. `/path/to/project/.venv/bin/kitaru-mcp`).
  The absolute-path form is the most reliable.
</Callout>

### Option 1: project `.mcp.json`

Add this to `.mcp.json` in your project root (committed to the repo, so the
whole team picks it up):

```json
{
  "mcpServers": {
    "kitaru": {
      "command": "kitaru-mcp",
      "args": []
    }
  }
}
```

Or, using an absolute venv path:

```json
{
  "mcpServers": {
    "kitaru": {
      "command": "/absolute/path/to/.venv/bin/kitaru-mcp",
      "args": []
    }
  }
}
```

### Option 2: `claude mcp add` CLI

Claude Code can register the server for you. Scope controls where the
registration lives:

```bash
# Just you, just this project (default scope: local)
claude mcp add kitaru -- kitaru-mcp

# Shared with the team via .mcp.json in this repo
claude mcp add -s project kitaru -- kitaru-mcp

# Available in every project on your machine
claude mcp add -s user kitaru -- kitaru-mcp
```

Verify with `claude mcp list`. If `kitaru-mcp` isn't on PATH, pass the
absolute venv path instead:

```bash
claude mcp add -s project kitaru -- /absolute/path/to/.venv/bin/kitaru-mcp
```

You can also just ask Claude: *"add the Kitaru MCP server to this project"* —
it will run `claude mcp add` for you.

## Tool set

Execution tools:

- `kitaru_executions_list`
- `kitaru_executions_get`
- `kitaru_executions_latest`
- `get_execution_logs`
- `kitaru_executions_run`
- `kitaru_executions_cancel`
- `kitaru_executions_input`
- `kitaru_executions_retry`
- `kitaru_executions_replay`

Deployment tools:

- `kitaru_deployments_deploy`
- `kitaru_deployments_invoke`
- `kitaru_deployments_list`
- `kitaru_deployments_get`
- `kitaru_deployments_delete`
- `kitaru_deployments_tag`
- `kitaru_deployments_untag`

Artifact tools:

- `kitaru_artifacts_list`
- `kitaru_artifacts_get`

Secret tools:

- `kitaru_secrets_create`

`kitaru_secrets_create` returns metadata only: secret ID, name, visibility, key
names, and missing-value status. The MCP server intentionally does not expose a
secret delete tool; use the CLI or Python SDK for deletion.

Connection tools:

- `kitaru_start_local_server`
- `kitaru_stop_local_server`
- `kitaru_status`
- `kitaru_stacks_list`
- `manage_stack`

## Copy-paste prompts

Use prompts like these in an MCP-capable assistant after you configure the
Kitaru MCP server.

Read-only status check:

```text
Check my Kitaru status and list the five latest executions. Summarize anything waiting for input.
```

Start and watch a flow:

```text
Run `examples/features/basic_flow/first_working_flow.py:research_agent` with topic="durable execution", then watch the execution until it finishes.
```

Resolve a waiting execution safely:

```text
Find executions waiting for input. If exactly one is waiting, show me the question and ask me for the value before calling the input tool.
```

Plan and run a replay:

```text
Replay the latest failed execution from the checkpoint before the failing one. Explain the replay plan before running it.
```

Inspect results from a completed execution:

```text
Get the latest completed execution and show me its response artifacts.
```

Manage a local stack:

```text
Create a local Kitaru stack named local-dev if it does not already exist, then show me the current Kitaru status.
```

Deploy and invoke a shared flow route:

```text
Deploy `flows/research.py:research_agent` with topic="durable execution" as a canary deployment, then invoke the canary route and show me the started execution ID.
```

## Starting executions with `kitaru_executions_run`

The `kitaru_executions_run` tool requires a `target` string in the format:

```text
<module_or_file>:<flow_name>
```

The left side can be an importable module path or a `.py` filesystem path.
The right side is the flow attribute name in that module.

Examples:

```text
examples/features/basic_flow/first_working_flow.py:research_agent
./examples/features/basic_flow/first_working_flow.py:research_agent
```

Pass flow inputs as `args` (a JSON object) and optionally specify a `stack`:

```json
{
  "target": "my_app.flows:research_flow",
  "args": {"topic": "durable execution"},
  "stack": "prod-k8s"
}
```

When `stack` is provided, the tool passes it to `.run(stack=...)` so the
execution targets that stack.

## Deployment tools

The deployment tools let assistants publish and invoke versioned flow routes
without shelling out to `kitaru deploy` or `kitaru invoke`.

| Tool | Use it for |
|---|---|
| `kitaru_deployments_deploy` | Create a new deployment version from `<module_or_file>:<flow_name>` |
| `kitaru_deployments_invoke` | Start a new execution from a deployed flow by `default`, tag, or version |
| `kitaru_deployments_list` | List all deployment versions, optionally filtered to one flow |
| `kitaru_deployments_get` | Inspect one deployment by version or tag |
| `kitaru_deployments_delete` | Delete one version when no exclusive tag protects it |
| `kitaru_deployments_tag` | Attach or move a public tag to a version |
| `kitaru_deployments_untag` | Remove a non-reserved public tag from a version |

`kitaru_deployments_deploy` accepts deployment-time flow inputs plus optional
deployment controls:

```json
{
  "target": "flows/research.py:research_agent",
  "inputs": {"topic": "durable execution"},
  "tag": "canary",
  "exclusive": true,
  "stack": "production",
  "image": {
    "requirements": ["kitaru[openai]"],
    "secret_environment_from": ["openai-creds"]
  },
  "cache": false,
  "retries": 1
}
```

`image` accepts either a base image string or an object matching
`kitaru.ImageSettings`.

That deploy-time image config is saved into the deployment snapshot. Later
`kitaru_deployments_invoke` calls can override flow inputs, but they do not
rewrite the deployment image.

The first deployment of a flow gets the reserved `default` tag automatically.
`default` is always exclusive and cannot be removed. Non-default tags are shared
by default; pass `exclusive=true` when the tag should move to exactly one
version, such as `canary`, `stable`, or `prod`.

`kitaru_deployments_invoke` is the MCP equivalent of the primary CLI command
`kitaru invoke`. If neither `version` nor `tag` is provided, it invokes the
reserved `default` route:

```json
{
  "flow": "research_agent",
  "inputs": {"topic": "serverless routing"}
}
```

Pin a version or named route when needed:

```json
{
  "flow": "research_agent",
  "tag": "stable",
  "inputs": {"topic": "consumer request"}
}
```

```json
{
  "flow": "research_agent",
  "version": 2,
  "inputs": {"topic": "reproducible request"}
}
```

Use the list/get/tag tools for the producer side of a shared flow:

```json
{"flow": "research_agent"}
```

```json
{"flow": "research_agent", "tag": "stable", "version": 2, "exclusive": true}
```

Then consumers can invoke by flow name and tag; they do not need the producer's
source file path.

For the full deployment model, including auto-versioning, tag exclusivity,
serverless routing, and auth context, see [Deployments](/concepts/deployments).

## Example query flow

1. Call `kitaru_executions_list(status="waiting")`
2. Ask the user to confirm an action for a pending wait
3. Call `kitaru_executions_input(exec_id=..., wait=..., value=...)` (MCP requires explicit `wait`; CLI auto-detects)
4. Re-check state via `kitaru_executions_get(exec_id)`

To provision or clean up a local stack, use `manage_stack(action="create", name="local-dev")`
or `manage_stack(action="delete", name="local-dev", force=True)`.

## Authentication and context

The MCP server reuses the same config/auth context as `kitaru` CLI and SDK.
If you want MCP tools to target a local server, start one first with bare
`kitaru login` or via `kitaru_start_local_server(...)`. If you want MCP tools
to target a deployed Kitaru server or managed workspace, connect first with
`kitaru login <server-or-workspace> --api-key <workspace-api-key>` before
starting `kitaru-mcp`, or set `KITARU_SERVER_URL`, `KITARU_AUTH_TOKEN`, and
`KITARU_PROJECT` in the MCP server environment. If you can run `kitaru status`,
MCP tools use that same connection.

Deployment MCP calls do not use per-deployment tokens. `kitaru_deployments_deploy`,
`kitaru_deployments_invoke`, and the deployment management tools authorize through the active
workspace/project context, just like `kitaru deploy`, `kitaru invoke`, and
`KitaruClient().deployments.invoke(...)`.

## Replay behavior

`kitaru_executions_replay` starts a new execution and returns:

- `available: true`
- `operation: "replay"`
- the serialized replayed execution payload

Use `from_` for checkpoint selection, optional `flow_inputs` for flow
parameter overrides, and optional `overrides` for `checkpoint.*` overrides.

Replay does not support `wait.*` overrides. If the replayed execution reaches a
wait, resolve it through the normal input flow afterward.

MCP currently exposes `kitaru_executions_input` but not a separate resume tool.
If your backend requires an explicit resume step after input resolution, use the
CLI or SDK `resume(...)` surface.
