Effective access
Access is bounded by the real issuer's current permissions, original tenant/module/read-write grant, organization policy, connection policy, record authorization, underlying business rules and usage limits. Narrowing policy cannot enlarge the original grant. Enforcement is checked again at execution, including approved writes.
In Settings → MCP → Security, use Organization policy for tenant-wide controls and Connection permissions for narrower grants. Monitoring exposes accountable users, last activity, expiry, alerts, affected-record references and quota usage.
Policy replacement semantics
Policy PUT endpoints replace writable policy fields: they are not PATCH. Missing writable properties reset to validator defaults. Unknown properties and invalid tool/rule names are rejected. Always GET the latest policy, merge your intended changes locally and PUT the full writable result. An incomplete {enabled:false} also resets other writable policy fields to defaults.
Exception: platform-managed usage ceilings are preserved. Omit organizationLimits, userLimits and connectionLimits from tenant PUT requests. Older clients may echo unchanged values, but attempting to change these fields (including sending stale ceilings) returns 403. This prevents an ordinary security edit from changing or resetting platform allocations.
Platform-managed usage budgets
Adaptive server protection
Platform Admin → MCP Administration → Server protection manages a separate platform-wide admission policy through GET/PUT /api/platform/mcp/protection. Tenant admins cannot read or change this configuration. A shared PostgreSQL token bucket and expiring, heartbeated request leases cap admission across server instances; local rate, IP and concurrency guards run before body parsing and authentication. MCP transport, OAuth and MCP file paths receive this protection. Management controls remain available when admission is paused.
Every two seconds, each instance samples event-loop delay/utilization, memory pressure and database queuing. Busy instances reduce their own throughput, burst and concurrency capacity by 30% per busy sample, with a 10% minimum. Healthy samples recover five percentage points at a time. Severe pressure rejects new admission entirely. Live telemetry is explicitly for the responding instance; shared admission counts and burst tokens are global. These guards do not replace the organization's, user's or connection's persistent usage budgets.
Rate/concurrency refusals return 429 with Retry-After; platform pause or an unavailable shared admission store returns 503. Body reads have an absolute 15-second deadline and requests have a configurable HTTP deadline. An HTTP timeout does not prove an already-running business write was cancelled: check activity/approval status before retrying a mutation. Transport work retains its capacity until its handler settles, including after client disconnect.
Configuration is persisted and audited. The new table is created only through normal schema migrations/Publish, never deployment-time or request-time DDL.
Platform Admin → MCP Administration → Usage budgets lets platform administrators select an organization and manage its organization, per-user and per-connection ceilings for requests/minute, concurrent operations, changes/hour and download bytes/hour. Existing allocations are retained; this ownership change does not reset them. Individual connection policies can impose tighter limits, and runtime enforcement always applies the platform ceilings.
GET /api/platform/tenants/{tenantId}/mcp-usage-limits returns tenantId, tenantName, organizationLimits, userLimits and connectionLimits. PUT at the same endpoint accepts the three limit groups only, validates them, preserves the organization's other security rules, and records before/after values and the actor in MCP activity. Authentication and platform authorization are required; normal tenant admins cannot use either endpoint. Existing platform API-key scope restrictions also apply.
The exact machine-readable validators and defaults are available at /api/mcp-public/security-schema and /api/mcp-public/reference. Use these rather than copying a stale schema from this guide.
Connection policy fields
| Fields | Meaning / default |
|---|---|
modules | Further narrowing; empty means retain the original module grant |
actions | read/create/update/delete; all four default to eligible, bounded by original read/guarded-write access |
allowedTools, deniedTools | Exact tool names; empty allowedTools means no extra allowlist; denial wins |
siteIds, projectIds, recordIds | UUID allowlists; recordIds maps module names to record UUIDs; empty lists impose no extra narrowing |
approvalRules | Exact tool, action or sensitive/ordinary family → required or not_required |
allowDocuments, allowExports | Both default false on a connection; organization must also permit sharing |
maskedFields | Up to 50 case-insensitive JSON keys/dotted paths returned as [masked] |
maxExportRows | 500 by default; maximum 10,000 |
maxResponseBytes | 2,097,152 by default and maximum |
maxBatchChanges | 25 by default; maximum 100 |
limits | Persistent request/concurrency/change/download budgets |
UUID scope lists allow at most 200 entries each. Unsupported scopes fail closed: a child/document/report operation that cannot safely relate its records to the allowlist is denied, not broadened. Exact existing-record scopes do not authorize creating arbitrary new records. Scoped lists omit an unfiltered global total. Use both scope-filtered pagination and warnings accurately.
Field masks recursively match object keys or dotted paths; array positions are not part of those paths. Organization and connection masks are combined. Masks do not redact attachment contents or guarantee that a separately named aggregate cannot reveal a derived fact.
Array results exceeding 100 entries require both export grants. Row/response caps still apply when exports are enabled. Oversized datasets are rejected rather than silently truncated by the security layer. Outcome reports may independently disclose bounded/incomplete scans.
Organization policy
Organization fields include enabled, restrictClients, approvedClientIds, approvalRules, approvalExpiryMinutes, allowDocuments, allowExports, maskedFields, row/response/batch caps, organizationLimits, userLimits and connectionLimits.
Defaults: enabled true, client restriction false, approved clients empty, approval expiry 1,440 minutes (maximum 24 hours), organization document/export eligibility true. This eligibility does not opt connections into sharing.
When enabled, client restriction permits only approved actual OAuth registration IDs. Names and redirect labels are self-declared, not brand verification. Manual bearer connections are blocked under that restriction.
Approval precedence
For a mutation the first matching rule wins:
- Connection exact tool.
- Connection action.
- Connection sensitive/ordinary family.
- Organization exact tool.
- Organization action.
- Organization sensitive/ordinary family.
- Implemented tool's default sensitive classification.
Reads do not require MCP human approval. GET is classified read; DELETE and delete_/remove_ names are delete; PATCH and replace_/update_/assign_/set_/reorder_/send_ names are update; other mutations are create.
Users may explicitly select not_required for chosen changes. This only disables the extra MCP review—not existing business approvals, locks or validation. A required approval binds immutable arguments, expires at the configured interval and is single-use. Organization or connection policy updates reject pending/approved requests so they require fresh review.
Persistent quota defaults
| Scope | Requests/minute | Concurrent client RPCs | Changes/hour | Download bytes/hour |
|---|---|---|---|---|
| Organization | 600 | 20 | 500 | 209,715,200 |
| Issuing user | 240 | 8 | 200 | 104,857,600 |
| Connection | 120 | 4 | 100 | 52,428,800 |
All relevant dimensions must have capacity. Connection limits cannot exceed organization connection ceilings. Requests use fixed one-minute buckets; changes and bytes use fixed one-hour buckets, not rolling windows. Concurrency uses durable expiring leases with renewal. Global app/IP rate limits also remain in force.
Change volume is charged before executing a mutation, so failed attempts can consume budget. Batch volume uses the largest submitted top-level array, not a recursive count of all affected database rows. JSON output accounting conservatively doubles serialized bytes for text/structured representations; managed file downloads are charged separately. These are enforcement budgets, not provider token or billing counts.
Management endpoints
All endpoints below require a signed-in owner/admin browser session in the selected tenant. Obtain/send CSRF according to the app's existing session flow. Do not use an MCP bearer token, invent a tenant ID, or embed a privileged admin session in an AI widget.
| Method and path | Payload / result |
|---|---|
GET /api/mcp-admin/overview | Connections, open/recent approvals, activity, tool definitions, provider readiness |
POST /api/mcp-admin/connections | name, access (read/guarded_write), modules, expiresInDays (1–90), optional connection policy; returns {connection,token} once |
POST /api/mcp-admin/connections/:id/revoke | No replacement credential; returns revoked status |
POST /api/mcp-admin/approvals/:id/review | {decision:"approve"} or {decision:"reject",reason:"..."}; reviews without executing |
GET /api/mcp-admin/security | {policy,connections,alerts,usage,clients,activity} |
PUT /api/mcp-admin/security | Full writable organization policy; platform usage ceilings preserved; returns saved policy |
PUT /api/mcp-admin/connections/:id/policy | Full connection policy; returns saved policy |
POST /api/mcp-admin/security/alerts/:id/acknowledge | Returns acknowledged status; tenant-bound |
Security connections/activity use database-style snake_case fields, whereas the older overview uses ORM-style camelCase fields. Alerts/activity are bounded to the latest 200 entries each; usage to 500 recent buckets; registered-client metadata to 500 entries. No credentials or client secrets are returned. Client registrations are server-wide public registrations, not records proving a client's organization.
Example organization update, after fetching the latest policy:
{
"approvalRules": {"delete":"required","update_task":"not_required"},
"approvalExpiryMinutes": 60
}Merge these fields into the fetched full policy before PUT. Likewise merge {"actions":["read"],"allowedTools":["list_sites","get_site"],"maskedFields":["address"]} into the fetched connection policy for a narrowly readable connection.
Shutdown and alerts
Setting enabled:false permanently revokes all existing connections and rejects pending/approved approvals. Re-enabling does not restore tokens; create/link new connections. Revocation does not recall data already shared with a provider or undo an already committed write.
In-app alerts cover repeated denied actions, suspicious expired/revoked/client access, quota exceedance, large downloads and repeated deletion/replace activity. Thresholds are heuristic signals, not a complete intrusion detection guarantee. Alerts can be acknowledged; acknowledgement does not change permissions.
No email, SMS, Slack or external alert delivery is currently provided by this MCP dashboard.
Download this guide as Markdown.