# Update a custom tool

- **OpenAPI Version:** `3.2.0`
- **API Version:** `3.1.0`
- **Contact:** Syndai <https://syndai.ai>

## Contents

**Operations**

- [PATCH /api/v1/external/coding/tools/{tool\_id}](#scalar-operation-patch-apiv1externalcodingtoolstool-id)

**Schemas**

- [CustomToolUpdateRequest](#scalar-schema-customtoolupdaterequest)
- [CustomToolManualClient](#scalar-schema-customtoolmanualclient)
- [CustomToolResponse](#scalar-schema-customtoolresponse)
- [CustomToolRead](#scalar-schema-customtoolread)
- [CustomToolOAuthRead](#scalar-schema-customtooloauthread)
- [ProblemDetail](#scalar-schema-problemdetail)
- [ExternalErrorCode](#scalar-schema-externalerrorcode)

<a id="scalar-context-global-servers"></a>

## Servers

- **URL:** `https://api.syndai.ai`

<a id="scalar-context-global-authentication"></a>

## Authentication

- **CustomerApiKey**: HTTP bearer (`API Key`)

  Customer API key sent as a bearer token

## Tags

### Tools

Custom tools your runs may call: skills and MCP servers, workspace-wide or for one project. Add, update, rescan or delete a tool. Each is safety-scanned, and runs skip a flagged tool until someone acknowledges the flag.

## Operations

<a id="scalar-operation-patch-apiv1externalcodingtoolstool-id"></a>

### Update a custom tool

- **Method:** `PATCH`
- **Path:** `/api/v1/external/coding/tools/{tool_id}`
- **Operation ID:** `updateTool`
- **Tags:** Tools

Edit a tool; a changed config is scanned again. Omitting an MCP server's `token` keeps the stored one, but moving the server to a new origin requires the token again. Returns 404 for an unknown tool. Requires the `coding:tools:write` scope.

**Servers:** [Inherited servers](#scalar-context-global-servers)

**Authentication:** [Global authentication](#scalar-context-global-authentication)

#### Path parameters

- **`tool_id` (required)**: `string`, format: `uuid`

#### Query parameters

- **`customer_id`**: `string | null`, format: `uuid`

#### Request body

**Required:** `true`

**Content type:** `application/json`

[CustomToolUpdateRequest](#scalar-schema-customtoolupdaterequest)

<a id="scalar-example-1"></a>

**Generated example:**

```json
{
  "auth_mode": "oauth",
  "config": {
    "additionalProperty": "anything"
  },
  "description": "",
  "enabled": true,
  "manual_client": {
    "client_id": "",
    "client_secret": ""
  },
  "name": "",
  "repository_id": ""
}
```

#### Responses

##### 200 Request fulfilled, document follows

**Content type:** `application/json`

[CustomToolResponse](#scalar-schema-customtoolresponse)

<a id="scalar-example-2"></a>

**Generated example:**

```json
{
  "tool": {
    "auth_mode": "token",
    "auth_status": "pending",
    "config": {
      "additionalProperty": "anything"
    },
    "description": "",
    "description_hint": "",
    "enabled": true,
    "has_token": true,
    "id": "",
    "kind": "mcp_server",
    "name": "",
    "not_ready_reason": "",
    "oauth": {
      "connected_at": "",
      "connected_by_left": true,
      "connected_by_name": "",
      "issuer_host": "",
      "redirect_uri": "",
      "requested_scopes": [
        ""
      ],
      "scopes": [
        ""
      ]
    },
    "repository_id": "",
    "run_ready": true,
    "scan_reason": "",
    "scan_status": "scanned",
    "scanned_at": ""
  }
}
```

##### 400, 401, 403, 404

- `400` Bad request syntax or unsupported method
- `401` Invalid or missing customer API key
- `403` Insufficient scope or forbidden customer access
- `404` Resource not found

**Content type:** `application/problem+json`

[ProblemDetail](#scalar-schema-problemdetail)

RFC 7807 problem detail returned for public CaaS errors.

<a id="scalar-example-3"></a>

**Generated example:**

```json
{
  "code": "BUDGET_EXHAUSTED",
  "detail": null,
  "existing_run_id": null,
  "instance": null,
  "status": 1,
  "title": "",
  "type": "about:blank",
  "additionalProperty": "anything"
}
```

##### 429 Rate limit exceeded

**Headers:**

- **`Retry-After`**

  Seconds to wait before retrying the request

  `integer`

**Content type:** `application/problem+json`

[ProblemDetail](#scalar-schema-problemdetail)

RFC 7807 problem detail returned for public CaaS errors.

[Generated example](#scalar-example-3)

##### default Unexpected error

**Content type:** `application/problem+json`

[ProblemDetail](#scalar-schema-problemdetail)

<a id="scalar-example-4"></a>

**Generated example:**

```json
null
```

## Schemas

<a id="scalar-schema-customtoolupdaterequest"></a>

### CustomToolUpdateRequest

**Type:** `object`

- **`auth_mode`**: `null | string`, possible values: `"oauth", "token", "none", null`
- **`config`**: `object | null`
- **`description`**: `string | null`
- **`enabled`**: `boolean | null`
- **`manual_client`**: [CustomToolManualClient](#scalar-schema-customtoolmanualclient) | `null`
- **`name`**: `string | null`
- **`repository_id`**: `string | null`, format: `uuid`

<a id="scalar-example-5"></a>

**Generated example:**

```json
{
  "auth_mode": "oauth",
  "config": {
    "additionalProperty": "anything"
  },
  "description": "",
  "enabled": true,
  "manual_client": {
    "client_id": "",
    "client_secret": ""
  },
  "name": "",
  "repository_id": ""
}
```

<a id="scalar-schema-customtoolmanualclient"></a>

### CustomToolManualClient

**Type:** `object`

- **`client_id` (required)**: `string`
- **`client_secret`**: `string | null`, format: `password`

<a id="scalar-example-6"></a>

**Generated example:**

```json
{
  "client_id": "",
  "client_secret": ""
}
```

<a id="scalar-schema-customtoolresponse"></a>

### CustomToolResponse

**Type:** `object`

- **`tool` (required)**: [CustomToolRead](#scalar-schema-customtoolread)

<a id="scalar-example-7"></a>

**Generated example:**

```json
{
  "tool": {
    "auth_mode": "token",
    "auth_status": "pending",
    "config": {
      "additionalProperty": "anything"
    },
    "description": "",
    "description_hint": "",
    "enabled": true,
    "has_token": true,
    "id": "",
    "kind": "mcp_server",
    "name": "",
    "not_ready_reason": "",
    "oauth": {
      "connected_at": "",
      "connected_by_left": true,
      "connected_by_name": "",
      "issuer_host": "",
      "redirect_uri": "",
      "requested_scopes": [
        ""
      ],
      "scopes": [
        ""
      ]
    },
    "repository_id": "",
    "run_ready": true,
    "scan_reason": "",
    "scan_status": "scanned",
    "scanned_at": ""
  }
}
```

<a id="scalar-schema-customtoolread"></a>

### CustomToolRead

**Type:** `object`

- **`config` (required)**: `object`
- **`description` (required)**: `string`
- **`enabled` (required)**: `boolean`
- **`has_token` (required)**: `boolean`
- **`id` (required)**: `string`
- **`kind` (required)**: `string`, possible values: `"mcp_server", "skill"`
- **`name` (required)**: `string`
- **`run_ready` (required)**: `boolean`
- **`scan_status` (required)**: `string`, possible values: `"scanned", "unscanned", "flagged", "acknowledged"`
- **`auth_mode`**: `string`, possible values: `"oauth", "token", "none"`, default: `"token"`
- **`auth_status`**: `null | string`, possible values: `"pending", "connected", "reconnect", "more_access", null`
- **`description_hint`**: `string | null`
- **`not_ready_reason`**: `string | null`
- **`oauth`**: [CustomToolOAuthRead](#scalar-schema-customtooloauthread) | `null`
- **`repository_id`**: `string | null`
- **`scan_reason`**: `string | null`
- **`scanned_at`**: `string | null`

<a id="scalar-example-8"></a>

**Generated example:**

```json
{
  "auth_mode": "token",
  "auth_status": "pending",
  "config": {
    "additionalProperty": "anything"
  },
  "description": "",
  "description_hint": "",
  "enabled": true,
  "has_token": true,
  "id": "",
  "kind": "mcp_server",
  "name": "",
  "not_ready_reason": "",
  "oauth": {
    "connected_at": "",
    "connected_by_left": true,
    "connected_by_name": "",
    "issuer_host": "",
    "redirect_uri": "",
    "requested_scopes": [
      ""
    ],
    "scopes": [
      ""
    ]
  },
  "repository_id": "",
  "run_ready": true,
  "scan_reason": "",
  "scan_status": "scanned",
  "scanned_at": ""
}
```

<a id="scalar-schema-customtooloauthread"></a>

### CustomToolOAuthRead

**Type:** `object`

- **`connected_by_left` (required)**: `boolean`
- **`requested_scopes` (required)**: `array of string`
- **`scopes` (required)**: `array of string`
- **`connected_at`**: `string | null`
- **`connected_by_name`**: `string | null`
- **`issuer_host`**: `string | null`
- **`redirect_uri`**: `string | null`

<a id="scalar-example-9"></a>

**Generated example:**

```json
{
  "connected_at": "",
  "connected_by_left": true,
  "connected_by_name": "",
  "issuer_host": "",
  "redirect_uri": "",
  "requested_scopes": [
    ""
  ],
  "scopes": [
    ""
  ]
}
```

<a id="scalar-schema-problemdetail"></a>

### ProblemDetail

**Type:** `object`

RFC 7807 problem detail returned for public CaaS errors.

- **`code` (required)**: `string`, possible values: `"BUDGET_EXHAUSTED", "QUOTA_EXCEEDED", "RUN_CONCURRENCY_LIMIT", "CUSTOMER_DISABLED", "REPO_NOT_BOUND", "IDEMPOTENCY_REPLAY", "CONFLICT", "MISSION_BUSY_RETRY", "HITL_REQUEST_CONFLICT", "HITL_REQUEST_SETTLED", "RUN_TERMINATED_BEFORE_RESPONSE", "INVALID_POLICY", "INVALID_SCOPE", "RATE_LIMITED", "INSTALLATION_INCOMPLETE", "SUBSCRIPTION_USAGE_UNAVAILABLE", "INVALID_TOKEN", "ROLE_REQUIRED", "PLAN_UPGRADE_REQUIRED", "EMAIL_MISMATCH", "EXPIRED_TOKEN", "NOT_FOUND", "OVERSCOPE_ACK_REQUIRED", "VERIFY_FAILED", "PUBLISH_IN_FLIGHT", "PUBLISH_UNSUPPORTED_REPO", "PUBLICATION_NOT_LIVE", "NO_APP_DATA", "FEATURE_REQUESTS_NEEDS_MEMBERS", "EMPTY_UPDATE", "BAD_CURSOR", "HUMAN_APPROVAL_REQUIRED", "PROTECTED_PATHS_MANAGED_ONLY", "RUN_IN_FLIGHT", "TEXT_EDIT_REFUSED", "CLI_UPGRADE_REQUIRED", "PRODUCTION_STEP_UP_REQUIRED", "PRICES_UPDATING", "GITHUB_UNAVAILABLE", "PUBLISH_NOT_SET_UP", "VERSION_NOT_DEPLOYED", "INTERNAL_ERROR"`

  Stable error codes surfaced to public CaaS clients.
- **`status` (required)**: `integer`
- **`title` (required)**: `string`
- **`detail`**: `string | null`, default: `null`
- **`existing_run_id`**: `string | null`, default: `null`
- **`instance`**: `string | null`, default: `null`
- **`type`**: `string`, default: `"about:blank"`

<a id="scalar-example-10"></a>

**Generated example:**

```json
{
  "code": "BUDGET_EXHAUSTED",
  "detail": null,
  "existing_run_id": null,
  "instance": null,
  "status": 1,
  "title": "",
  "type": "about:blank",
  "additionalProperty": "anything"
}
```

<a id="scalar-schema-externalerrorcode"></a>

### ExternalErrorCode

**Type:** `string`, possible values: `"BUDGET_EXHAUSTED", "QUOTA_EXCEEDED", "RUN_CONCURRENCY_LIMIT", "CUSTOMER_DISABLED", "REPO_NOT_BOUND", "IDEMPOTENCY_REPLAY", "CONFLICT", "MISSION_BUSY_RETRY", "HITL_REQUEST_CONFLICT", "HITL_REQUEST_SETTLED", "RUN_TERMINATED_BEFORE_RESPONSE", "INVALID_POLICY", "INVALID_SCOPE", "RATE_LIMITED", "INSTALLATION_INCOMPLETE", "SUBSCRIPTION_USAGE_UNAVAILABLE", "INVALID_TOKEN", "ROLE_REQUIRED", "PLAN_UPGRADE_REQUIRED", "EMAIL_MISMATCH", "EXPIRED_TOKEN", "NOT_FOUND", "OVERSCOPE_ACK_REQUIRED", "VERIFY_FAILED", "PUBLISH_IN_FLIGHT", "PUBLISH_UNSUPPORTED_REPO", "PUBLICATION_NOT_LIVE", "NO_APP_DATA", "FEATURE_REQUESTS_NEEDS_MEMBERS", "EMPTY_UPDATE", "BAD_CURSOR", "HUMAN_APPROVAL_REQUIRED", "PROTECTED_PATHS_MANAGED_ONLY", "RUN_IN_FLIGHT", "TEXT_EDIT_REFUSED", "CLI_UPGRADE_REQUIRED", "PRODUCTION_STEP_UP_REQUIRED", "PRICES_UPDATING", "GITHUB_UNAVAILABLE", "PUBLISH_NOT_SET_UP", "VERSION_NOT_DEPLOYED", "INTERNAL_ERROR"`

Stable error codes surfaced to public CaaS clients.
