Plugins are available on accounts where the feature has been enabled. The Add plugin entry only appears 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.
Entrypoint declarations
Tools can declare entrypoints in_meta["openai/ui"].entrypoints to surface as global actions, thread actions, or file handlers. MCPJam reads each declaration independently, so one unrecognized item does not hide the tool’s other entrypoints. An unrecognized declaration produces a PLUGIN_ENTRYPOINT_UNRECOGNIZED warning in Logs naming the affected tools.
The type: "settings" entrypoint is retired. Declare structured settings with the openai/settings server capability instead; a type: "settings" item is ignored and reported in Logs.
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.
Plugin servers on the Servers tab
Once a plugin is installed and has an active version, each MCP server it declares appears as a server card in the Servers tab grid, alongside your project’s own servers. The card shows:- The plugin’s icon and the server’s declared name.
- A from <plugin> badge identifying which plugin added it.
- A status indicator where a project server’s connect switch would sit.
Plugin server status
Plugin server cards are not reorderable — they belong to the plugin’s version, not your project’s server list.
Opening a plugin server’s settings
Click a plugin server card, or click ⋮ → Configure, to open its Settings. The Settings panel contains:- Plugin section — the plugin’s status, active version, and other available versions. Click Activate next to a version to make it the active one. Activating a version changes what chats run from the next message.
- Setup — per-server component readiness and a Configure button to supply credential values.
- Set up <plugin> — appears when the plugin’s version declares an onboarding flow.
- Disable / Enable — temporarily disable the plugin without uninstalling it.
- Uninstall plugin… — soft-uninstall the plugin (project admins only).
Plugins with no active version
A plugin that has been installed but has no active version (“Install only”) shows a single card labelled with the plugin’s name. Click it to open Settings, where you can activate a version or uninstall the plugin.Plugin skills on the Skills tab
Plugin skills appear as a source in the Skills tab list alongside local, library, and connected-server skills. Each row is badged Plugin · <plugin name> and is counted in the tab’s skill total. Click a plugin skill row to open its read-only detail, which shows:- The skill’s
SKILL.mdcontent. - Its model reference.
- Plugin settings — a link to the plugin’s server Settings (or an inline Plugin section for a skills-only plugin with no servers).
- Detach as copy — creates an independent, editable copy of the skill in your project store (project admins only).
Credential setup
After installing a plugin, each MCP server component that requires credentials shows its readiness in the server card’s status indicator and in the Settings panel. The setup section of the install summary lists the environment variable and header names the bundle declared. You configure the actual values in the server’s Settings under Setup — MCPJam never reads or stores credential values from the bundle itself.Plugins in Playground chat
When your project has at least one installed plugin with an active revision, the Playground runs that plugin on every chat turn automatically — you do not need to select an environment or configure anything extra. What you see in the composer Plugin servers appear in the server list inside the Options panel (the + button in the chat input) as on and read-only, labelled with the plugin’s name. They are not part of your manual server selection and cannot be toggled off here — to change whether a plugin runs, disable or uninstall it from the plugin server card on the Servers tab. Skipped plugins If an installed plugin cannot run on a given chat — for example, it needs authorization, its component runs only on a local machine, or it has been disabled — the chat shows one plain notice per session the first time you send a message, explaining which plugins were skipped and why. The same information appears as a Logs entry in the right rail. Compare mode Multi-model and multi-host compare columns each run as plain client turns without plugins. The chat says so once on the first send of each comparison. Desktop app On the desktop app, a turn that must stay on the local route — a model keyed to this machine, a local-only server, a client run on this machine, or this machine’s browser or shell — runs without plugins and shows a brief explanation. Turns that can use the web route carry plugins as normal. Reopening a chat When you reopen a chat that ran with plugins, the Playground recomposes for the current client using whatever plugins are active now. Plugin versions are project state, like a live server configuration, so the reopened chat reflects the project’s current plugin setup rather than pinning the exact versions from the original session.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.

