mcp capability plugins
This page is the capability plane — StandMeet as MCP host (see confusables). The agent's external tools / skills (retrieval, booker, summarize, ask_visitor + owner-registered ext-mcp). Already plugin-shaped — one of the two plugin axes (the other is connector-plugins; the axes touch only at connector-deps).
- Sandboxed: each runs in a bubblewrap namespace,
--unshare-net(network-isolated), reaching the host only through one narrow unix socket per capability (/run/standmeet/<cap>.sock).ask_visitorhas no socket at all — fully offline. (cmd/server/axiscap/register.goregisters them;internal/capabilities/sandbox/is the bwrap runner; the builtin manifests are data atbackend/capabilities/<id>/manifest.yaml, loaded bybackend/capabilities/loader.go.) - Builtin == third-party: builtins are static binaries loaded through the same sandbox_stdio path as third-party plugins; the contract is a manifest + the MCP protocol, not Go imports.
- Manifest
Requires: a capability declares its deps (calendar.book→requires: [calendar],mail.send→[smtp]); the host validates them at boot (axiscap/register.go:97) and gates exposure if a dep isn't connected — the Android-manifest model of prompt-injection-is-buffer-overflow. A second, per-tool layerVisitorToolRequires(tool → action-qualified dep such ascalendar:events.insert, F-B-8) hides only the tool the connection cannot perform, instead of the whole capability.
Class view
classDiagram
class Manifest {
<<mcpplugin manifest>>
ID, Version, Title string
Shape Shape
Requires []string
VisitorTools []string
VisitorToolRequires map[string][]string
OwnerTools []OwnerTool
Config, CodeConfig, RoleConfig []ConfigField
Quota *QuotaDecl
ClaimGate *ClaimGateDecl
PromptFragmentID string
ACL string
Transport Transport
}
class Transport {
Kind string
Command string + Args []string
URL string
Env, Headers map[string]string
InProcessServer *MCPServer
Sandbox *Sandbox
}
class Sandbox {
PluginDir string
HostOps []string - op names, socket path derived by host
AllowNet bool
Workspace bool
}
class PluginSpec {
<<agentcore PluginSpec - the Driver hand-off>>
ID, Command string
Args []string
Env map[string]string
HostOps []string
RawToolNames bool
ACLAlways bool
}
Manifest *-- Transport
Transport *-- Sandbox
Manifest ..> PluginSpec : flattened for the agent loop
Transport.Kind selects the wire (stdio child / http / in-process); Sandbox.HostOps names the host ops (fixed vocabulary in routes/hostdesk) that the capsocket back-channel serves — the socket path is derived by the host from the plugin id, never declared (renamed from HostSockets when hostdesk landed, 2026-08-01, 5cb8d8464); Requires feeds connector-deps; PromptFragmentID feeds the prompt-hash regression.
How a capability gets the session's trusted scope without the LLM forging it → trusted-identity-via-meta.