Extensions
Agent Skills & MCP
Latch v0.3.4 supports the Agent Skills specification and MCP tool servers over sandboxed stdio and Streamable HTTP. Neither integration can change kernel state, grant permissions, certify evidence, or bypass the sandbox. The existing Latch extension protocol and SDKs are unchanged.
Agent Skills¶
Discovery checks these directories, in this order:
<workspace>/.latch/skills<workspace>/.agents/skills<workspace>/.claude/skills- The same three paths under the user's home directory.
Each immediate child directory must contain SKILL.md. The first valid skill of
a given name wins. Directory names must match the frontmatter name. Discovery
is deterministic and limited to 512 skills; invalid skills produce diagnostics
without preventing other skills from loading. Use latch skills or /skills to
inspect the catalog. Restart the session to discover new skills.
.latch/skills/review/
SKILL.md
references/checklist.md
scripts/check.py
assets/template.txt
---
name: review
description: Review Rust changes against the repository's conventions.
compatibility: Requires cargo and ripgrep.
metadata:
author: example
---
Read references/checklist.md before reviewing changes.
Use ordinary command tools to run scripts/check.py when appropriate.
YAML frontmatter supports name, description, license, compatibility,
metadata, and experimental allowed-tools. The latter is informational and
never pre-approves tools. Only metadata goes into the session prompt. The
model calls load_skill with {"name":"review"} to load instructions, then
{"name":"review","path":"references/checklist.md"} for resources. Text reads
are limited to 1 MiB and must stay within the skill's real root; traversal,
escaping symlinks, hardlink aliases, and non-UTF-8 resources are rejected.
Scripts are not executed by the loader. Workspace scripts run through the normal sandboxed tools and approval rules. User-level scripts remain subject to home masking; the model can read their text and explicitly create a workspace copy before proposing execution. Binary assets use existing image/file tooling where its permissions allow access, rather than being injected into context. Skills are instructions, not trusted kernel policy.
The catalog is session context, never the stable provider system field. Loaded
instructions and resources are ordinary durable tool results: history, replay,
rotation, recall, and context budgets treat them like any other tool output.
Large results use the existing 24 KB preview and immutable artifact spill; full
content remains accessible with read_artifact. Resume does not re-read a
resource to reconstruct an old result. Root and child
agents discover skills independently in their shared workspace.
MCP configuration¶
Add operator-owned entries to the normal Latch configuration file. Project files and skills cannot silently configure or launch servers.
[[mcp_servers]]
name = "local-tools"
transport = "stdio"
command = "python3" # use "python" on Windows if that is the installed alias
args = ["/absolute/path/to/server.py"]
enabled = true
timeout_seconds = 120
[[mcp_servers]]
name = "remote-tools"
transport = "streamable_http"
url = "https://example.com/mcp"
bearer_token_env = "EXAMPLE_MCP_TOKEN"
enabled = false
name is a unique 1–32 character ASCII identifier (letters, digits, hyphens).
Deadlines are 1–3600 seconds. HTTP requires HTTPS except for literal loopback
and localhost. URLs containing user information or fragments are rejected.
Redirects and ambient proxy discovery are disabled. Bearer credentials are
resolved from the explicitly named environment variable, not written to config
or passed to unrelated servers. Stdio inherits the execution backend's minimal
sandbox environment; host credentials are not implicitly forwarded.
latch mcp lists configuration without contacting a server. latch mcp --check
connects enabled servers, discovers tools, reports the negotiated version, and
closes connections without making model or tool calls. Ctrl+C cancels startup.
The TUI's /mcp shows live status; /mcp stop disconnects the current session's
servers. Edit enabled in config and start a new session to enable/disable a
server. Schema registrations remain fixed for the session even after disconnect.
Every enabled server must initialize successfully before a session starts. Child agents open independent clients using the root's operator configuration; their calls, approvals, results and evidence belong to the child session. On Windows, stdio uses a fresh initialized connection per call (see below). Closing workers and sessions tears down their clients. No process or permission grant is shared between sessions.
Protocol and lifecycle¶
The client probes server/discover for modern MCP 2026-07-28, sends the
required per-request protocol/client metadata, and supports HTTP method/name
headers and validated x-mcp-header parameter mirroring. A recognized modern
error never triggers a legacy initialization fallback. For legacy peers it
negotiates initialize / notifications/initialized, accepting 2025-11-25,
2025-06-18, 2025-03-26, and 2024-11-05. Legacy Streamable HTTP sessions
carry Mcp-Session-Id and are terminated with DELETE. The deprecated separate
HTTP+SSE endpoint transport is not supported; configure a Streamable HTTP
endpoint instead. Protocol compatibility does not imply every optional MCP
feature is implemented.
Stdio uses newline-delimited JSON-RPC, independently of the Latch extension protocol's Content-Length frames. HTTP accepts both JSON and request-scoped SSE, including split frames, CRLF and keep-alives. Tool discovery supports pagination and rejects repeated cursors and duplicate tools. Each server is limited to 512 tools and each request/response to 4 MiB. Provider-facing names use the server id and a stable SHA-256 name suffix to avoid collisions and unsupported characters.
Startup, probes, calls, cancellation and cleanup have deadlines. Cancellation sends a bounded stdio cancellation notification or closes the HTTP response stream; legacy HTTP also receives a cancellation notification. A failed exchange disconnects the client. There are no automatic tool retries: a timeout or lost response does not prove that an external action failed to happen. Start a new session to reconnect. Stdio closes stdin, waits briefly, then kills and reaps a server that does not exit. Process lifetime remains owned by the platform execution backend (Bubblewrap on Linux; native AppContainer/Job Object on Windows).
Windows retains the native boundary's one-active-recovery-transaction-per-user rule. Stdio discovery closes its sandbox before returning; each tool call opens an independent initialized server, verifies the protocol and entire tool catalog against the fixed session snapshot, executes exactly once, and closes it. A catalog change fails closed. This releases the recovery lock between calls so command tools and child agents can operate. Stdio server memory does not persist between Windows calls; servers requiring in-memory session state must use Streamable HTTP. Linux stdio connections persist for the session. No global recovery lock, journal rule, or AppContainer protection is weakened.
Only tool discovery/execution is exposed. Sampling, elicitation, client roots,
subscriptions, MCP resources/prompts, OAuth flows, and asynchronous tasks are not
advertised. Unsupported server interactions fail explicitly. Tools may return
validated result envelopes, structured/text content and isError; media remains serialized external data
rather than becoming an unvalidated image handle.
Permissions and evidence¶
Stdio servers run with the existing extension sandbox: read-only workspace, network access, masked home and protected state. There is no unsandboxed fallback. HTTP servers execute remotely; Latch cannot sandbox a remote service. Their invocations still pass kernel permissions and cancellation.
All MCP tools require WORK mode. Strict and Standard safety require a real
approval resolved through the configured permission resolver; Autonomous permits
execution. AI review falls back to human approval for MCP even when arguments
contain a command field; command-only review cannot certify an external tool.
Server readOnlyHint, destructiveHint, other annotations, skill
instructions and tool descriptions never authorize execution. Extension guards
can further restrict MCP calls. Before an MCP call, the kernel durably records
WorkspaceMutationPossible and makes old validation evidence stale, including
for failed/cancelled calls. External output cannot create Passed evidence or
complete the root task. Child reports remain child evidence.
The stable provider system prompt and provider adapters are unchanged. Catalog schemas are fixed for one session; tool results use the normal append-only durable history and Context Engine. Changes to operator configuration take effect on new sessions/resume startup, as with existing extension configuration.
Validation¶
cargo test -p latch-kernel --lib skills --locked
cargo test -p latch-kernel --lib mcp --locked
bash scripts/release-gate.sh
MCP tests use a credential-free loopback HTTP/SSE fixture and a real sandboxed
Python stdio server in both modern and legacy modes. They cover cancellation,
invalid configuration, header injection/collision, unsupported interactions,
conservative mode enforcement, evidence invalidation and stable schemas after
shutdown. Skill tests cover YAML validation, discovery precedence, progressive
disclosure, resource containment and durable tool results. Native Windows runs
must be serial (-- --test-threads=1) and require Python for the stdio fixture;
Linux fixture execution requires working Bubblewrap. Never skip failed sandbox
coverage or report Linux results as Windows qualification.
Specification references: MCP versioning, stdio, Streamable HTTP.