Watch Odile Gate: runs, held actions, audit log with signed export, metrics and refusal reasons.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Gate Actions: give one agent session narrow, expiring permission. Actions are rules with {placeholders} bound by scope (e.g. "PATCH /customers/{customer}/tickets/:id" with scope {"customer":"A"}), each with an optional max and approval. Add a human approver with gate_add_approver before granting approval:true actions; without an active approver the grant is refused. Returns a run token (shown once) the agent sends as x-odile-run with its app key. Writes in a run need an Idempotency-Key. Give a write a check ("GET /bookings?idempotency_key={key}") and the agent can settle a lost answer with POST /g/<id>/_gate/recover.
The app id (app_...) this run is for
Rules, or {rule, max, approval, check}
The project admin key (ga_...). Read it from the .env; never print it.
The project id from gate_create_project, e.g. p1a2b3...
Optional: what the run is for, e.g. "triage ticket 4411"
Values for the {placeholders}, e.g. {"customer":"A"}
Optional: calls allowed in the whole run
How long the run lasts (default 3600)
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http gate-oversight https://gate.odilelabs.com/mcp/oversight
Gate Actions: give one agent session narrow, expiring permission. Actions are rules with {placeholders} bound by scope (e.g. "PATCH /customers/{customer}/tickets/:id" with scope {"customer":"A"}), each with an optional max and approval. Add a human approver with gate_add_approver before granting approval:true actions; without an active approver the grant is refused. Returns a run token (shown once) the agent sends as x-odile-run with its app key. Writes in a run need an Idempotency-Key. Give a write a check ("GET /bookings?idempotency_key={key}") and the agent can settle a lost answer with POST /g/<id>/_gate/recover.
| Argument | Type | Description |
|---|---|---|
| app* | string | The app id (app_...) this run is for |
| label | string | Optional: what the run is for, e.g. "triage ticket 4411" |
| scope | object | Values for the {placeholders}, e.g. {"customer":"A"} |
| actions* | array | Rules, or {rule, max, approval, check} |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| max_calls | integer | Optional: calls allowed in the whole run |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
| ttl_seconds | integer | How long the run lasts (default 3600) |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"app",
"actions"
],
"properties": {
"app": {
"type": "string",
"description": "The app id (app_...) this run is for"
},
"label": {
"type": "string",
"description": "Optional: what the run is for, e.g. \"triage ticket 4411\""
},
"scope": {
"type": "object",
"description": "Values for the {placeholders}, e.g. {\"customer\":\"A\"}",
"additionalProperties": {
"type": "string"
}
},
"actions": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"required": [
"rule"
],
"properties": {
"max": {
"type": "integer",
"minimum": 1
},
"rule": {
"type": "string"
},
"check": {
"type": "string",
"description": "For a write: the GET that finds it by key, e.g. \"GET /customers/{customer}/bookings?idempotency_key={key}\"; it must also be a GET action of the run"
},
"approval": {
"type": "boolean"
},
"idempotent": {
"type": "boolean",
"description": "With check: the API dedupes on Idempotency-Key, so a not-found write may be retried"
}
}
}
]
},
"maxItems": 50,
"minItems": 1,
"description": "Rules, or {rule, max, approval, check}"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"max_calls": {
"type": "integer",
"minimum": 1,
"description": "Optional: calls allowed in the whole run"
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
},
"ttl_seconds": {
"type": "integer",
"maximum": 86400,
"minimum": 60,
"description": "How long the run lasts (default 3600)"
}
},
"additionalProperties": false
}Hand a narrower run to another active app in the same project. Uses the parent app key and run token, never the admin key. Scope, expiry, approvals and ancestor budgets stay enforced; maximum depth five.
| Argument | Type | Description |
|---|---|---|
| app* | string | The destination app id |
| label | string | A short label for the delegated job |
| actions* | array | |
| app_key* | string | The parent app key (gk_...) |
| max_calls | integer | |
| run_token* | string | The parent run token (gr_...) |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
| ttl_seconds | integer |
{
"type": "object",
"required": [
"project_id",
"app_key",
"run_token",
"app",
"actions"
],
"properties": {
"app": {
"type": "string",
"description": "The destination app id"
},
"label": {
"type": "string",
"description": "A short label for the delegated job"
},
"actions": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"required": [
"rule"
],
"properties": {
"max": {
"type": "integer",
"minimum": 1
},
"rule": {
"type": "string"
},
"approval": {
"type": "boolean"
}
}
}
]
},
"maxItems": 50,
"minItems": 1
},
"app_key": {
"type": "string",
"description": "The parent app key (gk_...)"
},
"max_calls": {
"type": "integer",
"maximum": 100000,
"minimum": 1
},
"run_token": {
"type": "string",
"description": "The parent run token (gr_...)"
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
},
"ttl_seconds": {
"type": "integer",
"maximum": 86400,
"minimum": 60
}
},
"additionalProperties": false
}What a Gate refusal means and how to fix it, from the x-gate-refused header value (e.g. route_not_allowed).
| Argument | Type | Description |
|---|---|---|
| reason* | string | The x-gate-refused value |
| recoverable | boolean | Whether the write was granted with a recovery check |
{
"type": "object",
"required": [
"reason"
],
"properties": {
"reason": {
"type": "string",
"description": "The x-gate-refused value"
},
"recoverable": {
"type": "boolean",
"description": "Whether the write was granted with a recovery check"
}
},
"additionalProperties": false
}Returns chained audit rows, decided-action feature snapshots and signed anchors; use it for a portable tamper-evident export instead of gate_read_audit's recent-call view, then check it with gate_verify_audit_proof. No sealed paths/bodies, notes, keys or IPs in the action labels. Legacy actions lack snapshots and are excluded. store_audit=false has no chain. Follow next_from for audit rows and next_actions_after as actions_after for labels (10,000 each). Use API/SDK to verify exports above the MCP request size limit. The signature is HMAC-SHA256.
| Argument | Type | Description |
|---|---|---|
| to | integer | |
| from | integer | |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
| actions_after | string | Action cursor from next_actions_after |
{
"type": "object",
"required": [
"project_id",
"admin_key"
],
"properties": {
"to": {
"type": "integer",
"minimum": 1
},
"from": {
"type": "integer",
"minimum": 1
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
},
"actions_after": {
"type": "string",
"description": "Action cursor from next_actions_after"
}
},
"additionalProperties": false
}Returns project-wide 24-hour call aggregates, anomaly scores, idle apps and current-month usage; use it for operational trends rather than individual calls in gate_read_audit or one run in gate_get_run_timeline. Includes stored call counts by HTTP status and reason, measured duration through response headers (including upstream wait), per-app anomaly scores and 24-hour anomaly counts, idle apps (active apps whose key made no allowed call in the project's idle_days, default 14; a flag only, never a revoke), and separate current-month gateway usage: plan, used, allowed, plus upgrade URL and checkout path on Free at 80% or above. Only POST the checkout path when the admin asks to upgrade; reading metrics never starts checkout. Requires the project owner key or an active member key. Audit may be partial: invalid-key sampling and audit-off periods are disclosed. No upstream requests, quota use or policy changes; not a health certificate or performance guarantee. For individual calls use gate_read_audit.
| Argument | Type | Description |
|---|---|---|
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key"
],
"properties": {
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Returns one run's call metadata, approvals and approver names, recovery outcomes and delegated children; use it to reconstruct that session instead of gate_read_audit's project-wide calls or gate_get_run_tree's permission state. No bodies or query values. One run only; the project-wide log is gate_read_audit.
| Argument | Type | Description |
|---|---|---|
| before | integer | Older audit events (timeline pages have at most 500 events) |
| run_id* | string | The run id |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"run_id"
],
"properties": {
"before": {
"type": "integer",
"minimum": 1,
"description": "Older audit events (timeline pages have at most 500 events)"
},
"run_id": {
"type": "string",
"description": "The run id"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Returns one run and its delegated descendants without tokens; use it to inspect delegation and permission state instead of gate_get_run_timeline events. One run only; the project-wide log is gate_read_audit.
| Argument | Type | Description |
|---|---|---|
| run_id* | string | The run id |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"run_id"
],
"properties": {
"run_id": {
"type": "string",
"description": "The run id"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Read normalized routes and a suggested per-minute limit from an admin-enabled, time-boxed learning session. Records only method, normalized path templates and counts per minute; no query values, raw ids, headers or bodies. Never enables learning or applies rules.
| Argument | Type | Description |
|---|---|---|
| app* | string | The app id |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"app"
],
"properties": {
"app": {
"type": "string",
"description": "The app id"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Actions waiting for approval (or in another state), with the exact call. With an installed approval-risk model, pending actions sort by risk descending and include risk (0–1) and risk_features (top two advisory signals). No model means no score and newest first. Only a person decides in the dashboard.
| Argument | Type | Description |
|---|---|---|
| state | string | Default: pending |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key"
],
"properties": {
"state": {
"enum": [
"pending",
"approved",
"rejected",
"executed",
"unknown",
"expired"
],
"type": "string",
"description": "Default: pending"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Returns recent gateway calls (time, app, matched route, status, reason, duration); use it to investigate individual calls across the project rather than gate_get_metrics aggregates or a single gate_get_run_timeline. Newest first, with totals by status and refusal reason for the returned calls. This view never returns bodies, query values or headers. For 24-hour totals and anomaly scores use gate_get_metrics; for a signed export an auditor can check, gate_export_audit_proof; for one run's history, gate_get_run_timeline.
| Argument | Type | Description |
|---|---|---|
| app | string | Optional: only this app id (app_...) |
| limit | integer | How many calls (default 20) |
| status | string | Optional: only this HTTP status, e.g. "403" |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key"
],
"properties": {
"app": {
"type": "string",
"description": "Optional: only this app id (app_...)"
},
"limit": {
"type": "integer",
"maximum": 100,
"minimum": 1,
"description": "How many calls (default 20)"
},
"status": {
"type": "string",
"description": "Optional: only this HTTP status, e.g. \"403\""
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}End one run granted with gate_create_run: its token stops working at once (403 run_revoked) while the app itself keeps working. Use it to stop an agent mid-job; grant a new run with gate_create_run if the work should continue.
| Argument | Type | Description |
|---|---|---|
| run_id* | string | The run id: run.run_id in gate_create_run's result |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"run_id"
],
"properties": {
"run_id": {
"type": "string",
"description": "The run id: run.run_id in gate_create_run's result"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Apply stored learning suggestions to an existing app and return the applied routes, suggested per-minute limit and learning-session metadata. Review gate_learn_suggestions first, then explicitly confirm; requires the project owner key or an admin member key. mode="extend" adds learned routes (default); "replace" removes existing routes before applying them. Both modes set the learned rate limit and keep the app key. Only learned suggestions can be applied: arbitrary routes or rate limits are not accepted, and this tool never starts learning.
| Argument | Type | Description |
|---|---|---|
| app* | string | The app id (app_...) with stored learning suggestions |
| mode | string | Extend existing routes (default), or replace them with learned routes; both set the suggested rate limit |
| confirm* | boolean | Explicit confirmation to apply the reviewed learning suggestions |
| admin_key* | string | The project owner key (ga_...) or an accepted admin member key (gm_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"app",
"confirm"
],
"properties": {
"app": {
"type": "string",
"description": "The app id (app_...) with stored learning suggestions"
},
"mode": {
"enum": [
"extend",
"replace"
],
"type": "string",
"description": "Extend existing routes (default), or replace them with learned routes; both set the suggested rate limit"
},
"confirm": {
"enum": [
true
],
"type": "boolean",
"description": "Explicit confirmation to apply the reviewed learning suggestions"
},
"admin_key": {
"type": "string",
"description": "The project owner key (ga_...) or an accepted admin member key (gm_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}Returns intact or broken_at for a supplied signed export; use it to check a gate_export_audit_proof export rather than retrieve audit rows. Recomputes the chain and project signature; broken_at is a one-based row position. Does not approve actions or change permissions.
| Argument | Type | Description |
|---|---|---|
| proof* | object | The full signed export from gate_audit_proof |
| admin_key* | string | The project admin key (ga_...). Read it from the .env; never print it. |
| project_id* | string | The project id from gate_create_project, e.g. p1a2b3... |
{
"type": "object",
"required": [
"project_id",
"admin_key",
"proof"
],
"properties": {
"proof": {
"type": "object",
"description": "The full signed export from gate_audit_proof"
},
"admin_key": {
"type": "string",
"description": "The project admin key (ga_...). Read it from the .env; never print it."
},
"project_id": {
"type": "string",
"description": "The project id from gate_create_project, e.g. p1a2b3..."
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 14, 2026.