---
title: "What the caller may do here"
method: GET
path: "/projects/{projectId}/capabilities"
tags: ["Projects"]
---

# What the caller may do here

`GET /projects/{projectId}/capabilities`

Role, gate state, plan limits and a set of derived booleans — so an agent on a static surface can check before it acts instead of attempting a write and reading the failure.

Descriptive, never authoritative: see the schema.

## Response `200`

The caller's capabilities in this project.

- ProjectCapabilities — What the caller may do in this project, asked BEFORE they try it. **A planning aid, not a gate.** Every enforcement point is unchanged: the write path checks roles and the beta flag inside the platform regardless of what this returned a second earlier. A caller that reads a `true` here and races a flag flip gets the same clean `403` it would have got without asking. Nothing may consult this INSTEAD of its own check. It exists because every agent surface MCPJam ships is static — one MCP tool catalog built with no organization in hand, a CLI command tree fixed at install — so an agent planning a task otherwise has to attempt the write and read the failure. By then it has usually already told a human what it was about to do.
  - `projectId` string, required
  - `organizationId` string, nullable, required
  - `role` string, required — The caller's ORGANIZATION role: `guest`, `member`, `admin` or `owner`. This is what the platform's role checks rank; a project grant does not raise it.
  - `projectRole` string, required — `admin` or `editor`, when the caller holds a project grant.
  - `surface` string, required — Which channel we resolved this request to arrive on. Echoed so an agent can confirm it is labelled the way it expects — a CLI showing up as `rest` means its user agent is not reaching us.
  - `features` object, required
    - `sandboxes` object, required
      - `enabled` boolean, required
      - `mode` 'off' | 'dark' | 'enforce', required — `off` | `dark` | `enforce`. Only `enforce` turns a disabled flag into a refusal; in `dark` the platform logs what it would have blocked and lets the write through.
      - `enforced` boolean, required
      - `reason` string
  - `plan` object, nullable, required
    - `name` string, required
    - `limits` object, required
    - `features` object, required
  - `vocabulary` object — The eval vocabulary this deployment understands (see the `x-mcpjam-eval-vocabulary` header). Absent on a deployment that predates the negotiation, which then speaks only vocabulary 1. Each `fields` entry lists the LEGACY spellings a vocabulary-2 body may still use for that canonical field; a canonical spelling sent together with one of its legacy spellings is refused. `iterations` is deliberately absent from `legacyIterations`: under vocabulary 2 that key is the exact count, not the floor.
    - `version` 2, required
    - `evaluatorKinds` string[], required
    - `assertionKinds` string[], required — The assertion types a case may author, in the same order and spelling as `EvalCheck.type`.
    - `fields` object, required
      - `assertions` string[], required
      - `defaultAssertions` string[], required
      - `iterations` string[], required
      - `legacyIterations` string[], required
  - `apiVocabulary` object — The resource-noun VALUE vocabulary this deployment understands (see the `x-mcpjam-api-vocabulary` header). Absent on a deployment that predates the negotiation, which then speaks only vocabulary 1. SEPARATE from `vocabulary` above, which is eval-scoped by name and moves on its own schedule.
    - `version` 2, required
    - `values` object, required — Value family -> (stored spelling -> canonical spelling). A family with no renamed member is absent rather than empty, so a client can read "nothing moves here" from the shape.
    - `resourceTypes` object, required — Permalink resource type -> the pre-rename keys that resolve to the same route. Listed apart from `values` because these are table KEYS, not a per-request projection: both spellings resolve at all times, and which one a response carries follows the OPERATION rather than the header.
  - `can` object, required — The booleans to branch on, derived server-side rather than left for each caller to re-derive from `role` plus flag state.
    - `readSwarms` boolean, required
    - `readUserTesting` boolean, required
    - `writeSwarms` boolean, required — Authoring personas, goals and swarms.
    - `launchGoalRun` boolean, required
    - `cancelGoalRun` boolean, required — Stays TRUE for an organization that has lost the beta. Losing the feature is exactly when stopping a run matters most.
    - `launchJourneyRun` boolean, required — Pre-rename spelling of `launchGoalRun`, emitted alongside it until general availability.
    - `cancelJourneyRun` boolean, required — Pre-rename spelling of `cancelGoalRun`, emitted alongside it until general availability.
    - `publishUserTestingScenario` boolean, required — Project admin, and behind the beta gate.
    - `unpublishUserTestingScenario` boolean, required — Project admin, NOT gated — same reasoning as cancelling a run.
    - `changeUserTestingExposure` boolean, required — Mode changes, member invites and removals, link rotation, renames — the controls an ordinary MEMBER can use, none of them gated. Guest execution is not covered here; it needs admin and has its own key.
    - `manageUserTestingGuestExecution` boolean, required — The guest-execution spend caps. Project admin, ungated.
    - `requestInsights` boolean, required
    - `readEvals` boolean, required — Reading eval suites, runs, iterations and traces.
    - `writeEvalSuites` boolean, required — Authoring suites and cases — every eval write short of deleting. Unlike the swarm keys this counts a project GRANT, not organization rank alone.
    - `launchEvalRun` boolean, required — Starting a suite or case run.
    - `deleteAnyEvalSuite` boolean, required — Deleting a suite SOMEONE ELSE created — the project admin tier. The creator of a suite may always delete it whatever their role, so `false` here does not mean you cannot delete your own.
    - `deleteAnyEvalRun` boolean, required — Same tier and same creator exception, for runs.
    - `exportEvalTraces` boolean, required — Whether the trace export surface is open. Export still filters row by row against the caller, so this does not promise every session in the project lands in the file.

## Other responses

- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.

## Changes

- **2026-09-22** `561e4fd0dfa2` — 5 info
  - added the optional property `apiVocabulary` to the response with the `200` status
  - response property `can/cancelJourneyRun` deprecated
  - response property `can/launchJourneyRun` deprecated
  - added the required property `can/cancelGoalRun` to the response with the `200` status
  - …1 more
- **2026-09-14** `aba99a0018e2` — 1 info
  - added the optional property `vocabulary` to the response with the `200` status
- **2026-08-18** `64b8be1de874` — 6 info
  - added the required property `can/deleteAnyEvalRun` to the response with the `200` status
  - added the required property `can/deleteAnyEvalSuite` to the response with the `200` status
  - added the required property `can/exportEvalTraces` to the response with the `200` status
  - added the required property `can/launchEvalRun` to the response with the `200` status
  - …2 more
- **2026-08-15** `d3adfe49fbbf` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/mcpjam/apis/mcpjam-api/changes/projects/:projectId/capabilities/get.md)

---

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