Skip to Content
Connect an AI agent (MCP)

Connect an AI agent (MCP)

Drive Marshal from the AI agent you already use. Connect Claude Code or Codex on your laptop, or a headless agent in CI, and it can do what you do in the web app: start runs, follow them, steer them, answer the questions they ask, manage your spaces, deputies, manifests and connections, and for admins, run the org. It acts as the person who signed in, with that person’s permissions.

The endpoint is on the same host as the web app:

https://<your-marshal-host>/mcp

Each install has its own endpoint. Give your people this address.

An agent connected over MCP sees only what the signed-in person sees in the web app. A connection never raises anyone’s role and never reaches another org.

What you can do with it

  • Hand off a task and keep coding. In Claude Code: “Start the release-notes mission on our docs deputy, and tell me when it asks something.” The agent starts the run (runs_launch), follows it (runs_wait), and shows you the question when the run asks one. You answer in the same chat, and the agent passes your answer on (inbox_answer). The run continues.
  • Find out why a run failed. “Why did my last run fail?” The agent lists your runs (runs_list), reads the failed one (runs_get) and its output (runs_logs), and checks the space it ran in for restarts or out-of-memory stops (spaces_get). You get the cause, not a page of logs.
  • Clear your inbox from one place. “What is waiting for me?” The agent lists the open asks from your runs (inbox_list), and answers the ones you decide on (inbox_answer).
  • Get answers from the docs. “What does Marshal recommend for space compute sizes?” The agent searches the official docs (docs_search), reads the page (docs_read), and answers with the link.

See it end to end: Delegate from your AI client.

Step 1: an admin turns MCP on

MCP access is off in every org until an owner or admin turns it on, in Organization settings > General, card MCP access. Until then, an agent that tries to connect is told to ask an org admin.

SwitchDefaultWhat it does
Allow MCP accessOffWhen off, no agent can connect, and every agent already connected in this org is refused on its next call.
Agents may answer approval gatesOffWhen off, agents answer ordinary questions only. Approval and takeover asks wait for an answer in the web app or Slack.
Agents may approve blocked domains and toolsOffWhen off, an agent that hits a blocked domain or tool can only report it. Approving it for a space stays in the web app.
Require approval for every launchOnWhen on, an agent asks you before it starts a run or a space, and API keys and apps that cannot show a confirmation prompt cannot launch. When off, agents and API keys launch without asking.

The approval switches are separate on purpose. An agent reads text that runs produce, so text inside a run can try to steer it. Keep approval gates and policy approvals for people unless you decide otherwise.

Every run and space uses compute and AI tokens, so a person approves each launch by default. Turn Require approval for every launch off when you want unattended launches, such as an API key in CI. Marshal asks you to confirm the change first. With approval off, an agent can start several runs in a row on its own. Runs it starts still count toward the run cap, and every launch is in the audit log.

The switches are stored as mcp.access_enabled, mcp.answer_approval_gates, mcp.policy_approvals and mcp.launch_without_approval (the inverse of Require approval for every launch) in the org’s settings.

Step 2: connect your agent

Marshal shows the exact commands for your install, with your address filled in:

  • Connect agent, in the top bar on every page. It opens the same commands, with a tab for Claude Code and a tab for Codex, and a link to your connected apps. Once you have connected an agent, it shrinks to an icon.
  • Personal settings > Connected apps, card Connect an agent, with a tab for Claude Code and a tab for Codex. Select the copy button next to a command.
  • Home, when you have no connected app yet. The card there shows the Claude Code command and links to the full card.

Add the server once:

claude mcp add --transport http marshal https://<your-marshal-host>/mcp

The first tool call opens your browser (/mcp inside Claude Code starts the same flow). You sign in to Marshal as usual, then approve the consent page.

What you approve

After you sign in, a consent page asks:

  • which org this connection is for. One org per connection.
  • which permissions to grant. See the five permissions.

The page names the client and the host its identity comes from. A client whose host is not on the install’s verified list is marked Unverified, and only Read starts ticked. Tick the others yourself if you want them.

Manage your work and Org admin are never ticked for you, for any client. You opt in on purpose, because they change things. Org admin is shown only to owners and admins.

Select Approve, and the client is connected. Nothing has to be registered in Marshal first.

An app connected earlier holds Read, Launch and Answer only. To use the manage and admin tools, reconnect the app and approve Manage your work (and Org admin, for admins).

What the agent can do

Every tool needs exactly one of five permissions, so a Read-only connection cannot start, stop, change or delete anything.

The five permissions

PermissionOn the consent pageWhat it covers
ReadReadSee runs, logs, spaces, deputies, manifests, audit events and the inbox, and read the Marshal docs.
LaunchLaunch and stop runsStart runs from deputies and manifests, steer them and stop them.
AnswerAnswer your inboxAnswer the questions runs and agents ask, in your name.
ManageManage your workCreate, change and delete your own spaces, deputies, missions, schedules, memory, manifests and connections.
AdminOrg adminOrg admin actions: packages, members, teams, policies, compute and the admin dashboards.

Manage and Admin are never pre-ticked on the consent page, and Admin is offered only to owners and admins. Your role still decides each call: an agent never does more than the person it acts for.

Every tool

The Lowest role column is the lowest org role the tool is listed for. Member means any member. Admin means owners and admins. A tool that asks you to confirm shows you what will happen first, and declining changes nothing. Deputy tools appear when deputies are enabled for your org.

Runs

Start, follow, steer and continue runs.

Name every run you start. A title such as Fix flaky checkout test shows in the runs list, in the web app and in marshal runs list, so runs from the same mission are easy to tell apart. A launch that waits in a mission’s queue shows its title there too, and the run keeps it when it starts. A title can be up to 120 characters. A launch without a title still starts, and the answer asks you to name the next one.

ToolWhat it doesPermissionLowest roleAsks you to confirm
runs_launchStart a run from a deputy mission (with optional notes for that run only), or from a manifest with a task. Pass a title to name the run.LaunchMemberYes, unless launch approval is off
runs_waitWait for news on a run and return the events after a cursor. summary returns only the state and the agent’s last message.ReadMemberNo
runs_getRead one run: its result once it ended, state, what started it, deputy, mission, manifest, task and timing. brief leaves out the task, manifest and who started it.ReadMemberNo
runs_listList runs with the web app’s filters. scope=org needs owner or admin. Each task shows its first 80 characters; task_chars changes that.ReadMemberNo
runs_stopCancel a run that has not ended.LaunchMemberNo
runs_logsRead what a run printed.ReadMemberNo
runs_usageWhat a run’s agent has cost so far: estimated USD and tokens by provider and model, and per conversation.ReadMemberNo
runs_attentionEverything that needs you now, in one call: your open asks, one line each, and runs that failed or timed out in the last minutes (default 60), or are parked. scope=org needs owner or admin.ReadMemberNo
changes_sinceWhat changed since your last call: runs created, started or ended and asks raised or resolved, oldest first, with a cursor for the next call. scope=org needs owner or admin.ReadMemberNo
runs_messageSend a message to a running run’s agent, queued for the end of its turn or, with interrupt, read now. While the run waits on an ask the message is attached to that ask and the agent reads it with your answer (attached_to_ask).LaunchMemberNo
runs_interruptStop the step a running run’s agent is on and let it read what is queued.LaunchMemberNo
runs_take_wheelTake over a run you own or share a team with, to drive it by hand.LaunchMemberYes
runs_timeoutAdd time to a live run’s timeout, pause the timeout clock, or resume it.LaunchMemberNo
runs_renameGive a run’s whole chain a new name.LaunchMemberNo
runs_continuationWhether a finished run can be continued, and what continuing would do (working tree carried over, depth).ReadMemberNo
runs_chainEvery run of one chain, oldest first: the original and each continuation, with status and a short task. Give any run of the chain.ReadMemberNo
runs_lineageThe run this one continues, and every run that continues it.ReadMemberNo
runs_changesThe files a run changed, per checkout; give path (and repo, group) for one file’s patch.ReadMemberNo
runs_continueStart a new segment of a finished run’s conversation with a follow-up task.LaunchMemberYes, unless launch approval is off
deputies_run_adhocStart a one-off task on a deputy, keeping its context and memory. Pass a title to name the run.LaunchMemberYes, unless launch approval is off
runs_cancel_queuedCancel a launch that is still waiting in a mission’s queue.LaunchMemberYes

Inbox and agent requests

Answer what runs and agents are waiting on you for.

ToolWhat it doesPermissionLowest roleAsks you to confirm
inbox_listList the open asks put to you. brief gives one line per ask.ReadMemberNo
inbox_answerAnswer one ask, in your name.AnswerMemberNo
inbox_allEverything waiting on you: asks, space agent requests, preview reviews.ReadMemberNo
inbox_countHow many items are waiting on you: the number on the web inbox badge.ReadMemberNo
inbox_getOne ask in full: its question, choices, state and whether you may answer it here.ReadMemberNo
inbox_replyAnswer an ask as you; the run continues.AnswerMemberNo
inbox_claimTake the first-responder lock on an ask so nobody else works it.AnswerMemberNo
inbox_dismissClose an ask nobody will answer; the run carries on told nothing.AnswerMemberNo
inbox_wakeBring a parked run back so you can look before you answer its ask.AnswerMemberNo
spaces_requests_listThe questions and documents an agent in your space is waiting on you for.ReadMemberNo
spaces_requests_getOne agent request in full, with the draft comments people have added.ReadMemberNo
spaces_requests_respondSettle an agent request in your space as you: answer an ask, or submit annotations on a document.AnswerMemberNo
spaces_requests_dismissClose an agent request nobody will answer; the agent is told it went unanswered and carries on.AnswerMemberNo
spaces_requests_commentAdd a draft comment on lines of an annotate request, as you.AnswerMemberNo
spaces_reviews_listThe preview reviews open on your space, newest first.ReadMemberNo
spaces_reviews_submitFinish a preview review with the comments gathered; any waiting agent continues with them.AnswerMemberNo
spaces_reviews_cancelEnd a preview review with no verdict so a waiting agent stops waiting.AnswerMemberNo

Spaces

Create, resize and manage your spaces.

ToolWhat it doesPermissionLowest roleAsks you to confirm
spaces_getRead the space a run executed in: restarts, out-of-memory stops, why it stopped.ReadMemberNo
spaces_listList your spaces: id, name, state, when each started and stopped.ReadMemberNo
spaces_archivedList your archived spaces.ReadMemberNo
spaces_createStart a new space from a manifest.ManageMemberYes, unless launch approval is off
spaces_forkStart a new space from a copy of an existing space’s workspace disk.ManageMemberYes, unless launch approval is off
spaces_renameGive one of your spaces a new name.ManageMemberNo
spaces_stopStop a running space.ManageMemberNo
spaces_resumeStart a stopped space again from its kept workspace.ManageMemberNo
spaces_archiveStop and archive a space.ManageMemberYes
spaces_restoreBring an archived space back to stopped, so spaces_resume can start it.ManageMemberNo
spaces_deleteDelete a space and its workspace.ManageMemberYes
spaces_portsList the ports a running space is listening on, and whether each speaks HTTP.ReadMemberNo
spaces_preview_urlGet a preview URL for an HTTP port of a running space.ManageMemberNo
spaces_compute_getRead a space’s compute size, any resize in progress or staged, and how far it can be resized in place.ReadMemberNo
spaces_compute_setResize a running space: move to a compute class, or set cpu_limit and memory_limit in place.ManageMemberYes
spaces_uploadPut a file (up to 10 MB) into a running space’s inbox.ManageMemberNo
spaces_auditRead the audit events of one space, newest first: who did what and when.ReadMemberNo

Space policy approvals

Allow a blocked domain or tool for a space. These need the Agents may approve blocked domains and tools switch.

ToolWhat it doesPermissionLowest roleAsks you to confirm
spaces_policy_approveAllow a domain the space blocked, for this space and for every future space from its manifest.ManageMemberYes, with the switch on
spaces_live_overlay_setAllow a domain the space blocked, for this space’s session only.ManageMemberYes, with the switch on
spaces_tool_policy_setAllow a tool the space blocked by removing the tool-policy rules that block it, for this session only.ManageMemberYes, with the switch on
spaces_live_overlay_getThe policy changes applied to a running space so far: its network rules, tool policy and MCP and database policies.ReadMemberNo

Deputies, missions, schedules and triggers

Build and run deputies.

ToolWhat it doesPermissionLowest roleAsks you to confirm
deputies_listList deputies with their active missions.ReadMemberNo
deputies_getOne deputy: name, description, owner, manifest, state, defaults (timeout, compute, output mode, concurrency).ReadMemberNo
deputies_createCreate a deputy (personal by default; team or org if your role allows).ManageMemberNo
deputies_updateChange a deputy’s name, description, manifest or defaults.ManageMemberNo
deputies_suspendSuspend a deputy: its schedules and triggers stop starting runs until it is resumed.ManageMemberNo
deputies_resumeResume a suspended deputy.ManageMemberNo
deputies_restoreBring an archived deputy back.ManageMemberNo
deputies_archiveArchive a deputy: it stops running and is hidden; deputies_restore brings it back.ManageMemberYes
deputies_insightsA deputy’s insights for a window: runs, success rate, people, waiting, reliability, human-in-the-loop, per mission and version.ReadMemberNo
deputies_queueLaunches of a deputy waiting for their mission’s concurrency limit, in order.ReadMemberNo
missions_listA deputy’s missions: name, stage (draft or active), active version, mode, run count.ReadMemberNo
missions_createCreate a mission with its version 1, as a draft: nothing runs until missions_version_activate.ManageMemberNo
missions_renameGive a mission a new name.ManageMemberNo
missions_deleteDelete a mission; one with runs is archived instead, so its history stays readable.ManageMemberYes
missions_versionsA mission’s versions, newest first: prompt, mode, grants, inputs, timeout.ReadMemberNo
missions_version_addAdd a version; it becomes the mission’s active version at once.ManageMemberYes, when the mission is active
missions_version_dry_runRender the mission’s active version with these inputs, at any stage, without starting a run.ManageMemberNo
missions_version_activateMake a draft mission active: its latest version starts running unattended.ManageMemberYes
schedules_listA deputy’s schedules: mission, cron and zone, notes, paused or not, last and next firing.ReadMemberNo
schedules_createRun a mission on a cron schedule in a time zone.ManageMemberYes
schedules_updatePause or resume a schedule, or change when it fires or its notes.ManageMemberYes, when the notes change
schedules_deleteRemove a schedule; its mission stops firing on it.ManageMemberYes
triggers_listA deputy’s triggers: which integration event starts which mission, its filter and input mapping.ReadMemberNo
triggers_previewTry a trigger filter on recent deliveries of an event: how many match, with samples.ReadMemberNo
triggers_createStart a mission whenever an integration event matches.ManageMemberYes
triggers_updatePause or resume a trigger, or change its event, filter, inputs or endpoint.ManageMemberNo
triggers_deleteRemove a trigger; its events stop starting the mission.ManageMemberYes

Memory

Read and write deputy and personal memory documents.

ToolWhat it doesPermissionLowest roleAsks you to confirm
memory_getRead a deputy’s context or memory document, or your own (omit deputy).ReadMemberNo
memory_revisionsA memory document’s revisions, newest first: content, who wrote it (person or agent, which run), reverts.ReadMemberNo
memory_putReplace a memory document, based on the version you read; an out-of-date version is refused.ManageMemberYes, when writing context
memory_revertRestore an earlier version of a memory document as a new version; history keeps both.ManageMemberYes, when reverting context

Manifests and stacks

Environments for runs and the curated stacks they build on.

ToolWhat it doesPermissionLowest roleAsks you to confirm
manifests_listList manifests (run environments).ReadMemberNo
manifests_getRead one manifest: stack version, owner, auto-stop, overrides and whether it is held.ReadMemberNo
manifests_previewResolve a manifest, optionally with trial overrides, and report policy violations and warnings.ReadMemberNo
manifests_createCreate a manifest (a run environment) on a published stack version.ManageMemberNo
manifests_updateChange a manifest’s name, overrides, auto-stop or compute class.ManageMemberNo
manifests_deleteDelete a manifest.ManageMemberYes
manifests_upgradeMove a manifest to a newer published version of its stack.ManageMemberYes
manifests_cloneCopy a manifest you can see into a new one you own, with its own name.ManageMemberNo
manifests_sendSend an independent copy of a manifest you manage to another member.ManageMemberYes
stacks_listThe stacks (curated environments) you can see, with their latest published version.ReadMemberNo
stacks_getOne stack: its draft, published versions, held upgrades and whether it follows major versions.ReadMemberNo
stacks_createCreate a stack, a curated environment members build manifests on.AdminAdminNo
stacks_update_draftChange a stack’s name, description, modules, policy or compute classes.AdminAdminNo
stacks_publishPublish the stack’s draft as a new version.AdminAdminYes
stacks_unpublishRetire a stack: hide it from the picker and stop launches from manifests on it.AdminAdminYes
stacks_push_to_membersGive every member without one a manifest on the stack’s latest version.AdminAdminYes
stacks_check_upgradesLook for newer versions of the stack’s modules and apply the allowed ones.AdminAdminNo

Connections, credentials and secrets

Manage who can reach what. Values are never returned, and adding or replacing a secret value happens in the web app.

ToolWhat it doesPermissionLowest roleAsks you to confirm
connections_listThe connections you can sign in to or add a credential for, and whether you are connected.ReadMemberNo
credentials_listThe credentials you can see: name, type, owner, status, who reaches them.ReadMemberNo
credentials_impactHow many live sessions use a credential now, so you know what rotating it would affect.ReadMemberNo
http_secrets_listYour HTTP secrets: name, env var, the hosts each is sent to, its credential and owner.ReadMemberNo
vault_connections_listYour vault connections (AWS, GCP, HashiCorp, 1Password): name, provider, owner.ReadMemberNo
shares_listWho an item is shared with (resource_type + resource_id), or what is shared with someone (principal_type + principal_id).ReadMemberNo
shares_recipientsTeams and people (and the org, if you may share org-wide) you can share with, by name or email.ReadMemberNo
integrations_listThe integration catalog you can see, custom MCP servers included; installed=true for this org’s own.ReadMemberNo
connections_oauth_startStart an OAuth sign-in to a connection; you finish it in the browser.ManageMemberNo
connections_device_startGet the link that starts a device-code sign-in (for example AWS SSO) in the web app.ManageMemberNo
credentials_addGet the link where you add a credential value in the web app.ManageMemberNo
credentials_rotateGet the link where you replace a credential value in the web app.ManageMemberNo
http_secrets_addGet the link where you add an HTTP secret in the web app.ManageMemberNo
credentials_removeDelete a credential.ManageMemberYes
credentials_owner_setMove a credential to you, a team or the org.ManageMemberYes
http_secrets_updateRename an HTTP secret, or change the hosts it is sent to or its credential.ManageMemberYes, when hosts or credential change
http_secrets_removeDelete an HTTP secret; running sessions stop getting it.ManageMemberYes
http_secrets_owner_setMove an HTTP secret to you, a team or the org.ManageMemberYes
vault_connections_removeDelete a vault connection and the HTTP secrets it produced.ManageMemberYes
vault_connections_owner_setMove a vault connection, with its secrets, to you, a team or the org.ManageMemberYes
shares_createShare a credential, HTTP secret, vault connection, manifest or stack with people, teams or the org.ManageMemberYes
shares_updateChange one share between read and use.ManageMemberYes
shares_withdrawStop sharing an item with one person, team or the org.ManageMemberYes
integrations_removeDelete an integration catalog entry, such as a custom MCP server, and its connections.ManageMemberYes

Marketplace, network and compute

Org-wide packages, network policies and compute classes.

ToolWhat it doesPermissionLowest roleAsks you to confirm
marketplace_browseSearch the marketplace’s packages, or read one package or one version: compatibility, publisher, declared credential injections.ReadMemberNo
marketplace_installedThe packages installed in the org, each with its Auto-update setting, latest compatible version and whether an upgrade is available; or, with a catalog id, the manifests and stack versions that still reference one.ReadMemberNo
marketplace_installInstall a marketplace package version for the whole org.AdminAdminYes
marketplace_upgradeInstall a newer version of an installed package, as the web’s Upgrade does.AdminAdminYes
marketplace_uninstallRemove an installed package from the org.AdminAdminYes
network_policies_listThe org’s network policies with their rules, or one policy by id.ReadMemberNo
network_policies_createCreate a network policy, or copy one with duplicate_of.AdminAdminYes
network_policies_updateChange a network policy’s name, default action, rules or user additions; omitted fields keep their value.AdminAdminYes
network_policies_deleteDelete a network policy.AdminAdminYes
compute_classes_listThe org’s compute classes, one class by id, or with policy=true the compute policy (allowed classes, default, default storage class, resize overrides).ReadMemberNo
compute_classes_createCreate a compute class (CPU, memory, disk, QoS, GPU).AdminAdminYes
compute_classes_updateChange a compute class; omitted fields keep their value.AdminAdminYes
compute_classes_deleteDelete an org compute class.AdminAdminYes
compute_classes_bulk_storageSet the storage mode and storage class on all of the org’s compute classes, or on a chosen few, in one change. Preview it first with a per-class before and after and the effect on existing spaces; apply it with apply=true. Moving persistent classes to ephemeral also needs confirm_ephemeral=true.AdminAdminApply only
compute_policy_setSet which compute classes people may pick and the default class. The org’s default storage class and resize overrides are kept.AdminAdminYes

People

Members, invitations and teams.

ToolWhat it doesPermissionLowest roleAsks you to confirm
members_listList everyone in the org with their role.ReadMemberNo
members_offboardingThe shared items that need a new owner, and what is deleted or stopped, if a member is removed.ReadAdminNo
members_role_setChange a member’s role to owner, admin or member.AdminAdminYes
members_removeRemove a member from the org.AdminAdminYes
invitations_listThe org’s invitations with role, expiry and whether they were used or cancelled.ReadAdminNo
invitations_createInvite someone as admin or member.AdminAdminYes
invitations_cancelCancel an invitation that was not used yet.AdminAdminYes
teams_listThe org’s teams with member counts and your role on each.ReadMemberNo
teams_createCreate a team.AdminAdminYes
teams_updateRename, re-describe, archive or restore a team.AdminAdminYes
teams_member_addAdd a member to a team as member or lead.AdminAdminYes
teams_member_removeRemove a member from a team; they lose what the team’s shares gave them.AdminAdminYes

Admin dashboards

The admin dashboards, for owners and admins.

ToolWhat it doesPermissionLowest roleAsks you to confirm
admin_overviewThe admin dashboard’s headline numbers: active people, sessions, spend, blocked egress, credentials, deputy runs.AdminAdminNo
admin_usageUsage over time or by breakdown: series, utilization, top egress hosts, egress decisions, MCP and tool usage.AdminAdminNo
admin_costSpend: compute cost by person, LLM token cost, deputy cost by deputy, by day or both (view: deputy), or what pausing saved.AdminAdminNo
admin_securitySecurity: egress posture, credential exfiltration attempts, anomaly days, active alerts.AdminAdminNo
admin_sessionsEvery session in the org with state, owner, activity and LLM cost; or one by id.AdminAdminNo
admin_nodesThe cluster’s nodes: capacity, requests, usage, headroom, pending sessions and recommendations.AdminAdminNo
admin_nodes_refreshTake a fresh reading of the cluster’s nodes now; the platform limits how often one is taken.AdminAdminNo
admin_credentialsCredential statistics, or the inventory of every credential with owner, last use and age (no values).AdminAdminNo
admin_credentials_revokeForce-revoke any member’s or the org’s credential.AdminAdminYes

Security Center

Block a vulnerable package version, see what it affects, move it out of your stacks and manifests, and restart spaces that run an old setup. These are the same actions as the Security Center in the web app, for owners and admins. Anything that changes something asks you to confirm first, showing facts read from the server.

ToolWhat it doesPermissionLowest roleAsks you to confirm
security_blocks_listThe org’s blocked version ranges, or one block with what it affects and its last stop job.AdminAdminNo
security_blocks_createBlock a version range of a package (it does not have to be installed yet), or of the runtimes a toolchain offers; choose whether running spaces keep running or stop now.AdminAdminYes
security_blocks_removeUnblock a version range. The block stays as history.AdminAdminYes
security_blocks_affectedThe stacks, manifests, spaces (running, stopped, or with no package record) and runs that hold a version in a block’s range, with their owners.AdminAdminNo
security_blocks_fixPreview, then apply, moving the block’s stacks and manifests to the newest installed version outside every block. A preview changes nothing; applying asks you to confirm.AdminAdminYes, to apply
security_blocks_stop_affectedStop the running spaces that hold a block’s versions and cancel their runs. Spaces with their own disk keep it.AdminAdminYes
security_overviewCounts: active blocks, affected spaces, spaces with no package record, outdated spaces.AdminAdminNo
security_outdated_spacesSpaces whose snapshot is behind their manifest, and the last restart-all job.AdminAdminNo
security_outdated_notifyEmail each owner a list of their outdated spaces, at most once per 24 hours each.AdminAdminYes
security_outdated_restartStop each running outdated space and start it on its manifest, resolved again as its owner.AdminAdminYes

Audit

Search the audit log.

ToolWhat it doesPermissionLowest roleAsks you to confirm
audit_searchSearch the audit log: your own events, or the whole org for owners and admins.ReadMemberNo

Credential, secret and vault values are never returned. Adding or replacing a value happens in the web app, and the tool hands you the link.

Docs

Let the agent read the official docs instead of guessing. The pages are the ones on docs.marshal.codes, bundled with your install, so the agent reads the docs as of your install’s API release. It works on installs with no outbound internet, and every member and admin sees the same pages.

ToolWhat it doesPermissionLowest roleAsks you to confirm
docs_searchFind the pages and sections that answer a question, such as “upgrade to a new release” or “space compute sizes”. Returns up to 10 pages, each with a snippet and its docs.marshal.codes link.ReadMemberNo
docs_readRead one page as markdown, by the path docs_search returned. A long page comes in parts of up to 32 KiB; pass next_offset as offset until done is true.ReadMemberNo

Ask for them by name when you want a sourced answer: “Search the Marshal docs for how to add a package to a stack, read the best page, and tell me the steps with the link.”

How the tools behave

  • Confirmations come from your client. Claude Code and Codex ask you before the action runs.
  • Short ids work. The run and ask tools take the first 8 or more characters of an id, the way the web app and the CLI show it, as long as only one run or ask that you can see starts with them: your own runs (any run in the org for owners and admins) and the asks you may answer. Give the whole id for anything else.
  • Messages reach a run that is waiting on an ask. A run waiting on an ask cannot read its queue until the ask is settled, so runs_message attaches your message to the ask instead and returns delivered: true with attached_to_ask. The agent gets the message together with the answer, before it acts. The person answering sees it on the ask card in the web app and in inbox_get. An ask holds up to 5 messages of 2 KB each; when it is full, wait for the ask to be settled and send again. A message is attached only to the agent’s own question, and only when the run can show it. In every other case (a tool-permission prompt, a longer message, a run whose agent cannot show the message, an interrupt) the message is queued as before, and delivered is false while the run waits. If the ask is skipped, a running agent reads the message at the end of its turn; a parked run whose ask is skipped does not resume, and the message ends with it. If the ask times out, the run ends and the message ends with it: continue the run with runs_continue and repeat the instruction.
  • runs_continue says what to do instead. When a run kept no conversation to continue from, start a new run with runs_launch and give it what it needs to know in notes.
  • Runs started over MCP read as MCP. A run started with runs_launch or deputies_run_adhoc shows MCP as its trigger on the run page and in the Runs list, so you can tell it apart from a run started in the web app, the CLI or the API.
  • runs_wait holds at most 30 seconds per call and returns at most 200 events. It returns early when the run ends, asks a question, or produces events. The agent calls it again with the cursor it got back.
  • runs_wait keeps each answer small. One call returns about 24,000 characters of events (max_chars, up to 57,344) and the rest on the next call, so nothing is lost. The text of each tool call and tool result is cut to its first 400 characters (text_chars; -1 returns it whole, and runs_logs always does). summary returns no events at all: the run’s state, the agent’s last message, how many tools it called and a count of each kind of event, over everything after the cursor.
  • A run that handed off names its successor. When a run ends because a later segment picked it up (stop reason continued, after an answer or a wake), runs_get and runs_wait return that run’s id as continued_by_run_id. Follow that run to see the work finish.
  • Watch for changes with changes_since. Call it once with no cursor to get a cursor, then pass the cursor from each answer into the next call. Each call returns only what happened since: runs created, started or ended, and asks raised, answered, expired or canceled, oldest first. Add minutes (up to 1,440) on the first call to start with the last few minutes; it is ignored once you pass a cursor. You see your own runs and the asks put to you; scope=org shows the whole org to owners and admins. An event appears about 5 seconds after it happens, so a change that commits a moment late is still returned, in order, and each event comes back once. A change that takes more than 5 seconds to commit can still be missed. When has_more is true, call again straight away. A cursor older than 24 hours starts again from 24 hours ago and says reset. A run that parks gets an ended event, because its turn is over; the state on an event is the run’s state when you call, so a run that has since been ended shows its final state. What happens to a parked run afterwards, and runs waiting on an ask, show in runs_attention.
  • Lists stay short. runs_list shows the first 80 characters of each task, and inbox_list with brief shows one line per ask. Read the whole thing with runs_get or inbox_get.
  • runs_logs reads the stored transcript first. If your install keeps no transcripts, it reads the run events that are still kept (about an hour after the run ends). When there is neither, it returns logs_unavailable, never an empty success.
  • Deputy cost is one call. admin_cost with view: deputy rolls up what your deputies’ runs cost over a date range (since and until, up to 90 days, the last 7 by default). Set group_by to deputy (run hours, compute, LLM cost, total and tokens per deputy, most tokens first), day (LLM cost and tokens per UTC day) or deputy_day (each deputy with a row for each day it used tokens, up to 31 days). It lists the top 20 deputies (10 for deputy_day) and sums the rest in other, so the total covers every deputy. Only the usage of deputy runs counts, not people’s own spaces. Per-day rows, and the total of the day and deputy_day groupings, carry LLM cost and tokens only. Deputies are ordered by tokens, then known spend (compute plus priced LLM cost), so a large spender on an unpriced model is listed first. Run hours are the part of each run inside the range, and a run that is waiting on a person or parked adds its hours when it completes, so a closed day can grow. A model with no price is flagged unpriced on the row, named once in the total, and its cost is left out, never counted as $0. Owners and admins only; it answers once per 10 seconds.
  • Run output is wrapped in an <untrusted-content> block, with known secret shapes redacted, so the agent treats it as data and not as instructions. The note that explains the block comes once per answer, on the first block.

The run cap

One person may have 5 runs started through the MCP active at once, per org. The sixth is refused, with the runs that are in the way:

refused: you already have 5 active runs started through the MCP in this org, and the cap is 5. Active runs: <ids>. Wait for one to end (runs_wait) or stop one (runs_stop), then launch again.

Runs started in the web app, the CLI or by a schedule do not count. The cap guards clients that cannot ask you to confirm a launch, so think about that before you raise it. To change it for the whole install, set MARSHAL_MCP_RUN_CAP on the API (chart value api.extraEnv).

Auditing and revoking

Every launch, stop and answer, and every sign-in, token and revoke, is written to the audit log with the person, the client, the permissions and the outcome, under channel mcp. Search it on the Audit page, or from an agent with audit_search.

To end a connection:

  • A person revokes their own in Personal settings > Connected apps, with Revoke. The client is refused on its next call and must sign in again.
  • An owner or admin sees every connection in the org on the same page and can revoke any of them.
  • Turning off Allow MCP access ends every connection in the org at once.

Access also ends by itself when the person leaves the org or their role changes, by the same rules that end their web sign-in.

Other MCP clients

Any client that speaks MCP over streamable HTTP and OAuth 2.1 with PKCE can connect. Nothing about the endpoint is Claude-specific. One rule decides whether a client works: its redirect URI must be https://, or http:// on a loopback host (127.0.0.1, [::1] or localhost, on any port, which is what desktop clients use). A client that registers a private-use scheme such as myapp://callback is refused.

Installs with no inbound internet

Most self-hosted installs take no traffic from the internet. MCP works there with two settings. Claude Code, Codex, other clients inside your network, and headless agents with an API key all work.

How a laptop reaches the install

The chart supports two ways:

  • A tailnet name. Set tailscaleIngress.enabled=true and tailscaleIngress.hostname, and the install also answers on <hostname>.<your tailnet>.ts.net for anyone on the tailnet. Also set tailscaleIngress.tailnet to your tailnet’s domain. The chart then allows both the short name and the full MagicDNS name on /mcp.
  • An internal DNS name. Any name that resolves to the install’s ingress inside your network. List it in ingress.extraHosts so it gets its own routing rule. If the name reaches the API another way, list it in mcp.extraHosts.

A name that is not in one of those lists gets 403 on /mcp, while the rest of the app works on it. This check is deliberate: it stops a name someone else controls from pointing at your install and driving the MCP with a person’s token.

Each name is its own sign-in

A person signs in per name. Connect on marshal.ts.net and you sign in there. The same laptop connecting on marshal.internal signs in again. The address you use decides the whole exchange (the sign-in page, the consent page and the token), so a token from one name is refused on the other, and the client asks you to sign in again.

So pick one name per audience and put it in your install’s instructions.

No outbound internet: turn off client metadata documents

By default, Marshal identifies a client by fetching the https:// URL the client uses as its ID, a Client ID Metadata Document on the public internet. An install with no outbound internet cannot fetch it: the fetch waits for its timeout and fails, and the person sees an error about the client’s host.

On such an install, set mcp.cimdEnabled=false in the chart (MARSHAL_MCP_CIMD_ENABLED=false on the API). Then:

  • the authorization server stops advertising those documents, so clients register themselves dynamically instead. Claude Code and other standard clients do this.
  • a client that still sends a URL as its ID is refused at once, with a message telling it to register dynamically.
  • every client is Unverified on the consent page (only a document can carry a verified host), so only Read starts ticked and the person ticks the ones they want.

Keep it on (the default) if the install can reach the internet outbound, even when nothing can reach it inbound. Fetching those documents is what lets the consent page tell a real client from one that only uses the name.