Skip to main content
Connect to the Reinx MCP server with an organization key (reinx_org_live_…) and you get the management band instead of the agent spend band: tools for provisioning and configuring agents, projects, and teams. This is the “give one agent the orchestrator role” surface. An orchestrator can create a worker agent, set its budget, pause it, and read its activity — but can never spend its money.

Configuration

Same URL as the agent band — the credential prefix selects the band.
The bands are disjoint. An organization key cannot see or call request_wallet_payment or any other spend tool. If you need one identity that both manages and spends, you need two credentials — that separation is the point.

Every call needs a purpose

All 21 tools — including search_docs and get_docs_page — require a purpose string of 3–500 characters explaining why the orchestrator is acting. Omitting it fails schema validation, so a client built without it fails on every call. It is recorded in the organization’s append-only audit ledger alongside the call outcome — write something an operator would find useful, and never put personal data in it. Note the ledger is append-only but not indefinitely readable: audit queries are clamped to the organization’s retention window (Free 7 days, Pro 30, Enterprise full history), so do not treat this trail as a permanently queryable record of your own activity.

What gates each call

The 19 resource-management tools must pass three checks, independently:
  1. Scope — does the key carry the required scope? Missing → 403 INSUFFICIENT_SCOPE (the response names the required_scope).
  2. Binding rung — may a key bound at this level call this route at all? No → 403 BINDING_NOT_ALLOWED.
  3. Target scope — the rung is fine, but is the object inside the key’s container? No → 403 OUT_OF_SCOPE, or 404 where the route hides the object’s existence entirely.
The last two are easy to conflate and need different fixes: BINDING_NOT_ALLOWED means the route is above your rung, OUT_OF_SCOPE means the object is outside your container.
Gate 3 fires only on per-target operationsget_*, set_*, pause_agent, archive_agent, anything naming one object. The list reads (list_agents, list_transactions, list_audit_events) behave differently: an out-of-binding projectId / teamId filter is intersected with the binding, so it returns a successful empty result, not 403 OUT_OF_SCOPE or 404. A bound key can never widen its view by passing a foreign filter — but it also never gets an error for trying, so do not wait for one. An empty list from a filtered read may simply mean the filter fell outside your binding.
search_docs and get_docs_page are exempt from all three. They need a valid org key and a purpose, but carry no scope requirement and no binding check — they only fetch public documentation, so there is no tenant resource to gate. A read-only key can call them.
See Authentication for the scope vocabulary and the binding matrix, and limits and boundaries for what no key can ever do.

Tools

Reads (8)

The last five require a write scope, not a read scope. They are write preconditions — a full-replacement write needs the current version first — so the write scope covers them. An agents:write key is self-sufficient for the agent read-modify-write loop.

Writes (11)

Docs (2)

An escape hatch for deeper recovery and how-it-works questions. Tool descriptions remain the primary contract — reach for these when a description isn’t enough. get_docs_page is pinned to docs.reinx.ai and refuses any other host with INVALID_PATH.

Creating: the idempotency contract

All three create tools — create_agent, create_project, create_team — require a caller-owned idempotencyKey. create_agent additionally provisions external resources (a wallet, a policy) and returns a one-time API key, so a naive retry there could duplicate the agent or lose the key; the key prevents both. Project and team creates are simpler but take the same key for the same reason.
idempotencyKey is required on every create — create_agent, create_project, and create_team. Each tool’s input schema enforces it, so on the MCP path omitting it fails argument validation before the call is made (not the REST 400 IDEMPOTENCY_KEY_REQUIRED — that is the direct-REST contract). Generate a stable, high-entropy value per logical resource and persist it before you call — you need it to recover.
On any ambiguous failure — timeout, network error, code-less 5xx, 409 REQUEST_IN_PROGRESS, 409 ORG_NOT_READY, or (agents only) 503 CREATE_RETRYABLE — retry with the SAME key and the SAME payload. It dedupes or resumes and returns the committed resource, never a second one. (Project and team creates dedupe the same way but never emit 503 CREATE_RETRYABLE — that is the agent-saga-only contention code.) Retries are not re-charged against your quota within the same UTC day — the attempt marker dedupes them whether or not the create completed. The one exception: resuming an incomplete create after 00:00 UTC consumes a unit from the new day, because the marker is day-scoped. Reusing a key with a different payload returns 409 IDEMPOTENCY_KEY_REUSE — that’s a bug in your code, not a transient condition.

Reconfiguring: the version loop

Every reconfiguring write carries a version token, and the loop is always the same:
  1. Read the current state (get_*) — it includes version.
  2. Modify it.
  3. Write it back with that same version.
If anything else changed it in between you get a 409 — re-read and retry, never blind-write. The code differs by tool, so branch on all three:
The two write shapes differ on omitted fields. This is the easiest thing to get wrong.
  • update_agent_budget_policy is a PARTIAL patch. A field you omit is left unchanged. To clear a spend ceiling you must send it explicitly as null — omitting it silently keeps the old limit in force.
  • set_project_budget / set_team_budget are STRUCTURED full replacements. capCents, the complete child array (teams for a project, agents for a team), and version are all required. You cannot omit a child to leave it alone — a missing one is rejected 422. Clearing a cap is capCents: null, never omission.
  • set_project_approval_rules / set_team_approval_rules replace the whole rules array. Leaving an entry out of the array deletes that rule. There is no per-field merge.
Omission is therefore never a clearing strategy: on the agent patch it means “leave alone”, and on the project/team setters it is either a validation failure or a deletion. Use explicit null on the agent patch and on capCents. On the agent patch, null also means different things per field: on perTransactionLimitCents and dailySpendLimitCents, null = no limit; on hourlyVelocityLimit and dailyVelocityLimit, null = fall back to the platform default, which is not unlimited.

Archiving: why your key usually cannot

Archiving is terminal, so a machine may archive only a zombie of its own making. Every one of these must hold:
  • The agent was created by this key’s lineage (a rotated key still qualifies).
  • Its bundled key’s re-delivery window has closed.
  • The credential never authenticated, and the agent has no activity.
  • The wallet balance is zero.
  • No human has ever minted or revoked a key for it. Any human key management permanently disqualifies the machine path — the agent is no longer a machine orphan, so it is a human’s to archive even if everything else passes.
If any of these fails to hold, archiving returns a terminal 403 MACHINE_ARCHIVE_DENIED — not retryable, ask a human to archive from the dashboard. Two cases are not this terminal 403, though: while the key window is still open or the non-delivery proof hasn’t been stamped, the route returns a recoverable 409 (KEY_STILL_DELIVERABLE / KEY_DELIVERY_UNPROVEN) instead — recover the key or stamp the proof rather than escalating (next section).
The server cannot prove the key was never delivered — only that it can no longer be re-delivered, and was never used. An expired re-delivery window says nothing about whether your original create response reached you; a key you received and simply never used looks identical to the gate. You hold the missing evidence. Before archiving, confirm from your own records that no credential was ever stored for this create. Archiving on the gate’s say-alone can destroy an agent whose key you are actually holding.
Two 409s are recoverable and mean specific things:
  • 409 KEY_STILL_DELIVERABLE — the new agent’s key window (~30 min) is still open. Do not archive. Replay create_agent with the same idempotencyKey to recover the key and keep the agent.
  • 409 KEY_DELIVERY_UNPROVEN — replay create_agent (it returns apiKey: null and keyDelivery: "expired", which attempts to stamp the non-delivery proof), then re-issue archive_agent. The stamp is best-effort — a transient DB failure can drop it and leave the archive returning KEY_DELIVERY_UNPROVEN again, so retry replay + re-archive a few times with backoff (the stamp is idempotent, and each replay re-attempts it) — but a persistent recurrence means the stamp itself is failing (a durable fault), so escalate to a human rather than looping. (Same-key replays within the day are not re-charged against your create quota — the quota dedupes them internally; they only consume request rate-limit capacity — so the cost of a bounded retry is rate limit, not quota.) Only do this after confirming from your own records that the original create response was genuinely lost.
Also retryable: 409 BALANCE_UNVERIFIABLE (retry later), and a 200 carrying a non-empty walletsFailed array (re-issue until it comes back empty).

Limits

  • Management writes: 20/min per key, 40/min per organization — on top of the general per-organization ceiling. Reads use the general buckets only.
  • Creation quota: agents, projects, and teams share one counter, 100/day by default, resetting 00:00 UTC. Exhaustion is 429 CREATE_QUOTA_EXHAUSTED and will not clear by waiting out a rate-limit window. Same-UTC-day retries are not re-charged; resuming an incomplete create after 00:00 UTC charges the new day.

Audit

Management calls that reach a handler are written to the organization’s audit trail as mcp.tool_invoked, attributed to the key (name, prefix, last 6) — never to a human user, and never carrying the key’s secret. The project/team recorded is taken from the key’s binding, not from anything the caller supplies. Denials are audited too, so a scope or binding failure is visible to the humans who own the organization.
The audit write is best-effort: it is fire-and-forget, so a database outage can drop a row while the management call still succeeds. That keeps an outage from breaking your integration, but it means the trail is an operational log rather than a guaranteed compliance record — do not rely on it as your own system of record.