> For the complete documentation index, see [llms.txt](https://docs.kinesis.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kinesis.network/mcp/tools/observability.md).

# Logs and usage

Read per-server runtime logs and resource usage over time.

Read per-server runtime logs and resource usage over time.

These are action names. In default compact mode, call the indicated group tool with `{"action":"<action-name>","params":{...}}`; the arguments below go inside `params`. In `?mode=all`, call the action name directly with those arguments. `browse_github` and `read_docs` are direct tools in both modes. Expand each schema for nested fields, enum values and validation constraints. Successful results are JSON in both text content and `structuredContent`; failures use `isError` and `structuredContent.error`.

Logs and log exports contain the app’s raw output and can include sensitive data. The OpenAI profile’s environment-value filtering does not sanitize log text.

The [OpenAI profile](/mcp/openai-profile.md) calls individual actions, omits `get_byod_token`, and restricts credential inputs and environment outputs. The input schemas below describe the standard catalog; profile-specific schemas are included where they differ.

## `get_app_logs`

Read a page of container logs for an app. Paging starts at the newest lines and moves back in time by default; inside a page, chunks and lines run oldest to newest, so the last line is the most recent. Lines are the app's own output, as it wrote them, so they can hold anything it prints, sensitive data included.

**Group:** `apps` · **Behavior:** Read

**Compact tool:** `apps` · **Action:** `get_app_logs`

**MCP annotations:** `readOnlyHint: true` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Permissions and REST equivalents

| Operation   | REST                                          | Required scopes   |
| ----------- | --------------------------------------------- | ----------------- |
| `apps.logs` | `GET /projects/{projectId}/apps/{appId}/logs` | `monitoring:read` |

### Arguments

| Argument    | Type                | Required | Description                                                                                                               |
| ----------- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `projectId` | `string`            | Yes      | Project id                                                                                                                |
| `appId`     | `string`            | Yes      | App id                                                                                                                    |
| `nodes`     | `array<string>`     | No       | Server addresses to read from; omit for every server the app ran on                                                       |
| `cursorNs`  | `string`            | No       | Cursor from a previous page (nextCursorNs)                                                                                |
| `cursor`    | `integer`           | No       | Unix time in milliseconds to seek to when no cursorNs is given; 0 or omitted means now                                    |
| `pageSize`  | `integer`           | No       | Lines per page, at most 1000 (default 200)                                                                                |
| `direction` | `"older" / "newer"` | No       | Which way the next page moves from the cursor: older (the default) or newer. Lines inside a page are always chronological |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    },
    "nodes": {
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Server addresses to read from; omit for every server the app ran on"
    },
    "cursorNs": {
      "type": "string",
      "description": "Cursor from a previous page (nextCursorNs)"
    },
    "cursor": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991,
      "description": "Unix time in milliseconds to seek to when no cursorNs is given; 0 or omitted means now"
    },
    "pageSize": {
      "type": "integer",
      "minimum": 1,
      "maximum": 1000,
      "description": "Lines per page, at most 1000 (default 200)"
    },
    "direction": {
      "type": "string",
      "enum": [
        "older",
        "newer"
      ],
      "description": "Which way the next page moves from the cursor: older (the default) or newer. Lines inside a page are always chronological"
    }
  },
  "required": [
    "projectId",
    "appId"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `logs` (`array<object>`): Chunks in chronological order, consecutive lines from one server merged into a chunk that from and to span; the last line of the last chunk is the newest
* `nextCursorNs` (`string or null`): Pass as cursorNs to fetch the next page in the same direction; null at the end
* `hasMore` (`boolean`): See the complete response schema below.
* `totalLines` (`integer`): Lines in this page across every chunk

<details>

<summary>Response schema: apps.logs</summary>

```json
{
  "type": "object",
  "properties": {
    "logs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "node": {
            "type": "string",
            "description": "Server address the lines came from"
          },
          "from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "description": "ISO 8601 timestamp (UTC)"
              },
              {
                "type": "null"
              }
            ]
          },
          "to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "description": "ISO 8601 timestamp (UTC)"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "node",
          "from",
          "to",
          "lines"
        ],
        "additionalProperties": false
      },
      "description": "Chunks in chronological order, consecutive lines from one server merged into a chunk that from and to span; the last line of the last chunk is the newest"
    },
    "nextCursorNs": {
      "description": "Pass as cursorNs to fetch the next page in the same direction; null at the end",
      "type": [
        "string",
        "null"
      ]
    },
    "hasMore": {
      "type": "boolean"
    },
    "totalLines": {
      "type": "integer",
      "description": "Lines in this page across every chunk"
    }
  },
  "required": [
    "logs",
    "nextCursorNs",
    "hasMore",
    "totalLines"
  ],
  "additionalProperties": false
}
```

</details>

## `get_app_usage`

Resource usage of an app over a time range, bucketed per server

**Group:** `apps` · **Behavior:** Read

**Compact tool:** `apps` · **Action:** `get_app_usage`

**MCP annotations:** `readOnlyHint: true` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Permissions and REST equivalents

| Operation    | REST                                           | Required scopes   |
| ------------ | ---------------------------------------------- | ----------------- |
| `apps.usage` | `GET /projects/{projectId}/apps/{appId}/usage` | `monitoring:read` |

### Arguments

| Argument    | Type     | Required | Description                                                        |
| ----------- | -------- | -------- | ------------------------------------------------------------------ |
| `projectId` | `string` | Yes      | Project id                                                         |
| `appId`     | `string` | Yes      | App id                                                             |
| `start`     | `string` | No       | Range start (ISO 8601); defaults to one hour before end            |
| `end`       | `string` | No       | Range end (ISO 8601); defaults to now. At most 30 days after start |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    },
    "start": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
      "description": "Range start (ISO 8601); defaults to one hour before end"
    },
    "end": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
      "description": "Range end (ISO 8601); defaults to now. At most 30 days after start"
    }
  },
  "required": [
    "projectId",
    "appId"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `start` (`string`): ISO 8601 timestamp (UTC)
* `end` (`string`): ISO 8601 timestamp (UTC)
* `intervalSeconds` (`integer`): Width of each bucket
* `series` (`array<object>`): One series per server the app ran on; each point sums the bucket

<details>

<summary>Response schema: apps.usage</summary>

```json
{
  "type": "object",
  "properties": {
    "start": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp (UTC)"
    },
    "end": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp (UTC)"
    },
    "intervalSeconds": {
      "type": "integer",
      "description": "Width of each bucket"
    },
    "series": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "node": {
            "type": "string",
            "description": "Server address"
          },
          "points": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Bucket start"
                },
                "cpuNs": {
                  "type": "number",
                  "description": "CPU time consumed, in nanoseconds"
                },
                "gpuNs": {
                  "type": "number",
                  "description": "GPU time consumed, in nanoseconds"
                },
                "gpuMemBytesSecs": {
                  "type": "number",
                  "description": "GPU memory held, in byte-seconds"
                },
                "memBytesSecs": {
                  "type": "number",
                  "description": "RAM held, in byte-seconds"
                },
                "storageBytesSecs": {
                  "type": "number",
                  "description": "Disk held, in byte-seconds"
                },
                "logStorageBytesSecs": {
                  "type": "number",
                  "description": "Log storage held, in byte-seconds"
                },
                "bwInBytes": {
                  "type": "number",
                  "description": "Bytes received"
                },
                "bwOutBytes": {
                  "type": "number",
                  "description": "Bytes sent"
                }
              },
              "required": [
                "at",
                "cpuNs",
                "gpuNs",
                "gpuMemBytesSecs",
                "memBytesSecs",
                "storageBytesSecs",
                "logStorageBytesSecs",
                "bwInBytes",
                "bwOutBytes"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "node",
          "points"
        ],
        "additionalProperties": false
      },
      "description": "One series per server the app ran on; each point sums the bucket"
    }
  },
  "required": [
    "start",
    "end",
    "intervalSeconds",
    "series"
  ],
  "additionalProperties": false
}
```

</details>

## `export_logs`

The app's container logs as one text, oldest first. Every line is stamped with its time and server, up to maxBytes (1 MiB by default, 4 MiB at most). For a page at a time use apps.logs instead. Lines are the app's own output, as it wrote them, so they can hold anything it prints, sensitive data included.

**Group:** `apps` · **Behavior:** Read

**Compact tool:** `apps` · **Action:** `export_logs`

**MCP annotations:** `readOnlyHint: true` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Permissions and REST equivalents

| Operation          | REST                                                 | Required scopes   |
| ------------------ | ---------------------------------------------------- | ----------------- |
| `apps.logs.export` | `GET /projects/{projectId}/apps/{appId}/logs/export` | `monitoring:read` |

### Arguments

| Argument    | Type            | Required | Description                                            |
| ----------- | --------------- | -------- | ------------------------------------------------------ |
| `projectId` | `string`        | Yes      | Project id                                             |
| `appId`     | `string`        | Yes      | App id                                                 |
| `nodes`     | `array<string>` | No       | Server addresses to include; omit for all              |
| `maxBytes`  | `integer`       | No       | Stop after this many bytes of text; 1048576 by default |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    },
    "nodes": {
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Server addresses to include; omit for all"
    },
    "maxBytes": {
      "type": "integer",
      "minimum": 1024,
      "maximum": 4194304,
      "description": "Stop after this many bytes of text; 1048576 by default"
    }
  },
  "required": [
    "projectId",
    "appId"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `text` (`string`): The log lines, newline-separated
* `lines` (`integer`): See the complete response schema below.
* `truncated` (`boolean`): maxBytes was reached before the end; the newest lines are missing

<details>

<summary>Response schema: apps.logs.export</summary>

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "The log lines, newline-separated"
    },
    "lines": {
      "type": "integer"
    },
    "truncated": {
      "type": "boolean",
      "description": "maxBytes was reached before the end; the newest lines are missing"
    }
  },
  "required": [
    "text",
    "lines",
    "truncated"
  ],
  "additionalProperties": false
}
```

</details>

Operation-specific errors: `429 too_many_attempts`.

## `get_log_retention`

How long the app's container logs are kept

**Group:** `apps` · **Behavior:** Read

**Compact tool:** `apps` · **Action:** `get_log_retention`

**MCP annotations:** `readOnlyHint: true` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Permissions and REST equivalents

| Operation                 | REST                                                    | Required scopes |
| ------------------------- | ------------------------------------------------------- | --------------- |
| `apps.logs.retention.get` | `GET /projects/{projectId}/apps/{appId}/logs/retention` | `apps:read`     |

### Arguments

| Argument    | Type     | Required | Description |
| ----------- | -------- | -------- | ----------- |
| `projectId` | `string` | Yes      | Project id  |
| `appId`     | `string` | Yes      | App id      |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    }
  },
  "required": [
    "projectId",
    "appId"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `days` (`integer`): How many days of container logs are kept
* `isDefault` (`boolean`): The platform default applies; no per-app setting

<details>

<summary>Response schema: apps.logs.retention.get</summary>

```json
{
  "type": "object",
  "properties": {
    "days": {
      "type": "integer",
      "description": "How many days of container logs are kept"
    },
    "isDefault": {
      "type": "boolean",
      "description": "The platform default applies; no per-app setting"
    }
  },
  "required": [
    "days",
    "isDefault"
  ],
  "additionalProperties": false
}
```

</details>

## `set_log_retention`

Set how many days the app's container logs are kept. 1 to 180; 0 goes back to the platform default

**Group:** `apps` · **Behavior:** Write

**Compact tool:** `apps_write` · **Action:** `set_log_retention`

**MCP annotations:** `readOnlyHint: false` · `destructiveHint: true` · `idempotentHint: true` · `openWorldHint: false`

### Permissions and REST equivalents

| Operation                    | REST                                                      | Required scopes |
| ---------------------------- | --------------------------------------------------------- | --------------- |
| `apps.logs.retention.update` | `PATCH /projects/{projectId}/apps/{appId}/logs/retention` | `apps:write`    |

### Arguments

| Argument    | Type      | Required | Description                     |
| ----------- | --------- | -------- | ------------------------------- |
| `days`      | `integer` | Yes      | Days to keep; 0 for the default |
| `projectId` | `string`  | Yes      | Project id                      |
| `appId`     | `string`  | Yes      | App id                          |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "days": {
      "type": "integer",
      "minimum": 0,
      "maximum": 180,
      "description": "Days to keep; 0 for the default"
    },
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    }
  },
  "required": [
    "days",
    "projectId",
    "appId"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `days` (`integer`): How many days of container logs are kept
* `isDefault` (`boolean`): The platform default applies; no per-app setting

<details>

<summary>Response schema: apps.logs.retention.update</summary>

```json
{
  "type": "object",
  "properties": {
    "days": {
      "type": "integer",
      "description": "How many days of container logs are kept"
    },
    "isDefault": {
      "type": "boolean",
      "description": "The platform default applies; no per-app setting"
    }
  },
  "required": [
    "days",
    "isDefault"
  ],
  "additionalProperties": false
}
```

</details>

Operation-specific errors: `429 too_many_attempts`.

## `clear_logs`

Delete the app's container logs older than a point in time. Cannot be undone.

**Group:** `apps` · **Behavior:** Write

**Compact tool:** `apps_write` · **Action:** `clear_logs`

**MCP annotations:** `readOnlyHint: false` · `destructiveHint: true` · `idempotentHint: false` · `openWorldHint: false`

Requires `confirm: true` for this irreversible action.

### Permissions and REST equivalents

| Operation         | REST                                                 | Required scopes |
| ----------------- | ---------------------------------------------------- | --------------- |
| `apps.logs.clear` | `POST /projects/{projectId}/apps/{appId}/logs/clear` | `apps:write`    |

### Arguments

| Argument    | Type     | Required | Description                                |
| ----------- | -------- | -------- | ------------------------------------------ |
| `olderThan` | `string` | Yes      | Lines before this instant are deleted      |
| `projectId` | `string` | Yes      | Project id                                 |
| `appId`     | `string` | Yes      | App id                                     |
| `confirm`   | `true`   | Yes      | Must be true: this action cannot be undone |

<details>

<summary>Complete input schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "olderThan": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
      "description": "Lines before this instant are deleted"
    },
    "projectId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "Project id"
    },
    "appId": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$",
      "description": "App id"
    },
    "confirm": {
      "type": "boolean",
      "const": true,
      "description": "Must be true: this action cannot be undone"
    }
  },
  "required": [
    "olderThan",
    "projectId",
    "appId",
    "confirm"
  ],
  "additionalProperties": false
}
```

</details>

### Result

* `deletedCount` (`integer`): Lines deleted

<details>

<summary>Response schema: apps.logs.clear</summary>

```json
{
  "type": "object",
  "properties": {
    "deletedCount": {
      "type": "integer",
      "description": "Lines deleted"
    }
  },
  "required": [
    "deletedCount"
  ],
  "additionalProperties": false
}
```

</details>

Operation-specific errors: `429 too_many_attempts`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.kinesis.network/mcp/tools/observability.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
