Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Permissions

ScaiMCP defines one module-level permission for its own admin surface; every individual tool inherits the permission its underlying service requires. There is no MCP-specific permission for "may call any tool" — the per-tool checks do the work.

Module permission#

Key What it grants
scaimcp:access Call the admin REST surface (GET /v1/modules/scaimcp/tools and friends). Does not grant any tool calls.

By default this is held by super_admin, partner_admin, and tenant_admin via ScaiGrid's catch-all in CurrentUser.has_module_permission. The MCP transport itself (/mcp) is open to any authenticated identity — what they see is determined entirely by their other permissions.

Per-tool permission#

Each McpToolDef declares a required_permission. The string is checked against the caller's CurrentUser in two ways:

  1. If it resolves to a value of the core Permission enum (models:use, webhooks:manage, admin:access, ...), user.has_permission(...) is called.
  2. Otherwise it is treated as a module-permission key and user.has_module_permission(...) is called.

Tools whose required_permission is an empty string are open to any authenticated caller (e.g., me_get, modules_list).

See the API reference for each tool's permission.

Filter behaviour#

list_tools filters the catalog before returning it. A caller who lacks a tool's permission never sees the tool — they cannot guess the name and call it anyway, because call_tool re-runs the same check and returns PERMISSION_DENIED.

This is the whole reason MCP is safe: the catalog the LLM sees is exactly what it can invoke. The LLM can't hallucinate a privileged tool into existence.

Cloud MCP gating#

Tools aggregated from cloud MCP servers via ScaiLink are gated on scailink:remote.use. A caller without that permission sees only platform-native tools; with it, they additionally see their personal cloud registrations and any tenant-shared ones. Revoke scailink:remote.use from a group's custom role to remove the feature for those users while leaving platform tools intact.

Audit#

Every permission-gated MCP call goes through ScaiGrid's standard audit log under the underlying service's action name (inference.chat, webhooks.create, etc.). Filter by actor_user_id to see what a given identity has been doing through MCP:

bash
1
2
curl "$SCAIGRID_HOST/v1/audit/events?actor_user_id=$USER_ID&limit=50" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY"

There is no separate "MCP" facet — by design, MCP is just another front door into the same audited services.

Granting selectively#

Most tenants run two patterns side by side:

  • A service-account identity (API key) for the desktop / agent client, scoped to exactly what the agent should be allowed to do — usually models:use plus any module permissions for the modules the agent needs.
  • The user's own JWT for interactive use, carrying their full role-based permissions.

Keep the service-account narrow — its key sits in a config file or env var and is the highest-impact thing to leak.

Updated 2026-05-18 15:01:31 View source (.md) rev 12