Plugins are available on accounts where the feature has been enabled. The Add plugin entry and the Plugins section only appear when the feature is active for your account. Importing a plugin requires project admin — it creates shared executable capabilities, so it carries the same bar as managing shared OAuth connections. Project members can view installed plugins; the feature flag only controls whether the surface appears, never who may import.
Bundle layout
Agent Plugins fixes where each component lives. MCPJam discovers components only from these locations:plugin.json anywhere else in the bundle is treated as an ordinary file, an mcp.json outside the root is ignored with an MCP_CONFIG_IGNORED preview warning, and a SKILL.md deeper than one directory under skills/ is not a skill. Directories the format does not define (hooks/, vendored folders, and so on) are preserved as plain files — they are not components and not errors.
plugin.json
The manifest requires two fields:
$schema— the canonical Agent Plugins schema identifier, for examplehttps://agent-plugins.org/schemas/1.0.0/plugin.schema.json. MCPJam uses it to select its locally supported validation rules; the URL is never fetched during import. A missing or unsupported$schemarejects the bundle.name— the plugin’s stable identity: 1–64 lowercase characters froma-z,0-9,-, and.. Dots are legal (com.example.deployis a valid name), separators may not lead or trail, and the same separator may not repeat (--and..are invalid — mixed pairs likefoo.-barare allowed by the spec).
version is a free-form string — the format imposes no semver rule. The manifest is a closed object: unknown top-level fields are reported in the import preview and ignored — with one exception. A handful of execution-ambiguous names (command, entrypoint, exec, install, install_script, postinstall, preinstall, run, script, scripts) reject the bundle outright rather than being ignored, because silently dropping something that looks like an install or run hook is the wrong failure mode. Remove them from plugin.json; there is no preview to fix them from. The extensions field carries client-specific data under reverse-domain namespaces; MCPJam reads its own presentation metadata (display name, icon, logo) from the com.mcpjam namespace and preserves other namespaces without validating their shape. Two hygiene rules still apply to every namespace: secret-looking values are dropped rather than stored (reported as MANIFEST_SECRET_FIELD_OMITTED), and a namespace nested beyond the depth cap rejects the bundle with VALUE_TOO_DEEP. Round-tripping client-specific metadata is safe as long as it carries no credentials and stays reasonably flat.
mcp.json
MCP servers are declared in one root document requiring its own $schema and an mcpServers object. The Agent Plugins version in mcp.json must match the one in plugin.json.
Every server entry declares an explicit type, which is authoritative — MCPJam never infers the transport from the presence of command or url:
http://localhost:…) are accepted with a warning for local development.
Plugin variables
Two placeholders are defined by the format, both resolved by MCPJam at launch time — never at import time:
Placeholders expand only in
args, env values, and cwd — a placeholder in command invalidates that server entry. Commands are single executable tokens: a ./-prefixed command resolves against the plugin root with containment enforced, so ./bin/server points at the file shipped in the bundle and ./bin/../../outside invalidates the entry. Materialization does not carry archive permission bits, so on macOS and Linux a shipped binary is written without its executable bit and will not spawn — prefer an interpreter command (node, python) with the script passed in args. cwd must start with ./, ${PLUGIN_ROOT}, or ${PLUGIN_DATA}. A bundle’s env may not define PLUGIN_ROOT or PLUGIN_DATA — those variables are client-controlled.
Failure isolation
Problems are contained at the narrowest boundary the format defines:
A skip in the import preview means exactly this: the component was declared but did not conform, so it is absent from the imported revision. Each skip appears in the preview’s warnings as a
COMPONENT_SKIPPED entry naming the component and the reason. A skipped server is a bundle problem to fix and re-import — not a runtime failure.
Credential values are never imported
MCPJam screens every literalenv and headers value in the bundle:
- Non-secret literals are stored —
{"MODE": "production"}or anX-Api-Versionheader imports as-is, so portable plugins run without a setup step. - Secret-looking literals are never stored — anything resembling a token, key, PEM block, or URL-embedded password is dropped with a warning and becomes a required setup item: you supply the value per server after installing.
${VAR}references always become setup items — the bundle names the variable, you provide the value.
Where plugin servers run
stdiocomponents run on the local MCPJam runtime today. At connect time the bundle is materialized into a local content-addressed cache,${PLUGIN_ROOT}/${PLUGIN_DATA}are substituted, and the process spawns on your machine. Hosted VM execution for plugin stdio components is coming; the plugin card shows a Local runtime badge in the meantime.streamable-httpandssecomponents are remote connections and work from any client.
Importing a plugin
Plugin import needs a cloud project — signed-in or guest. Fully local, unsynced mode shows an explanation instead of the import picker.- Open the Connect tab (Servers).
- Click the ⋯ actions menu in the top-right of the server list.
- Click Add plugin.
- In the dialog, choose your source:
- Choose a ZIP — select a
.zipplugin bundle up to 25 MB compressed. - Choose a folder — select the plugin’s root folder; MCPJam zips it locally before uploading.
- Choose a ZIP — select a
- Review any preflight warnings shown before the upload starts.
- Click Continue to upload and inspect the bundle.
- Review the import preview (see Preview below).
- Choose how to install:
- Install only — stores the revision without making it the active one.
- Install and connect — stores the revision and makes it the active one, so new attachments offer it.
Preview
Before you confirm the install, MCPJam shows a preview of what the bundle declares:Content-addressed re-import
If you import a bundle whose bytes are identical to one already stored, MCPJam reuses the existing revision instead of creating a new one. The success screen says Already imported rather than Plugin installed to make this clear.Retrying a failed import
The dialog stays open across close and reopen so an in-progress import is not lost. If an import fails:- Commit failed (the bundle was already inspected and previewed) — click Retry install to recommit the same import without re-uploading.
- Inspection failed (the bundle was uploaded but not yet inspected) — click Resume inspection to re-drive the inspect step.
- Terminal failure — click Start a new import to upload the bundle again.
Plugins section
Once at least one plugin is installed, a Plugins section appears above the server grid on the Connect tab. Each plugin is shown as a group card.Plugin group card
The card shows the plugin’s name and a rolled-up health badge:
Click the card header to expand it and see the active revision’s components:
- Revision ID — the short content-addressed identity of the active bundle.
- MCP servers — each server’s key, transport, placement, and readiness.
- Skills — model references for each declared skill, namespaced as
<plugin-name>/<skill-name>. - Unsupported components — a count of the same inert components the import preview itemizes. Only the count appears here; the per-component keys and reasons are shown at import time.
- Other revisions — ready revisions of the same plugin that are not currently active. Click Activate next to a revision to make it the active one.
Plugin actions
Click the ⋮ menu on a plugin card to:- Disable / Enable — temporarily disable a plugin without uninstalling it.
- Uninstall — soft-uninstall the plugin. Revisions already used by runs and sessions are preserved so existing history stays reproducible. Uninstall is blocked while a live environment still pins one of the plugin’s versions.
Credential setup
After installing a plugin, each MCP server component that requires credentials shows its readiness in the plugin card. The setup section of the install summary lists the environment variable and header names the bundle declared. You configure the actual values per server — MCPJam never reads or stores credential values from the bundle itself.Plugin provenance in runs and sessions
When an eval run or swarm simulation executes against an environment that pins a plugin, MCPJam records the exact bundle hash alongside the run. This record is immutable: re-importing the plugin after a run completes does not change what that run reports.- Eval run detail — a Plugins row below the environment label shows each pinned plugin’s name and short bundle hash. See Plugin provenance on runs.
- Swarm session pane — the transcript pane for a completed simulation shows the same plugin chips so you can tell which bundle produced that session’s transcript.

