---
title: "List what AI agents did through the MCP server"
method: GET
path: "/logs/mcp"
tags: ["Logs"]
---

# List what AI agents did through the MCP server

`GET /logs/mcp`

## Request

- Base URL: `https://api.oveyon.com/v1`
- URL: `https://api.oveyon.com/v1/logs/mcp`
- Auth: HTTP bearer

One entry per JSON-RPC message that reached the MCP server with a credential of the account — the tool the agent called, through which app (ChatGPT, Claude…), from where, how it ended and which API calls it made (their `mcpCallId` in GET /v1/logs is this `callId`). Kept for 180 days, like the API log. This log never keeps tool results, only their size (the API call a tool makes is in GET /v1/logs, redacted like any call); arguments are stored redacted (GET /v1/logs/mcp/{id}). Requests whose credential could not be identified are not in the log (a known key that is refused — switched off, for example — is). Scope read:logs.

## Query parameters

- `limit` integer
- `cursor` string
- `outcome` 'ok' | 'tool_error' | 'rejected' | 'error' | 'aborted'
- `tool` string
- `method` string
- `credential` integer
- `from` string
- `to` string

## Response `200`

Page

- McpLogList
  - `data` McpLog[], required
    - `id` integer, required: The MCP log entry id (GET /v1/logs/mcp/{id}).
    - `createdAt` string, date-time, required: When the request carrying this message ARRIVED (milliseconds).
    - `callId` string, required: One per JSON-RPC message. The API calls this message made carry the same value in `mcpCallId` (GET /v1/logs).
    - `credential` object, required: The credential the agent used: the connection an app (ChatGPT, Claude…) got through OAuth, or an API key used directly (`name` and `prefix` are null once it is deleted).
      - `id` integer, required
      - `name` string, nullable, required
      - `prefix` string, nullable, required
    - `application` object, nullable, required: The app behind an OAuth connection: the name it declared and the host it comes from. null = an API key used directly.
      - `name` string, nullable, required
      - `origin` string, nullable, required
    - `method` string, nullable, required: The JSON-RPC method (`tools/call`, `tools/list`, `initialize`…). null = no message could be read (malformed body, or a GET/DELETE answered 405).
    - `tool` string, nullable, required: The tool the agent called (only on `tools/call`).
    - `outcome` 'ok' | 'tool_error' | 'rejected' | 'error' | 'aborted', required: `ok`; `tool_error` = the tool ran and returned an error — usually the error the API answered (see `apiStatuses`); `rejected` = the MCP server refused the call before running the tool (unknown tool, invalid arguments); `error` = the MCP request itself failed with an HTTP 4xx/5xx (malformed JSON, method not allowed, the key refused…); `aborted` = the client gave up before the answer. Outside `tools/call`, `ok` means the request was answered: a protocol error inside the answer (an unknown method or resource) is not read.
    - `error` string, nullable, required: Why the message did not end `ok` at the MCP level: `tool_not_found`, `invalid_arguments`, or the error of the MCP request itself (`parse_error`, `method_not_allowed`, the authentication `error`…). The error of an API call the tool made is `apiError` (GET /v1/logs/mcp/{id}).
    - `status` integer, required: The HTTP status of the MCP request that carried this message.
    - `durationMs` integer, required: Server-side time of that request.
    - `apiCalls` integer, required: How many API calls this message made (0 for protocol messages).
    - `apiStatuses` integer[], required: The HTTP status of each of those API calls, in order.
    - `client` object, nullable, required: What the client DECLARED in `initialize` (clientInfo) — it authenticates nothing. null = not declared.
      - `name` string, required
      - `version` string, nullable, required
    - `batch` object, required: A JSON-RPC batch becomes one entry per message: how many came together, and this one's position (0-based).
      - `size` integer, required
      - `index` integer, required
  - `next_cursor` string, nullable, required: null = last page.

## Other responses

- `400`: bad_cursor, bad_date, bad_outcome, bad_tool, bad_method, bad_credential.
- `401`: Missing or invalid API key.
- `403`: Insufficient scope (`insufficient_scope`, with `required` and `have`), a scope the key holds but cannot use while its human-approval lock is on (`scope_blocked_by_approval_lock`, with `required` — approve:holds, write:send-policies, manage:webhooks, write:inbound, write:templates, write:surveys, write:domains, write:contacts), API key switched off by its owner in the panel (`key_disabled` — the key is valid; turn it back on or use another one, do not rotate), sending disabled, account suspended (`account_suspended`) or unknown (`account_unknown`), or the key used from an IP outside its allowed ranges (`ip_not_allowed`, with the `allowed` list — see /v1/credentials/ip-rules). 403 is not a limit: do not retry.
- `429`: Per-key limit (`rate_limited`, 600 requests/min by default per API key — or per MCP OAuth connection —, from any IP), per-IP limit for requests WITHOUT a valid credential (`rate_limited`, 600/min by default), too many unknown or malformed credentials from your address (`too_many_auth_failures`, 20/min by default, counted per IPv4 address or per IPv6 /48; a missing `Authorization`, an expired OAuth token or a disabled key do not count, and anything without the shape of one of our keys counts without being checked; from an address over that limit a valid key still gets through within 120 credential checks/min, and above them every credential not validated in the last 5 minutes gets this 429 until the minute turns) — all checked before the route, on every operation —, account quota (`quota_exceeded` with `window`, `used`, `limit`), warmup cap (`warmup_cap_reached`) or saturation (`queue_full`). Honor `Retry-After` with exponential backoff and jitter.
- `500`: internal_error — an unexpected failure on our side. The detail stays in our logs, never in the body. Retry reads; retry a write only when it is idempotent or carries an idempotency key.
- `503`: ip_rules_unavailable — the IP ranges bound to your key could not be checked right now (caution, not a denial). Retry after `Retry-After` (30 s).

---

[API](https://skmtc.dev/oveyon/apis/oveyon-api.md) · [All operations](https://skmtc.dev/oveyon/apis/oveyon-api/llms.txt) · [OpenAPI document](https://skmtc.dev/oveyon/apis/oveyon-api/revisions/abf64c09d297?raw)
