> ## Documentation Index
> Fetch the complete documentation index at: https://docs.karta.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> karta.jsonc - optional CLI, harness, and runtime settings that tune how your agent behaves at run time.

`karta.jsonc` is an optional file that tunes Karta's behavior without touching
your agent definitions. It is JSONC (JSON with comments and trailing commas).
Every key is optional, and the file lives at `./karta.jsonc` in the agent
project folder.

## Choose the right config file

| File                              | Owns                                                                                                  | Read by                                                                 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `karta.jsonc`                     | CLI rendering, local participant profile, Claude harness runtime knobs, and deployment approval mode. | `karta dev`, the Python SDK runtime, and the Claude harness.            |
| [`karta.toml`](/build/karta-toml) | Agent identity, deploy gate, buildpack, entry point, and declared env vars.                           | `karta setup`, `karta status`, `karta deploy`, and the release builder. |
| `.opencode/opencode.jsonc`        | OpenCode's own harness behavior.                                                                      | OpenCode.                                                               |

## Full example

```jsonc karta.jsonc theme={null}
{
  // How the CLI renders and gates a turn
  "cli": {
    "hidden_event_types": ["system", "step_start"],
    "input_required_policy": "prompt",
    "input_required_hidden_policy": "deny"
  },

  // Harness-specific settings
  "harness": {
    "claude": {
      "idle_timeout_seconds": 600,
      "thinking_budget_tokens": 10000,
      "permission_intercept": false,
      "agent_command": false
    }
  },

  // Deployment runtime behavior
  "runtime": {
    "permission_mode": "interactive"
  },

  // CLI user profile
  "profile": {
    "name": "alice",
    "display_name": "Alice Chen"
  }
}
```

## Behavior summary

| Key                                     | Default when missing or invalid            | Allowed values                                               | Use when                                                                    |
| --------------------------------------- | ------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `cli.hidden_event_types`                | `["system"]`; an empty list hides nothing. | Non-empty strings.                                           | Quiet local `karta dev` output without changing what the runtime emits.     |
| `cli.input_required_policy`             | `prompt`                                   | `prompt`, `deny`, `approve_once`, `approve_session`, `error` | Decide how the CLI responds when a visible turn pauses for approval.        |
| `cli.input_required_hidden_policy`      | No override.                               | `deny`, `approve_once`, `approve_session`, `error`           | Decide hidden approval prompts without asking the user.                     |
| `harness.claude.idle_timeout_seconds`   | `600`                                      | Positive integer.                                            | Keep a Claude harness process warm longer or shorter between turns.         |
| `harness.claude.thinking_budget_tokens` | Unset.                                     | Positive integer.                                            | Set the extended-thinking budget for Claude turns that request reasoning.   |
| `harness.claude.permission_intercept`   | `false`                                    | Boolean.                                                     | Let Karta handle Claude approval prompts instead of leaving them to Claude. |
| `harness.claude.agent_command`          | `false`                                    | Boolean.                                                     | Enable the Claude agent command surface.                                    |
| `runtime.permission_mode`               | `interactive` behavior.                    | `interactive`, `autonomous`, `approve_session`               | Make deployed/headless sessions auto-approve for the session.               |
| `profile.name`                          | OS username.                               | Non-empty string.                                            | Set the default human participant id for local CLI sessions.                |
| `profile.display_name`                  | Same as `profile.name`.                    | String.                                                      | Set the display label shown for the local participant.                      |

## `cli`

<ResponseField name="cli.hidden_event_types" type="string[]">
  [Event types](/concepts/streaming-events) the CLI should not render - e.g.
  `["system", "step_start"]`. Useful to quiet noisy harness internals.
</ResponseField>

<ResponseField name="cli.input_required_policy" type="string" default="prompt">
  How the CLI handles [`input_required`](/concepts/streaming-events#input_required)
  approval prompts: `prompt`, `deny`, `approve_once`, `approve_session`, or
  `error`.
</ResponseField>

<ResponseField name="cli.input_required_hidden_policy" type="string" default="deny">
  The auto-decision applied to approval prompts that are hidden (so the user
  is not asked for events they cannot see).
</ResponseField>

## `harness.claude`

<ResponseField name="harness.claude.idle_timeout_seconds" type="integer" default="600">
  How long the harness may stay idle before it is shut down.
</ResponseField>

<ResponseField name="harness.claude.thinking_budget_tokens" type="integer">
  Optional extended-thinking budget for turns that request reasoning.
</ResponseField>

<ResponseField name="harness.claude.permission_intercept" type="boolean" default="false">
  Whether Karta intercepts the harness's approval prompts (vs. letting the
  harness handle them).
</ResponseField>

<ResponseField name="harness.claude.agent_command" type="boolean" default="false">
  Enables the agent command surface.
</ResponseField>

## `runtime`

<ResponseField name="runtime.permission_mode" type="string" default="interactive">
  How a deployed agent treats approvals for tools that are not on the
  [`.claude/settings.json` allowlist](/build/agent-structure#permissions-and-bounded-authority).
  `interactive` pauses each off-allowlist tool as a tool-permission prompt the end
  user answers over the API (`approve_once`, `approve_session`, `deny`);
  `autonomous` auto-approves for the session (maps to `approve_session`). Set
  `autonomous` for unattended/headless deployments that should never pause - it
  bypasses the approval prompt entirely, so reserve it for trusted agents.
</ResponseField>

## `profile`

<ResponseField name="profile.name" type="string">
  The default human participant name for CLI sessions.
</ResponseField>

<ResponseField name="profile.display_name" type="string">
  A friendly display name for that participant. Falls back to your OS user if
  unset.
</ResponseField>

<Info>
  `karta.jsonc` governs **run-time behavior**;
  [`karta.toml`](/build/karta-toml) governs **publish/build**. OpenCode's own
  harness config lives separately in `.opencode/opencode.jsonc`.
</Info>

## Verify the file is being read

Run a one-shot local turn with an explicit config path:

```bash theme={null}
karta dev --config karta.jsonc -m "hello"
```

To check the deployed approval mode from Python, create a session and inspect
its `permission_mode`:

```python theme={null}
from app import app

session = app.session()
print(session.permission_mode)  # approve_session when runtime.permission_mode is autonomous
```

If a value has the wrong type or is outside the allowed set, Karta ignores that
value and uses the default shown above.
