Skip to main content
Version: Latest (1.9.x dev)

Govern MCP Apps and Tasks

MCP 2026-07-28 lets a tool do three new things. It can show the user a page (MCP Apps). It can run for hours or days (Tasks). It can ask for a model call while it runs (sampling). Each one is a new way in for hidden instructions, a new way out for data, or a new way to spend money.

DVARA, the AI governance platform, keeps all three off until you turn them on, per workspace. This guide says what each one risks, what DVARA does about it, and the order to turn them on. Each step links to the page with the details.

Enterprise only

Not included in DVARA Open Source.

What is off by default?​

If you change nothing, a client that asks for any of these gets core MCP behaviour instead, and the refusal is recorded.

FeatureDefaultTurned on by
MCP extensions (Tasks, MCP Apps)None allowedThe workspace's extension allow-list
Websites and browser permissions an MCP App page may useNoneThe workspace's MCP Apps lists, on Agents → MCP Extensions
Sampling (a model call a tool asks for)Refused with MCP_SAMPLING_REFUSEDThe workspace's sampling setting
Trimming fields from tool resultsOffThe workspace's mcp.response-projection.mode

Three things are on all the time, whatever you allow:

  • Changed tools wait for approval. A tool whose description, schemas, hints or MCP App page change, or a server that reports a new name or version, is quarantined until someone approves it.
  • Every step is audited. Each page served, each task status change and each sampling model call writes its own audit event, in the signed, hash-chained audit trail.
  • Every call is governed. Polls of a task, and tool calls a page makes, are ordinary governed calls: policy, PII and injection scans, approvals, budgets and rate limits apply.

What does each one risk, and what does DVARA do?​

RiskMCP AppsTasksSampling
Hidden instructionsThe page is HTML and script the server wrote. DVARA scans it for prompt injection and personal data, as any tool resultA finished task's result goes through the same scansThe prompt and the answer go through the LLM Gateway's PII scan and guardrails
Data leavingA page may name only the websites and browser permissions the workspace allowsA task id works only for the API key and workspace that started itThe model is the one the workspace set. The tool cannot choose it, use tools in the call, or read other servers' context
A swap after reviewOnly the approved page is served. A changed page waits for approval
Cost and runaway useTool calls the page makes count against budgets and rate limits1,000 calls per task by default. Task ids expire after 7 days. Cancel from Flightdeck, or kill the agent session. An approval covers one task, for one day at most4,096 tokens per model call, 3 round trips and 8 model calls per tool call by default. Each model call has its own cost record under the caller's key

Before you start​

  1. Set the audit secret on every Gateway replica. Task ids are sealed with a key made from DVARA_AUDIT_HMAC_SECRET. Without it, Tasks is not relayed. Every replica needs the same value. Changing it ends every open task id.
  2. Sync each server's tools. A sync records which extensions the server declares. Look for Declared extensions on the server's page in Flightdeck. A server not synced since 1.9.0 shows nothing, which is not the same as "none". The Gateway grants an extension only when at least one of the workspace's servers declares it.
  3. Review risk hints. On the server's page, Risk hints to review lists tools whose readOnlyHint, destructiveHint or openWorldHint contradicts what the tool does. Check them before a policy relies on a hint.
  4. Check your clients' revision. Tasks and MCP Apps work only on MCP 2026-07-28. See Move MCP clients and servers to 2026-07-28.

Step 1: allow the extension for a workspace​

An extension is in use on a call only when the client declares it on that request, the workspace allows it, and the server declares it.

ExtensionName
Tasksio.modelcontextprotocol/tasks
MCP Appsio.modelcontextprotocol/ui

Set the workspace's list in one of these places:

WhereWho
Agents → MCP Extensions in FlightdeckWorkspace admin
The workspace form's MCP extensions section in FlightdeckPlatform owner
mcp.extensions.allowed in the workspace's GitOps metadataWhoever runs the import
DVARA_MCP_GATEWAY_EXTENSIONS_ALLOWED, the fleet default for workspaces with no list of their ownOperator

Allow one workspace first, not the fleet. A workspace's own list replaces the fleet default, and none allows nothing even when the fleet default allows some.

A policy can still deny an extension the list allows. For example, to keep Tasks out of one workspace's agents:

version: "1"
rules:
- id: no-tasks
expression: request.metadata["mcp.extension_id"] == "io.modelcontextprotocol/tasks"
action: DENY

Each refusal writes MCP_EXTENSION_DENIED, with a reason such as not_allowed, policy_denied or not_offered. See control which MCP extensions a client may use.

Step 2: MCP Apps — approve the pages, then open the lists​

  1. Sync the server's tools again after you allow MCP Apps. The sync reads each tool's page and pins its fingerprint. A workspace whose tools were already approved is asked to approve once for each tool that has a page.

  2. Approve the change. A platform operator uses Release quarantine; a workspace admin uses Approve tool changes.

  3. Allow only the websites and permissions the pages need. Both lists are empty by default, so a page that loads nothing from outside and asks for no permission is served, and any other is refused with MCP_APP_REFUSED (domain_not_allowed or permission_not_allowed). Set them on the MCP Apps card of Agents → MCP Extensions (workspace admin) or in the workspace form's MCP extensions → MCP Apps section (platform owner). Flightdeck refuses a website that is not an origin, a wildcard over a whole top-level domain such as https://*.com, and a permission other than camera, microphone, geolocation and clipboardWrite. In GitOps:

    workspaces:
    - name: analytics
    metadata:
    mcp.extensions.allowed: io.modelcontextprotocol/ui
    mcp.apps.allowed-domains: https://api.weather.example
    mcp.apps.allowed-permissions: clipboardWrite

    The fleet defaults are DVARA_MCP_GATEWAY_APPS_ALLOWED_DOMAINS and DVARA_MCP_GATEWAY_APPS_ALLOWED_PERMISSIONS. The largest page is 1 MiB (DVARA_MCP_GATEWAY_APPS_MAX_RESOURCE_BYTES).

  4. Check each page on the server's page. From 1.9.0 the App pages card on the MCP server's page shows each page's approved version, its websites and permissions against your lists, the rule that decides, and whether it is served. MCP_APP_TEMPLATES_SYNCED in the audit trail keeps the same facts for every sync.

  5. Turn MCP Apps off where you do not want it. Rules on the same card narrow the workspace's decision for one server or one tool: deny github, deny github/delete_repo, or deny * with allow github/create_chart to keep a single App. The most specific rule decides, and a rule never turns MCP Apps on. A tool whose App is off still works as a plain tool. In GitOps the key is mcp.apps.rules. See Turn MCP Apps off for one server or one tool.

A tool meant only for the page is never listed to a client without MCP Apps, so it never reaches a model. Details: Govern MCP Apps.

Step 3: Tasks — set the limits, then watch the list​

A task can run for days, so DVARA governs the whole task, not only each call.

LimitDefaultChange it with
Calls one task may make (polls, answers, cancels)1,000DVARA_MCP_GATEWAY_TASKS_MAX_CALLS
How long a task id stays valid7 daysDVARA_MCP_GATEWAY_TASKS_MAX_AGE (for example P30D)
How long an approval covers its task1 day, or less if the task ends firstDVARA_MCPGATEWAY_AGENTIC_APPROVAL_TASKMAXAGE (for example PT12H)

A task over its call limit is cancelled by the Gateway, and the server is asked to stop. Every call also counts against the usual rate limits and budgets.

To see and stop tasks:

Page in FlightdeckWho seesWho cancels
MCP → TasksPlatform owners and policy admins, every workspaceThe same
Agents → MCP TasksEvery workspace role, its own workspaceWorkspace admin

Killing an agent session in Flightdeck also cancels the tasks that session started. A cancel reaches every Gateway replica within about 5 seconds, and survives restarts. Stopping the work is up to the server: a task whose client never calls again may run on at the server until its own lifetime ends.

Each status change writes MCP_TASK_STATUS_CHANGED, once, however many replicas see it.

If a tool needs approval, the approval a person gives covers the one task that call starts, and nothing else. Polls and answers on the task are not sent for approval again. The approval ends with the task, and cancelling the task withdraws it. To withdraw an approval while its task runs, cancel the task on the MCP Tasks page. Details: Run long tool calls as MCP Tasks.

Step 4: sampling — let a tool ask for a model call, under your rules​

Sampling is not an extension, so the allow-list does not turn it on. It is refused until a workspace chooses otherwise.

  1. Open Agents → MCP Sampling in Flightdeck (workspace admin), or the workspace's settings, section MCP sampling (platform roles).
  2. Choose Make the call through the LLM Gateway.
  3. Enter the Model. It must be a model the workspace may call.

In GitOps the same setting is two keys:

mcp.input_requests.sampling: gateway
mcp.input_requests.sampling.model: gpt-4o-mini

The model call is made with the API key of the application that called the tool, so it gets that key's policies, PII scan, budget and cost record. Each one writes MCP_SAMPLING_CALL; prompt and answer text is never written to the audit trail. A caller signed in with OAuth has no key to make it with, so its sampling is refused.

A task that asks for a model call while it runs gets it the same way, when the application that created it polls it. The model call's own audit record names the server and the task. Details: Govern model calls that MCP tools ask for.

Step 5 (optional): keep only the fields a result needs​

A long task or a rich App can return far more than an agent needs. Response trimming is off by default. Set mcp.response-projection.mode to discover first, read what each tool returns in the audit trail, then list the fields and switch to enforce. It applies to tool call results only, not to results read later through a task. See Keep only the fields an MCP tool result needs.

What to watch in the audit trail​

EventMeans
MCP_EXTENSION_DENIEDA client asked for an extension the workspace does not allow, a policy denied it, or no server offers it
MCP_TOOL_DEFINITION_CHANGED, MCP_SERVER_IDENTITY_CHANGED, MCP_SERVER_PIN_MISMATCHA server changed, and waits for approval
MCP_TOOL_ANNOTATION_CONTRADICTIONA tool's risk hint contradicts what it does
MCP_APP_RESOURCE_SERVED, MCP_APP_REFUSEDA page was served, or refused and why
MCP_TASK_CREATED, MCP_TASK_STATUS_CHANGED, MCP_TASK_CANCELLED, MCP_TASK_ADMIN_CANCELLEDA task started, changed status, or was stopped by the Gateway or by someone in Flightdeck
MCP_APPROVAL_TASK_BOUND, MCP_APPROVAL_TASK_USED, MCP_APPROVAL_TASK_EXPIRED, MCP_APPROVAL_TASK_REVOKEDAn approval was tied to a task, used by a call on it, ended, or withdrawn when the task was cancelled
MCP_SAMPLING_CALLThe Gateway made a model call a tool asked for

What is not covered yet​

  • A server that builds a new page for each request cannot be served: its fingerprint never matches.
  • Sampling from servers on older MCP revisions, and tool use in sampling, are refused.
  • Results read through a task are not trimmed by response projection.

Where to go next​