Skip to content

Plugins ​

A plugin adds MCP tools to the Kadmo runtime without changing the runtime itself. Each plugin is a folder under ~/.kadmo/plugins/ with a plugin.json manifest at its root. The runtime reads that folder when it loads, and the plugin's tools appear in MCP tools/list next to the core tools, for every client of that runtime: a local client using kadmo mcp over stdio, or a remote one using HTTP /mcp (see MCP).

Kadmo agents get their plugins from Kadmo when the agent is set up. Nothing needs to be installed by hand on them. On your own computer, you install plugins from a local folder with kadmo plugin install.

To write one, see Creating a plugin.

Plugins and skill packs ​

PluginsSkill packs
What they addNew MCP tools, backed by a program you writeDomain knowledge and workflows
Formatplugin.json plus a handler program in any languageMarkdown and YAML
Installed to~/.kadmo/plugins/<name>/~/.kadmo/skills/
Managed withkadmo plugin list / install / removekadmo install / uninstall / registry
Good forAbilities the agent does not have, such as a local command or an API callTeaching an agent how a specific web app works

The two work together. A skill pack tells an agent what to do on a site; a plugin gives it a tool it could not use before. See Skill packs.

Claude Code plugins, which the Kadmo app can install on an agent, are a different system. They are not read from ~/.kadmo/plugins/ and are not covered here.

Two runtimes ​

The manifest's runtime field decides how the runtime hosts the plugin.

process (default)service
How it runsA new handler process for every tool callOne long-running child process, kept alive by the runtime
ProtocolArguments as JSON on stdin, result as JSON on stdoutThe child is an MCP server over stdio
State between callsNoneKept in the child's memory until it exits
Where tools come fromThe tools array in plugin.jsonThe child's own tools/list, read when it starts
Public tool nameExactly the declared name<namespace>_<tool>; namespace defaults to the plugin name
Timeout30 seconds, fixed120 seconds by default; set per service and per tool
Calls in parallelEach call is its own processCalls to one service run one at a time

exec is accepted as another spelling of process. Any other value makes the runtime skip the plugin.

What happens on a tool call ​

Stepprocess pluginservice plugin
1The client calls a tool, for example echo_inputThe client calls a namespaced tool, for example counter_increment
2Core tools are checked first, then process plugin tools in folder orderNothing else matched, so the call goes to the service that lists this name
3The handler command is started in the plugin folderThe call is queued behind any call already running on that service
4The call's arguments object is written to stdin as JSONThe call is forwarded to the child with the original (un-namespaced) tool name
5The runtime waits for the handler to exit, then parses stdoutThe child's MCP result is returned as it is

If no core tool, plugin tool or service tool matches, the call fails with Tool not found: <name>.

How plugin tools look in tools/list ​

Every plugin tool's description gets a [plugin: <name>] prefix, so a model can tell where it came from. The input schema is passed through unchanged.

json
{
  "name": "echo_input",
  "description": "[plugin: echo-tools] Return the JSON arguments the handler received",
  "inputSchema": {
    "type": "object",
    "properties": { "text": { "type": "string" } },
    "required": ["text"]
  }
}

Order in the list: the core tools first, then process plugin tools, then service plugin tools. A service tool whose namespaced name is already taken is left out with a warning in the log; the rest of that service's tools stay. Your MCP client may add its own prefix (the server name you gave it) when it shows tools to the model.

Managing plugins ​

CommandWhat it does
kadmo plugin listLists the plugins in ~/.kadmo/plugins/ that pass validation, with their tools
kadmo plugin install <source>Checks <source>/plugin.json, then copies the folder to ~/.kadmo/plugins/<name>/
kadmo plugin remove <name>Deletes ~/.kadmo/plugins/<name>/

Full syntax is in the CLI reference.

bash
kadmo plugin install ./echo-tools
kadmo plugin list
text
  Kadmo

  ✓ Installed plugin: echo-tools
  Tools: echo_input, fail_always


  Installed Plugins

  echo-tools v0.1.0
    Echo input back for testing
    Tools (2): echo_input, fail_always

  Plugins dir: /home/you/.kadmo/plugins

What install does, exactly:

  • <source> must be a local folder. There is no download from a URL or registry.
  • The target folder name is the manifest's name, not the source folder's name. remove takes that same name.
  • If a plugin with that name is already installed, its folder is deleted first and replaced. Files the old copy wrote into its own folder are lost.
  • Everything is copied except .git and a top-level node_modules folder. Install your dependencies in the copied folder afterwards if the handler needs them.
  • The manifest is validated, but tool-name clashes with core tools are not checked at install time. Such a plugin installs, then is skipped when the runtime loads it.

For a service plugin, install and list show no tools (Tools (0):), because its tools are only known once the child is running. The /health endpoint of kadmo serve shows the live tool names (the /health of a client's kadmo mcp has no plugins field):

bash
curl -s http://127.0.0.1:9876/health | jq '.plugins'

When changes take effect ​

The runtime reads ~/.kadmo/plugins/ when it starts and again whenever it reloads its content. Reloads happen on:

TriggerExample
Runtime startkadmo serve, or an MCP client starting kadmo mcp
MCP tools run_workflow and list_workflowsAn agent lists or runs a workflow
Dashboard and API changesOpening the workflow list in the dashboard, or saving or installing workflows and packs through it

There is no file watcher, and the runtime does not tell connected MCP clients that the tool list changed. Most clients read tools/list once when they connect. After installing or removing a plugin, restart kadmo serve, or restart the MCP client session so it starts a fresh kadmo mcp.

On a reload, a service plugin whose plugin.json is unchanged keeps its running child. A removed one is stopped; one whose service block changed is restarted. Changing only the child's code does not restart it; restart the runtime for that.

kadmo serve and kadmo mcp are separate processes. If both run, each loads the plugins and each starts its own copy of every service plugin.

Loading rules ​

SituationResult
A folder without plugin.jsonSkipped, with a warning. Hidden folders are scanned too, so they warn as well
A symbolic link in ~/.kadmo/plugins/Ignored, without a warning. Install a real copy
plugin.json is not valid JSON, or name, version or description is missing or not a stringPlugin skipped
runtime: "process" with no tools array, or no valid tool in itPlugin skipped
A tool missing name, description, inputSchema or handler, or an inputSchema without a string typeThat tool skipped; the others load
A process tool named like a core tool (for example navigate)The whole plugin skipped
Two process plugins declare the same tool nameBoth are listed; calls always go to the plugin whose folder sorts first
runtime: "service" without service.commandPlugin skipped

Warnings go to the runtime's log (stderr). kadmo plugin list prints the same warnings, which makes it a quick check before you restart anything.

Known issues in this release ​

  • kadmo plugin remove <name> does not check the name. It deletes ~/.kadmo/plugins/<name> with the name taken as a path, so kadmo plugin remove .. deletes all of ~/.kadmo (settings, packs, workflows and plugins), kadmo plugin remove ../skills deletes every installed skill pack, and kadmo plugin remove "" deletes every plugin. Each reports success. Only pass a name that kadmo plugin list shows.
  • kadmo plugin install uses the manifest's name as a path in the same way. Only install plugins whose plugin.json you have read; a name such as ../workflows replaces that folder.
  • Running kadmo plugin install on a folder that is already inside ~/.kadmo/plugins/ empties that plugin and still reports success. Install from a copy outside the plugins folder.

Next steps ​