MCP servers as listings
Every MCP server, the tool servers Claude and Cursor already speak to, is a service an agent can buy: a node runs one and lists each of its tools at a price per call. The marketplace's MCP servers group holds hundreds of them, each template generated from a real registry entry, and a node of yours can serve any of them, or a server of your own.
The mcp adapter
One tool entry in services.json covers a whole server:
{
"key": "mcp-adbutler", "category": "mcp:dev", "priceUsdc": 0.02,
"tools": [{
"type": "mcp", "name": "adbutler", "transport": "stdio",
"command": "npx", "args": ["-y", "@adbutler/mcp-server@2.4.2"],
"env": { "ADBUTLER_API_KEY": "{env:ADBUTLER_API_KEY}" },
"tools": "all"
}]
}
transport is stdio (the node spawns the server once, command and args, with only the
env you declare beside a clean PATH) or http (a remote streamable-HTTP or SSE server at
url, with optional headers). At boot the node calls the server's tools/list and lists every
tool with the server's own input schema, or the one named in tool; tools/call goes to the
server with the paid session's arguments, and an error from the server is the tool's error. A
server that fails to start is reported and not listed. Image, audio and file results come back as
URLs on the node's /media path. timeoutMs (default 120 s) bounds a call, startTimeoutMs
(90 s) the start.
The catalogue
npm run templates:generate:mcp reads the official MCP registry
(registry.modelcontextprotocol.io), the modelcontextprotocol/servers README and
mcpmarket.com (--source registry,readme,mcpmarket; Smithery with SMITHERY_API_KEY, else left
out and said so) and writes one template per server: a provider-neutral title from what it does,
category mcp:<area> from its tags, env from its declared variables, keyless when it has
none, a price of 0.005 USDC a call keyless and 0.02 with a key, and generated: {source, at}.
--top (500) and --all size the run; --cache keeps the registry pages.
The bootstrap catalogue leaves MCP templates out unless you opt in: AIOUM_CATALOGUE_MCP=remote
lists the ones whose servers run elsewhere (http, nothing of them runs on your machine),
verified the ones that passed the check, all every keyless one; a skipped template says
"needs AIOUM_CATALOGUE_MCP=remote, =verified or =all" at boot.
Verified only inside a container
A registry server is code from a stranger, so npm run templates -- verify <name> never runs a
stdio server on the host. An npx or uvx server is started with docker run --rm -i in
node:22-slim or ghcr.io/astral-sh/uv:python3.12-bookworm-slim, with --cap-drop ALL --security-opt no-new-privileges --pids-limit 256 --memory 1g --cpus 1 and nothing of the host
mounted; the check is the server answering tools/list, and a tool is called only when the
template carries sample arguments. Without Docker the row reads "not run on this machine: a stdio
MCP server is verified only inside a docker container". A server whose command is a binary on the
host, or a docker run that mounts a host path, is not run by the check and stays verified: false. An http server needs no container: it runs elsewhere.
Served the same way
A stdio server listed on your node is served as it is verified: inside a docker container with
nothing of the host mounted, when docker answers (AIOUM_MCP_SANDBOX=docker, the default
then). Without docker it is not served, and the node says so at boot, unless you set
AIOUM_MCP_SANDBOX=host: your own decision to run a stranger's code on the machine. A server
that is a binary on the host cannot be put in a container and is refused under docker. An http
server runs elsewhere and needs neither.
Host access: hostAccess and allowHost
Some servers exist to read files, run commands or drive a browser on the machine they run on:
Playwright, Chrome DevTools, a filesystem server, Obsidian. Their templates carry hostAccess: true. Such a server is never in a bootstrap catalogue, and a node refuses to load it, "this MCP
server reads files, runs commands or drives a browser on the node it runs on; set "allowHost":
true on the listing to run it here anyway", until the listing says "allowHost": true. That is
the operator's own decision about their own machine, made per listing, never by a default. On
the Earn page such a template carries the badge Reaches into its node and the box "This
server reads files, runs commands or drives a browser on your node. List it anyway.", and Go
live now stays disabled until List it anyway is ticked; every stdio server's setup step
says Runs on your node with the permissions you give it. The marketplace shows the same
badge on the listing, so a buyer knows too.
List one
cd offchain
npm run templates -- verify mcp-adbutler # a keyed one, with ADBUTLER_API_KEY in your env
npm run templates -- add mcp-adbutler --out services.json
AIOUM_SERVICES_CONFIG=./services.json npm run multinode
Or on the Earn page, from the gallery; from the command line, aioum sell add --template mcp-adbutler --env ADBUTLER_API_KEY=…; from Claude, aioum_sell_add. A remote server is the
same entry with "transport": "http" and its url, as mcp-github is
(https://api.githubcopilot.com/mcp/, the key in a header); a server of your own is the same
entry with your command or URL. An agent sees each of the server's tools as one marketplace tool,
priced per call, with the schema the server declared.
Next: The crypto toolbox — the services agents actually buy, composed into bots, and the boundary that keeps their keys out of your node.