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

# MCP sessions

> Mint short-lived, revocable, least-privilege credentials for the Vetta MCP server.

An MCP session is an opaque bearer for [`POST /v1/mcp`](https://vetta.sh/docs/api/mcp). It carries an organization,
control-plane scopes, an explicit tool allowlist, an expiry and, optionally, an
[identity](https://vetta.sh/docs/api/identities.md) as a label. The label is not enforced yet: a session acts on any identity
its scopes and tools reach. Use one instead of a general API key when an MCP client should have a bounded lifetime and
blast radius.

The lifecycle routes require the `admin` scope. They are withheld from the MCP catalog itself, so a
model cannot mint, enumerate, or revoke credentials.

## Create

`POST /v1/mcp_sessions`

```bash theme={"system"}
curl -fsSL https://api.vetta.sh/v1/mcp_sessions \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{
    "name": "release agent",
    "identity_id": "idn_01H...",
    "scopes": ["agents:read", "sessions:write"],
    "allowed_tools": ["agents_list", "sessions_create"],
    "expires_in_seconds": 3600
  }'
```

`expires_in_seconds` defaults to one day and must be between 60 seconds and 30 days. Duplicate
scopes and tool names are collapsed. If `identity_id` is present, it must name an identity in the
same organization.

The response contains `secret` exactly once. Store it as a secret; the server stores only its
SHA-256 digest. Later reads expose the non-sensitive `prefix` so an operator can identify the
credential without replaying it.

```json theme={"system"}
{
  "id": "mcs_01H...",
  "object": "mcp_session",
  "name": "release agent",
  "identity_id": "idn_01H...",
  "scopes": ["agents:read", "sessions:write"],
  "allowed_tools": ["agents_list", "sessions_create"],
  "prefix": "mcp_01H...",
  "expires_at": "2026-09-07T18:00:00Z",
  "revoked_at": null,
  "created_at": "2026-09-07T17:00:00Z",
  "secret": "mcp_..."
}
```

The secret is shown only in this response. It is random and unrelated to the session's `id`; only its
SHA-256 and the `prefix` are stored. Use it as the MCP endpoint bearer:

```bash theme={"system"}
Authorization: Bearer mcp_...
```

`tools/list` returns only `allowed_tools`. A call must also satisfy its underlying route scope;
allowlisting a tool never widens `scopes`. The bearer also works on the REST route behind an
allowlisted tool, but never on a route the MCP catalog withholds (creating or rotating API keys,
creating MCP sessions, and the like), whatever the allowlist names: those answer `403`. Expiry and revocation are checked from storage on every
request, so revocation has no cache-delay window.

## List and inspect

* `GET /v1/mcp_sessions`
* `GET /v1/mcp_sessions/{id}`

Both return metadata only. Neither returns `secret` nor `secret_hash`.

## Revoke

`DELETE /v1/mcp_sessions/{id}` marks an active credential revoked. The next request made with that
bearer receives `401 unauthorized`. Revocation is one-way; mint a new session to restore access.

## TypeScript

```ts theme={"system"}
const session = await vetta.mcpSessions.create({
  name: "release agent",
  scopes: ["agents:read"],
  allowed_tools: ["agents_list"],
  expires_in_seconds: 3600,
});

await vetta.mcpSessions.list();
await vetta.mcpSessions.get(session.id);
await vetta.mcpSessions.revoke(session.id);
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.