Koskamo

Odile Gate MCP

An API gateway for AI-built apps that provides per-app keys, rate limits, and an audit log. The MCP server allows agents to create projects, register apps with specific allowed calls, manage rate limits, and view audit logs without storing request or response bodies.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Odile Gate MCP logo, by Odile LabsVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Odile Labs
You need:No OAuth login is needed; administering an existing project requires its admin key.
MCP endpoint (Streamable HTTP)
https://gate.odilelabs.com/mcp
Vendor documentation

What you can do with it

  • Create a new project and register apps with allowed API calls
  • Manage rate limits and view audit logs for API usage
  • Explain refused calls and delegate runs for approval
  • Generate audit proofs and verify offline HMAC authentication

Source and maintenance

Vendor evidenceRegistry 1.7.0

Protocol and capabilities

Server
com.odilelabs/gate 1.8.0
MCP protocol
2025-06-18
Tools
29 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Odile Gate, from Odile Labs (communication infrastructure connecting people, businesses and AI agents), puts a key, an allow-list, a rate limit and an audit log in front of an HTTP API. 1) gate_create_project with the API base URL; save the admin_key in the project .env (gitignored), never in code. 2) gate_create_app once per app, listing only the calls that app makes (from the client code you wrote). 3) Point the app at the gateway URL with Authorization: Bearer <app key>; first test an allowed call and a forbidden method (403 route_not_allowed). 4) gate_audit shows what each app did; gate_explain_refusal explains a refused call. Gate Actions: for an agent that changes customer data, gate_create_run grants one session narrow, expiring permission (scope, limits, approvals); gate_set_app_runs makes runs mandatory. Before handing an integration production access, use gate_check_setup to show the human actual protection settings, configuration gaps and exact remedies. It is read-only configuration analysis, not runtime verification or a security certificate; keep upstream ownership checks and test the real integration. For native OpenShell v0.1.5, gate_openshell_setup returns a one-command local installer, exact hash and recipe schema. Default is an isolated Free read-only demo; obtain owner-authorized upstream/routes/scope before using a custom recipe. Setup preserves TLS/JWT and does not renew revoked permissions. The hosted MCP server never executes local setup.

Tools

29 advertised

gate_openshell_setup — Discover one-command OpenShell setup
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read-only local setup plan for native OpenShell + Gate: one command, exact installer hash, recipe schema, prerequisites, authority boundaries and cleanup. Default creates an isolated Free read-only demo with no model or payment. A trusted local controller may configure an owner-authorized API with explicit routes/scope and private credential files. This tool does not run commands, create resources or accept credentials. Only for OpenShell users; any other agent starts with gate_create_project.

gate_openshell_setup input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
gate_openshell_setup annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_create_project — Create a Gate project
Advertised by the server during the last successful anonymous check.
Open-world

Create a Free project in front of an existing HTTPS API. No signup or payment required. For a credential-free demo use https://sandbox.gate.odilelabs.com with GET /customers/:cid/tickets/:id (customer A holds tickets 1-3, B holds 4-5: try GET /customers/A/tickets/1). Returns project_id, admin_key (shown once) and the gateway base URL apps call instead of the API. A real API and its credentials need owner authorization.

gate_create_project input schema
{
  "type": "object",
  "required": [
    "name",
    "upstream"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "A name for the project, e.g. \"Shop API\""
    },
    "upstream": {
      "type": "string",
      "description": "The API base URL, https only, e.g. https://api.example.com/v1"
    },
    "header_name": {
      "type": "string",
      "description": "Optional: the secret header your API expects, e.g. Authorization or apikey"
    },
    "header_value": {
      "type": "string",
      "description": "Optional: its value. Stored encrypted; apps never see it."
    }
  },
  "additionalProperties": false
}
gate_create_project annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_create_app — Register an app
Advertised by the server during the last successful anonymous check.
Open-world

Give one app its own key and the calls it may make. Routes are rules like "GET /orders/:id", "POST /orders", "GET /users/{user}/orders" (per-user), or example calls like "GET /orders/42", which become rules allowing any id. Returns key (shown once), app.id and normalized rules. Send key as Authorization: Bearer <key> to the project gateway; never send the admin key to the workload.

gate_create_app input schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "routes"
      ]
    },
    {
      "required": [
        "template"
      ]
    }
  ],
  "required": [
    "project_id",
    "admin_key",
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "The app name, e.g. \"storefront\" or \"nightly sync\""
    },
    "models": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "maxItems": 50,
      "minItems": 1,
      "description": "For a model API: the only models this app may ask for, exact names or a prefix ending in * (e.g. [\"gpt-4.1-mini\", \"claude-haiku-*\"]). Omit for no model limit."
    },
    "routes": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "maxItems": 50,
      "minItems": 1,
      "description": "Only the calls this app makes, one \"METHOD /path\" per item"
    },
    "template": {
      "enum": [
        "stripe",
        "github",
        "shopify",
        "hubspot",
        "supabase",
        "slack"
      ],
      "type": "string",
      "description": "Ready-made API policy: reads allowed, risky writes held, destructive calls refused. Explicit routes replace the entire template policy. Free and Pro; configure the project upstream first. See /templates."
    },
    "admin_key": {
      "type": "string",
      "description": "The project admin key (ga_...). Read it from the .env; never print it."
    },
    "max_calls": {
      "type": "integer",
      "maximum": 100000,
      "minimum": 1,
      "description": "Pro: optional lifetime call allowance for this app. Rotation preserves its count."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Pro: optional future ISO time with timezone, at most 30 days from creation. Rotation preserves this expiry."
    },
    "per_minute": {
      "type": "integer",
      "maximum": 6000,
      "minimum": 1,
      "description": "Calls per minute for this app (default 60)"
    },
    "project_id": {
      "type": "string",
      "description": "The project id from gate_create_project, e.g. p1a2b3..."
    }
  },
  "additionalProperties": false
}
gate_create_app annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_update_app — Apply learned app routes and rate limit
Advertised by the server during the last successful anonymous check.
Advertised destructive

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.

gate_update_app input schema
{
  "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
}
gate_update_app annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
gate_set_models — Set an app's allowed models
Advertised by the server during the last successful anonymous check.
Open-world

For a project in front of a model API: limit which models one app may ask for (the request body's "model", or a /models/<name> path). Other models are refused with 403 model_not_allowed before the provider sees them. models: null removes the limit.

gate_set_models input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "app",
    "models"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "The app id (app_...)"
    },
    "models": {
      "type": [
        "array",
        "null"
      ],
      "items": {
        "type": "string"
      },
      "maxItems": 50,
      "description": "Exact names or prefixes ending in *; null for no limit"
    },
    "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
}
gate_set_models annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_list_apps — List apps
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

The project's apps with their allowed calls, limits, state, idle_since (no allowed call in the project's idle_days) and anomaly-guard settings. Use it to find an app id for the app tools, or a retired app to revoke with gate_revoke_app.

gate_list_apps input schema
{
  "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
}
gate_list_apps annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_check_setup — Check an agent integration setup
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read actual Gate protection settings before giving an integration production access. Reports observe-only mode, writes without mandatory runs, missing user-token configuration, wildcard grants and approval separation, with evidence, exact remedies and explicit limits. Sends no upstream requests, changes no settings and uses no gateway quota. Configuration-only: not a security certificate or runtime enforcement test. Use it on a live project; to check an odile.yaml before applying it use gate_validate_config.

gate_check_setup input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "Optional: check one active app id (app_...) instead of all active apps"
    },
    "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
}
gate_check_setup annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_metrics — Read Gate operational metrics
Advertised by the server during the last successful anonymous check.
Advertised read-only

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_audit or one run in gate_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_audit.

gate_metrics input schema
{
  "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
}
gate_metrics annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_audit — Read the audit log
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns recent gateway calls (time, app, matched route, status, reason, duration); use it to investigate individual calls across the project rather than gate_metrics aggregates or a single gate_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_metrics; for a signed export an auditor can check, gate_audit_proof; for one run's history, gate_run_timeline.

gate_audit input schema
{
  "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
}
gate_audit annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_create_run — Grant one agent run
Advertised by the server during the last successful anonymous check.
Open-world

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.

gate_create_run input schema
{
  "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
}
gate_create_run annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_set_app_runs — Require runs for an app
Advertised by the server during the last successful anonymous check.
Open-world

Make an app need a run: "writes" (every write needs x-odile-run), "all" (every call), or "off".

gate_set_app_runs input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "app",
    "mode"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "The app id (app_...)"
    },
    "mode": {
      "enum": [
        "off",
        "writes",
        "all"
      ],
      "type": "string"
    },
    "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
}
gate_set_app_runs annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_set_response — Choose response fields for an app
Advertised by the server during the last successful anonymous check.

Opt-in JSON response redaction: return only explicit JSON Pointer paths, e.g. /id and /items/*/name. * matches one segment; selecting a container allows its whole subtree. Applies to every upstream response for this app, including errors. Maximum 1 MiB and 5 seconds to read; invalid/non-JSON responses are withheld. No bodies are stored. A withheld reply never reverses an upstream write. null disables filtering. Free and Pro.

gate_set_response input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "app",
    "allow"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "The app id (app_...)"
    },
    "allow": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 256
          },
          "maxItems": 32,
          "minItems": 1
        },
        {
          "type": "null"
        }
      ]
    },
    "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
}
gate_set_response annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_add_approver — Add an approver
Advertised by the server during the last successful anonymous check.
Open-world

Create an approver key for the person who approves held actions (shown once), before granting approval actions. Give it to that person, never to an agent. Only an active approver key can approve, reject or reopen actions.

gate_add_approver input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Who approves, e.g. \"Dana (support lead)\""
    },
    "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
}
gate_add_approver annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_invite_member — Invite a team member
Advertised by the server during the last successful anonymous check.

Use the project owner admin key (ga_...) to invite a named viewer, approver or admin. Returns a single-use invite link shown once, expiring after 72 hours; send it to that person. They accept it to receive their member key, also shown once. Gate sends no email.

gate_invite_member input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "name",
    "role"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 60,
      "minLength": 1,
      "description": "The person's name"
    },
    "role": {
      "enum": [
        "viewer",
        "approver",
        "admin"
      ],
      "type": "string"
    },
    "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
}
gate_invite_member annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_list_members — List team members
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use the project owner admin key (ga_...) to review invited, active and revoked members and find a member id to revoke. Invite links and member keys are shown once when issued and never returned by this list.

gate_list_members input schema
{
  "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
}
gate_list_members annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
gate_revoke_member — Revoke a team member
Advertised by the server during the last successful anonymous check.
Advertised destructive

Use the project owner admin key (ga_...) to remove a teammate's access immediately, invalidating their member key or pending invite. Safe to repeat. Invite links and keys are shown once; to restore access, create a new invite.

gate_revoke_member input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "member"
  ],
  "properties": {
    "member": {
      "type": "string",
      "pattern": "^mem_[0-9a-f]{16}$",
      "description": "The member id (mem_...) from gate_list_members"
    },
    "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
}
gate_revoke_member annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
gate_list_actions — List held actions
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

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.

gate_list_actions input schema
{
  "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
}
gate_list_actions annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_explain_refusal — Explain a refused call
Advertised by the server during the last successful anonymous check.
Advertised read-only

What a Gate refusal means and how to fix it, from the x-gate-refused header value (e.g. route_not_allowed).

gate_explain_refusal input schema
{
  "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
}
gate_explain_refusal annotations
{
  "readOnlyHint": true,
  "openWorldHint": false
}
gate_delegate_run — Delegate a narrower run
Advertised by the server during the last successful anonymous check.
Open-world

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.

gate_delegate_run input schema
{
  "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
}
gate_delegate_run annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
gate_learn_suggestions — Read learning suggestions
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

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.

gate_learn_suggestions input schema
{
  "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
}
gate_learn_suggestions annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_audit_proof — Export a signed audit proof
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns chained audit rows, decided-action feature snapshots and signed anchors; use it for a portable tamper-evident export instead of gate_audit's recent-call view, then check it with gate_audit_verify. 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.

gate_audit_proof input schema
{
  "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
}
gate_audit_proof annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_audit_verify — Verify a signed audit export
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns intact or broken_at for a supplied signed export; use it to check a gate_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.

gate_audit_verify input schema
{
  "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
}
gate_audit_verify annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_run_tree — Read run tree
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns one run and its delegated descendants without tokens; use it to inspect delegation and permission state instead of gate_run_timeline events. One run only; the project-wide log is gate_audit.

gate_run_tree input schema
{
  "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
}
gate_run_tree annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_run_timeline — Read run timeline
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns one run's call metadata, approvals and approver names, recovery outcomes and delegated children; use it to reconstruct that session instead of gate_audit's project-wide calls or gate_run_tree's permission state. No bodies or query values. One run only; the project-wide log is gate_audit.

gate_run_timeline input schema
{
  "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
}
gate_run_timeline annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
gate_rotate_app_key — Replace an app key
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Replace one app's key and keep its rules, limits, expiry and call count. The old key stops working at once (no overlap) and the new key is shown once. Use it when a key may have leaked; to remove the app entirely use gate_revoke_app.

gate_rotate_app_key input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "app"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "The app id (app_...) from gate_list_apps"
    },
    "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
}
gate_rotate_app_key annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
gate_revoke_app — Revoke an app
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Revoke one app: its key stops working at once (401) and the app no longer counts toward the plan's app limit. It cannot be undone; to give that agent access again, register a new app with gate_create_app. To replace a leaked key but keep the app, use gate_rotate_app_key.

gate_revoke_app input schema
{
  "type": "object",
  "required": [
    "project_id",
    "admin_key",
    "app"
  ],
  "properties": {
    "app": {
      "type": "string",
      "description": "The app id (app_...) from gate_list_apps"
    },
    "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
}
gate_revoke_app annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
gate_revoke_run — End an agent run
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

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.

gate_revoke_run input schema
{
  "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
}
gate_revoke_run annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
gate_validate_config — Check an odile.yaml
Advertised by the server during the last successful anonymous check.
Advertised read-only

Parse and check a declarative Gate config (apps, routes, rate limits, run mode, plugins including anomaly-guard, alerts, approvers) without changing anything. anomaly-guard settings: mode off|alert|strict, z_threshold 2–10, min_minutes 1–30, half_life 5–1440. Returns errors with their path, warnings, and the normalized config. Use it before gate_sync_declarative; to review a live project's settings use gate_check_setup.

gate_validate_config input schema
{
  "type": "object",
  "required": [
    "config"
  ],
  "properties": {
    "config": {
      "type": "string",
      "description": "The whole odile.yaml (or the same as JSON) as text"
    }
  },
  "additionalProperties": false
}
gate_validate_config annotations
{
  "readOnlyHint": true,
  "openWorldHint": false
}
gate_sync_declarative — Apply an odile.yaml
Advertised by the server during the last successful anonymous check.
Open-world

Make a Gate project match an odile.yaml: creates the project (if no project_id) and missing apps and approvers, applies run mode, loop, learning and anomaly-guard settings and alerts. Example plugin: {name: anomaly-guard, settings: {mode: alert, z_threshold: 4, min_minutes: 3, half_life: 60}}. Never revokes or deletes; differences it cannot apply (an app's routes or rate limit) come back as drift. dry_run lists the steps without changing anything. New keys are shown once.

gate_sync_declarative input schema
{
  "type": "object",
  "required": [
    "config"
  ],
  "properties": {
    "config": {
      "type": "string",
      "description": "The whole odile.yaml (or the same as JSON) as text"
    },
    "dry_run": {
      "type": "boolean",
      "description": "List the steps without changing anything"
    },
    "admin_key": {
      "type": "string",
      "description": "Its admin key (ga_...), required with project_id. Read it from the .env; never print it."
    },
    "project_id": {
      "type": "string",
      "description": "Optional: an existing project to sync"
    }
  },
  "additionalProperties": false
}
gate_sync_declarative annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
345 ms
95th percentile latency
345 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 345 ms · metadata changed · 29 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http odile-gate-mcp https://gate.odilelabs.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add odile-gate-mcp --url https://gate.odilelabs.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable odile-gate-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "odile-gate-mcp": {
      "url": "https://gate.odilelabs.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "odile-gate-mcp": {
      "type": "streamableHttp",
      "url": "https://gate.odilelabs.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start odile-gate-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "odile-gate-mcp": {
      "type": "http",
      "url": "https://gate.odilelabs.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http odile-gate-mcp https://gate.odilelabs.com/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "odile-gate-mcp": {
      "url": "https://gate.odilelabs.com/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "odile-gate-mcp": {
      "serverUrl": "https://gate.odilelabs.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Odile Gate MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Odile Gate MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing