# Agent Configs

## Create Agent Config

**post** `/v5/agent_configs`

Create a reusable agent configuration (system prompt, harness, model, allowed tools) under the caller's account.

The config is a template that a chat session or a non-chat trigger later turns
into task params; creating one does not start any task. `persistent_workspace`
opts tasks made from this config into a durable `/workspace` that survives
sandbox death (off by default, and fixed once a task starts), and `repos`
overrides which repositories provisioning clones into that workspace — omit it
(null) to use the deployment default, or pass an empty list to clone nothing.
A `repos` override is rejected with a 422 on the model-agnostic (litellm)
harness unless `persistent_workspace` is also true, because non-persistent
litellm tasks run in a pre-cloned warm-pool sandbox where the override would be
ignored. `allowed_tools` may name MCP servers (Slack, Linear, GitHub, ...)
alongside harness tools, and granting an MCP server name authorizes every tool
it exposes.

### Body Parameters

- `harness: "claude-code" or "codex" or "litellm"`

  Harness strategy. See Harness enum for supported values.

  - `"claude-code"`

  - `"codex"`

  - `"litellm"`

- `model: string`

- `name: string`

- `system_prompt: string`

- `allowed_tools: optional array of "Read" or "Write" or "Edit" or 34 more`

  Tools enabled for this config. See AllowedTool enum for the catalogue.

  - `"Read"`

  - `"Write"`

  - `"Edit"`

  - `"Bash"`

  - `"Glob"`

  - `"Grep"`

  - `"List"`

  - `"WebFetch"`

  - `"WebSearch"`

  - `"Task"`

  - `"TodoWrite"`

  - `"NotebookEdit"`

  - `"ExitPlanMode"`

  - `"Slack"`

  - `"Linear"`

  - `"GitHub"`

  - `"Confluence"`

  - `"Notion"`

  - `"Datadog"`

  - `"PagerDuty"`

  - `"Salesforce"`

  - `"Figma"`

  - `"Granola"`

  - `"Jira"`

  - `"Gmail"`

  - `"GoogleCalendar"`

  - `"GoogleDrive"`

  - `"GoogleDocs"`

  - `"GoogleSheets"`

  - `"GoogleSlides"`

  - `"Snowflake"`

  - `"Redash"`

  - `"Tableau"`

  - `"Metabase"`

  - `"Gong"`

  - `"ZoomInfo"`

  - `"Clay"`

- `description: optional string`

- `persistent_workspace: optional boolean`

  Give tasks a persistent /workspace that survives sandbox death. Fixed for a task's life; defaults off.

- `repos: optional array of RepoSpec`

  Per-config repo override. None uses the deployment default; an empty list clones nothing.

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

### Returns

- `id: string`

- `allowed_tools: array of string`

- `created_at: string`

- `harness: string`

- `model: string`

- `name: string`

- `system_prompt: string`

- `updated_at: string`

- `description: optional string`

- `object: optional "agent_config"`

  - `"agent_config"`

- `persistent_workspace: optional boolean`

- `repos: optional array of RepoSpec`

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs \
    -H 'Content-Type: application/json' \
    -H "x-api-key: $SGP_API_KEY" \
    -d '{
          "harness": "claude-code",
          "model": "x",
          "name": "x",
          "system_prompt": "x"
        }'
```

#### Response

```json
{
  "id": "id",
  "allowed_tools": [
    "string"
  ],
  "created_at": "2019-12-27T18:11:19.117Z",
  "harness": "harness",
  "model": "model",
  "name": "name",
  "system_prompt": "system_prompt",
  "updated_at": "2019-12-27T18:11:19.117Z",
  "description": "description",
  "object": "agent_config",
  "persistent_workspace": true,
  "repos": [
    {
      "url": "x",
      "depth": 1,
      "path": "path"
    }
  ]
}
```

## List Agent Configs

**get** `/v5/agent_configs`

List agent configurations visible to the caller, with cursor-based pagination.

A user caller sees only the configs they created unless fine-grained access
control (FGAC) grants them access to others; a service-account caller sees
every config under the account. This returns the stored config records as-is —
use `{agent_config_id}/resolve` instead when you need a config projected into
the params a task would run with. Because deleting a config removes it outright
rather than archiving it, there are no archived configs to page through here.

### Query Parameters

- `ending_before: optional string`

- `limit: optional number`

- `sort_by: optional string`

- `sort_order: optional SortOrder`

  - `"asc"`

  - `"desc"`

- `starting_after: optional string`

### Returns

- `has_more: boolean`

  Whether there are more items left to be fetched.

- `items: array of object { id, allowed_tools, created_at, 9 more }`

  - `id: string`

  - `allowed_tools: array of string`

  - `created_at: string`

  - `harness: string`

  - `model: string`

  - `name: string`

  - `system_prompt: string`

  - `updated_at: string`

  - `description: optional string`

  - `object: optional "agent_config"`

    - `"agent_config"`

  - `persistent_workspace: optional boolean`

  - `repos: optional array of RepoSpec`

    - `url: string`

    - `depth: optional number`

    - `path: optional string`

- `total: number`

  The total of items that match the query. This is greater than or equal to the number of items returned.

- `limit: optional number`

  The maximum number of items to return.

- `object: optional "list"`

  - `"list"`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "has_more": true,
  "items": [
    {
      "id": "id",
      "allowed_tools": [
        "string"
      ],
      "created_at": "2019-12-27T18:11:19.117Z",
      "harness": "harness",
      "model": "model",
      "name": "name",
      "system_prompt": "system_prompt",
      "updated_at": "2019-12-27T18:11:19.117Z",
      "description": "description",
      "object": "agent_config",
      "persistent_workspace": true,
      "repos": [
        {
          "url": "x",
          "depth": 1,
          "path": "path"
        }
      ]
    }
  ],
  "total": 0,
  "limit": 0,
  "object": "list"
}
```

## List MCP Tool Names

**get** `/v5/agent_configs/mcp_tools`

Return the fixed set of tool names that route to MCP servers rather than harness-provided tools.

These are the subset of `allowed_tools` values (Slack, Linear, GitHub, ...)
the platform treats as MCP servers; the list is a static enum, not account
data, so it is identical for every caller. It is exposed mainly so the
generated SDK carries the `McpTool` type and the frontend can assert its own
MCP-versus-harness tool classifier against the backend to prevent drift. It
does not list configs or the tools actually granted to any particular config.

### Returns

- `"Slack"`

- `"Linear"`

- `"GitHub"`

- `"Confluence"`

- `"Notion"`

- `"Datadog"`

- `"PagerDuty"`

- `"Salesforce"`

- `"Figma"`

- `"Granola"`

- `"Jira"`

- `"Gmail"`

- `"GoogleCalendar"`

- `"GoogleDrive"`

- `"GoogleDocs"`

- `"GoogleSheets"`

- `"GoogleSlides"`

- `"Snowflake"`

- `"Redash"`

- `"Tableau"`

- `"Metabase"`

- `"Gong"`

- `"ZoomInfo"`

- `"Clay"`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs/mcp_tools \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
[
  "Slack"
]
```

## Get Agent Config

**get** `/v5/agent_configs/{agent_config_id}`

Fetch a single stored agent configuration by id, including its `persistent_workspace` flag and any `repos` override.

This returns the saved record as-is and does not compute task params; use
`{agent_config_id}/resolve` when you need the config projected into the params
a task would run with. A user caller can only read a config they created unless
fine-grained access control grants access, while a service account can read any
config under the account; a missing or out-of-scope id returns a 404.

### Path Parameters

- `agent_config_id: string`

### Returns

- `id: string`

- `allowed_tools: array of string`

- `created_at: string`

- `harness: string`

- `model: string`

- `name: string`

- `system_prompt: string`

- `updated_at: string`

- `description: optional string`

- `object: optional "agent_config"`

  - `"agent_config"`

- `persistent_workspace: optional boolean`

- `repos: optional array of RepoSpec`

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs/$AGENT_CONFIG_ID \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "id": "id",
  "allowed_tools": [
    "string"
  ],
  "created_at": "2019-12-27T18:11:19.117Z",
  "harness": "harness",
  "model": "model",
  "name": "name",
  "system_prompt": "system_prompt",
  "updated_at": "2019-12-27T18:11:19.117Z",
  "description": "description",
  "object": "agent_config",
  "persistent_workspace": true,
  "repos": [
    {
      "url": "x",
      "depth": 1,
      "path": "path"
    }
  ]
}
```

## Update Agent Config

**patch** `/v5/agent_configs/{agent_config_id}`

Partially update a stored agent config; only fields present in the request body are changed.

`persistent_workspace` and `repos` are both patchable — an explicit null on
`repos` clears the override back to the deployment default, while the
always-present fields (name, system_prompt, harness, allowed_tools, model, and
persistent_workspace) reject an explicit null. Because `persistent_workspace`
and `repos` are read when a task is created and are fixed for a task's life,
changing them affects only tasks created afterward, not one already running. The
optional `task_id` query parameter opts into a live-config side effect: after
the row is persisted, the changed pass-through fields (system_prompt, model,
harness, and allowed_tools split into harness tools versus MCP servers) are
shallow-merged into that running task's params on Agentex in a background task so
the worker picks them up on its next turn; `persistent_workspace` and `repos`
are intentionally not forwarded to a running task. That side effect runs after
the response is sent, is best-effort, and no-ops if the task does not exist or the
caller does not own it. A user caller can only update a config they created unless
fine-grained access control grants access.

### Path Parameters

- `agent_config_id: string`

### Query Parameters

- `task_id: optional string`

  If set, after persisting the patch we shallow-merge the changed fields into this task's params column on Agentex so the worker picks up the new values on its next turn. Caller-provided context — Agentex enforces task ownership via its own auth, so the side-effect no-ops if the caller doesn't own the task.

### Body Parameters

- `allowed_tools: optional array of "Read" or "Write" or "Edit" or 34 more`

  - `"Read"`

  - `"Write"`

  - `"Edit"`

  - `"Bash"`

  - `"Glob"`

  - `"Grep"`

  - `"List"`

  - `"WebFetch"`

  - `"WebSearch"`

  - `"Task"`

  - `"TodoWrite"`

  - `"NotebookEdit"`

  - `"ExitPlanMode"`

  - `"Slack"`

  - `"Linear"`

  - `"GitHub"`

  - `"Confluence"`

  - `"Notion"`

  - `"Datadog"`

  - `"PagerDuty"`

  - `"Salesforce"`

  - `"Figma"`

  - `"Granola"`

  - `"Jira"`

  - `"Gmail"`

  - `"GoogleCalendar"`

  - `"GoogleDrive"`

  - `"GoogleDocs"`

  - `"GoogleSheets"`

  - `"GoogleSlides"`

  - `"Snowflake"`

  - `"Redash"`

  - `"Tableau"`

  - `"Metabase"`

  - `"Gong"`

  - `"ZoomInfo"`

  - `"Clay"`

- `description: optional string`

- `harness: optional "claude-code" or "codex" or "litellm"`

  Supported agent harness strategies.

  Mirrors `PROVIDERS` in golden-agent's `project/harness/activity.py`.

  - `"claude-code"`

  - `"codex"`

  - `"litellm"`

- `model: optional string`

- `name: optional string`

- `persistent_workspace: optional boolean`

- `repos: optional array of RepoSpec`

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

- `system_prompt: optional string`

### Returns

- `id: string`

- `allowed_tools: array of string`

- `created_at: string`

- `harness: string`

- `model: string`

- `name: string`

- `system_prompt: string`

- `updated_at: string`

- `description: optional string`

- `object: optional "agent_config"`

  - `"agent_config"`

- `persistent_workspace: optional boolean`

- `repos: optional array of RepoSpec`

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs/$AGENT_CONFIG_ID \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "x-api-key: $SGP_API_KEY" \
    -d '{}'
```

#### Response

```json
{
  "id": "id",
  "allowed_tools": [
    "string"
  ],
  "created_at": "2019-12-27T18:11:19.117Z",
  "harness": "harness",
  "model": "model",
  "name": "name",
  "system_prompt": "system_prompt",
  "updated_at": "2019-12-27T18:11:19.117Z",
  "description": "description",
  "object": "agent_config",
  "persistent_workspace": true,
  "repos": [
    {
      "url": "x",
      "depth": 1,
      "path": "path"
    }
  ]
}
```

## Delete Agent Config (hard delete)

**delete** `/v5/agent_configs/{agent_config_id}`

Permanently delete an agent config; this is a hard delete, not an archive, so the row is removed and cannot be restored.

Because a config is only a template, deleting it does not stop or alter any task
already created from it. A user caller can only delete a config they created
unless fine-grained access control grants access. The response echoes the
deleted id.

### Path Parameters

- `agent_config_id: string`

### Returns

- `id: string`

- `deleted: boolean`

- `object: optional "agent_config"`

  - `"agent_config"`

### Example

```http
curl https://api.egp.scale.com/v5/agent_configs/$AGENT_CONFIG_ID \
    -X DELETE \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "id": "id",
  "deleted": true,
  "object": "agent_config"
}
```

## Domain Types

### Repo Spec

- `RepoSpec object { url, depth, path }`

  A single repo the agent should clone into its workspace.

  Mirrors the per-entry shape the golden agent's `_validate_repos` accepts:
  `url` is required, the rest are optional passthrough hints. Sent verbatim
  as `task.params.repos` so provisioning clones these instead of the
  deployment-global default.

  - `url: string`

  - `depth: optional number`

  - `path: optional string`

### Agent Config Create Response

- `AgentConfigCreateResponse object { id, allowed_tools, created_at, 9 more }`

  - `id: string`

  - `allowed_tools: array of string`

  - `created_at: string`

  - `harness: string`

  - `model: string`

  - `name: string`

  - `system_prompt: string`

  - `updated_at: string`

  - `description: optional string`

  - `object: optional "agent_config"`

    - `"agent_config"`

  - `persistent_workspace: optional boolean`

  - `repos: optional array of RepoSpec`

    - `url: string`

    - `depth: optional number`

    - `path: optional string`

### Agent Config List Response

- `AgentConfigListResponse object { id, allowed_tools, created_at, 9 more }`

  - `id: string`

  - `allowed_tools: array of string`

  - `created_at: string`

  - `harness: string`

  - `model: string`

  - `name: string`

  - `system_prompt: string`

  - `updated_at: string`

  - `description: optional string`

  - `object: optional "agent_config"`

    - `"agent_config"`

  - `persistent_workspace: optional boolean`

  - `repos: optional array of RepoSpec`

    - `url: string`

    - `depth: optional number`

    - `path: optional string`

### Agent Config List Mcp Tools Response

- `AgentConfigListMcpToolsResponse = array of "Slack" or "Linear" or "GitHub" or 21 more`

  - `"Slack"`

  - `"Linear"`

  - `"GitHub"`

  - `"Confluence"`

  - `"Notion"`

  - `"Datadog"`

  - `"PagerDuty"`

  - `"Salesforce"`

  - `"Figma"`

  - `"Granola"`

  - `"Jira"`

  - `"Gmail"`

  - `"GoogleCalendar"`

  - `"GoogleDrive"`

  - `"GoogleDocs"`

  - `"GoogleSheets"`

  - `"GoogleSlides"`

  - `"Snowflake"`

  - `"Redash"`

  - `"Tableau"`

  - `"Metabase"`

  - `"Gong"`

  - `"ZoomInfo"`

  - `"Clay"`

### Agent Config Retrieve Response

- `AgentConfigRetrieveResponse object { id, allowed_tools, created_at, 9 more }`

  - `id: string`

  - `allowed_tools: array of string`

  - `created_at: string`

  - `harness: string`

  - `model: string`

  - `name: string`

  - `system_prompt: string`

  - `updated_at: string`

  - `description: optional string`

  - `object: optional "agent_config"`

    - `"agent_config"`

  - `persistent_workspace: optional boolean`

  - `repos: optional array of RepoSpec`

    - `url: string`

    - `depth: optional number`

    - `path: optional string`

### Agent Config Update Response

- `AgentConfigUpdateResponse object { id, allowed_tools, created_at, 9 more }`

  - `id: string`

  - `allowed_tools: array of string`

  - `created_at: string`

  - `harness: string`

  - `model: string`

  - `name: string`

  - `system_prompt: string`

  - `updated_at: string`

  - `description: optional string`

  - `object: optional "agent_config"`

    - `"agent_config"`

  - `persistent_workspace: optional boolean`

  - `repos: optional array of RepoSpec`

    - `url: string`

    - `depth: optional number`

    - `path: optional string`

### Agent Config Delete Response

- `AgentConfigDeleteResponse object { id, deleted, object }`

  - `id: string`

  - `deleted: boolean`

  - `object: optional "agent_config"`

    - `"agent_config"`
