Overview
The decentralised.art MCP server connects AI agents to the network through the Model Context Protocol. Add it to an MCP host such as Claude Code, Claude Desktop, Codex, Cursor or VS Code, and your agent can work with the network directly:
- find and read connectors, transformations, conditions, formats, accounts and new events;
- create its own operations as drafts and simulate them for free;
- publish them on chain from your account, within fee limits you set;
- execute published connectors and keep verifiable results.
The server runs on your computer and talks to the public chain API at https://api.decentralised.art/chain. Your agent does not need to run inside this
website: it works from any environment that can start the server. Reading, simulating and
executing need no account; creating and publishing need a private key that stays on your
machine.
The server's tools are format-agnostic: they handle values and structure, not what the values mean. Interpreting results as notes, images or motion is up to the agent and the Worlds it feeds. If you are writing code rather than working with an agent, use the SDK; both reach the same API.
Installation
The server is installed from source. You need Python 3.10 or later and git; make is used on macOS and Linux. The setup creates a private virtual
environment inside the folder, so nothing is installed system-wide.
git clone https://github.com/decentralised-art/mcp.git
cd mcp
make install # creates .venv and installs the server
make smoke # runs the test suite and a local tool callgit clone https://github.com/decentralised-art/mcp.git
cd mcp
py scripts\bootstrap_venv.py
.venv\Scripts\python -m unittest discover -s testsKeep the folder where it is: your MCP host starts the server from it. The examples below use /path/to/mcp for that folder; replace it with the full path on your machine.
Connect your agent
Register the server with your host. Every host needs the same three things: the Python inside
the folder's virtual environment, the arguments -m decentralised_art_mcp.server stdio, and the environment variables from Configuration.
claude mcp add --transport stdio --scope user \
--env API_BASE=https://api.decentralised.art/chain \
--env DECENTRALISED_ART_ARTIFACT_ROOT=/path/to/mcp/decentralised-art-mcp-artifacts \
--env PRIVATE_KEY=0xYourTestnetKey \
decentralised-art -- /path/to/mcp/.venv/bin/python -m decentralised_art_mcp.server stdio
claude mcp list # "decentralised-art" should be listed as connected# Requires uv (https://docs.astral.sh/uv/) on the machine running Claude Desktop.
cd /path/to/mcp
make mcpb # writes dist/decentralised-art-mcp-<version>.mcpb
# Then double-click the .mcpb file, drag it into Claude Desktop, or install it from
# Claude Desktop's extension settings. It asks for the API base URL, an optional
# private key, the timeout and the artifact folder.# ~/.codex/config.toml
[mcp_servers.decentralised-art]
command = "/path/to/mcp/.venv/bin/python"
args = ["-m", "decentralised_art_mcp.server", "stdio"]
[mcp_servers.decentralised-art.env]
API_BASE = "https://api.decentralised.art/chain"
DECENTRALISED_ART_TIMEOUT = "15"
DECENTRALISED_ART_ARTIFACT_ROOT = "/path/to/mcp/decentralised-art-mcp-artifacts"
PRIVATE_KEY = "0xYourTestnetKey" # optional{
"mcpServers": {
"decentralised-art": {
"type": "stdio",
"command": "/path/to/mcp/.venv/bin/python",
"args": ["-m", "decentralised_art_mcp.server", "stdio"],
"env": {
"API_BASE": "https://api.decentralised.art/chain",
"DECENTRALISED_ART_TIMEOUT": "15",
"DECENTRALISED_ART_ARTIFACT_ROOT": "/path/to/mcp/decentralised-art-mcp-artifacts"
}
}
}
}{
"servers": {
"decentralised-art": {
"type": "stdio",
"command": "/path/to/mcp/.venv/bin/python",
"args": ["-m", "decentralised_art_mcp.server", "stdio"],
"env": {
"API_BASE": "https://api.decentralised.art/chain",
"DECENTRALISED_ART_TIMEOUT": "15",
"DECENTRALISED_ART_ARTIFACT_ROOT": "/path/to/mcp/decentralised-art-mcp-artifacts"
}
}
}
}{
"command": "/path/to/mcp/.venv/bin/python",
"args": ["-m", "decentralised_art_mcp.server", "stdio"],
"cwd": "/path/to/mcp",
"env": {
"API_BASE": "https://api.decentralised.art/chain",
"DECENTRALISED_ART_TIMEOUT": "15",
"DECENTRALISED_ART_ARTIFACT_ROOT": "/path/to/mcp/decentralised-art-mcp-artifacts",
"PRIVATE_KEY": "<optional>"
}
}Restart the host, or open a new session, after adding the server; hosts usually load MCP
servers only at start-up. PRIVATE_KEY is optional: leave it out to use the server for
reading, simulating and executing only.
Sharing a project configuration
Claude Code can read servers from a .mcp.json file committed with a project. Never
put a key in that file; reference an environment variable instead:
{
"mcpServers": {
"decentralised-art": {
"command": "/path/to/mcp/.venv/bin/python",
"args": ["-m", "decentralised_art_mcp.server", "stdio"],
"env": {
"API_BASE": "https://api.decentralised.art/chain",
"DECENTRALISED_ART_ARTIFACT_ROOT": "/path/to/mcp/decentralised-art-mcp-artifacts",
"PRIVATE_KEY": "${PRIVATE_KEY}"
}
}
}
}Check the connection
Ask your agent something that needs the network, for example:
- “Use the decentralised.art MCP to list the formats on the network.”
- “Read the core.primer resource and summarise how execution works.”
If the tools do not appear, check that the path to .venv/bin/python is absolute
and that you restarted the host. To test the server on its own, open it in the MCP Inspector:
npx @modelcontextprotocol/inspector \
/path/to/mcp/.venv/bin/python -m decentralised_art_mcp.server stdioWorking with your agent
A good session builds on what others have published rather than starting from nothing. The agent should show you what exists, explain it, and agree with you before it spends anything. A typical path:
- Discover. Browse the feed, formats and accounts; read the operations that look useful.
- Understand. Read connector graphs and run published connectors with
core.execute_connectorto see what they produce. - Compose. Create your own transformations, conditions and connectors as drafts, reusing published ones by name.
- Try. Run the drafts with
core.simulate_connector. This is free. - Publish. When you are happy, publish dependencies first, then the connector that uses them, with explicit fee limits.
- Run on chain. Execute the published connector and keep the whole result, with its block and runner, as the reference for what the network produced.
Drafts, simulation and publication follow the same rules as everywhere on the platform; see SDK → Core concepts for transformations, conditions, dimensions and running instances.
Example prompts
| You ask | The agent uses |
|---|---|
| “What has been published on decentralised.art recently? Explain each connector.” | core.get_feed_page, core.get_connector |
| “Run the pitch connector for 16 steps on chain and show me the values with the block.” | core.execute_connector |
| “Create a transformation shift_up that adds its first argument, then a connector that uses add and shift_up, and simulate 16 steps.” | core.create_transformation, core.create_connector, core.simulate_connector |
| “What would publishing shift_up cost?” | core.prepare_publication |
| “Publish shift_up with at most 50 gwei per gas and 0.005 ETH in total, recorded in publications/shift_up.json.” | core.publish_entity |
| “Which connectors share pitch's format?” | core.get_connector, core.get_format |
Configuration
The server reads these environment variables when it starts:
| Variable | Default | Description |
|---|---|---|
API_BASE | https://api.decentralised.art/chain | The chain API to use. |
PRIVATE_KEY | none | Ethereum key for logging in, creating drafts and publishing. Not needed for reading, simulating or executing. |
DECENTRALISED_ART_TIMEOUT | 15 | Seconds per API request, between 0.1 and 120. |
DECENTRALISED_ART_ARTIFACT_ROOT | decentralised-art-mcp-artifacts | Folder for publication records. Use an absolute path; a relative one depends on where the host starts the server. |
Tools that call the API also accept api_base and timeout arguments
to override these for a single call, and authenticated tools accept private_key.
Prefer the environment variable for keys, so they never appear in the conversation.
The server logs in to the chain API by signing a one-time nonce with your key. That login is separate from signing in to this website.
Publishing safely
core.publish_entity is the only tool that spends anything. It publishes one draft under
your address and pays the gas from your account. It is built so that an agent cannot overspend or
publish twice by accident:
- Fee limits are required.
max_fee_per_gascaps the price per unit of gas andmax_total_feecaps the whole transaction (gas limit × max fee), both in wei. The tool refuses to sign anything above them. - Every publication has a record.
record_pathis a file insideDECENTRALISED_ART_ARTIFACT_ROOT. The transaction is written to it before it is sent. Calling the tool again with the same record only confirms that transaction; it never sends another. - Only zero-value transactions to the expected chain. The tool checks the
owner, the chain (
chain_id, Sepolia11155111by default) and that no value is transferred before it signs. - Your key never leaves your machine. The transaction is signed locally and the API relays it; no RPC endpoint of your own is needed.
{
"name": "core.publish_entity",
"arguments": {
"kind": "transformation",
"name": "shift_up",
"max_fee_per_gas": 50000000000,
"max_total_fee": 5000000000000000,
"record_path": "publications/shift_up.json"
}
}For reference: 50 gwei is 50000000000 wei and 0.005 ETH is 5000000000000000 wei.
Rules for agents
- Inspect first. Use
core.prepare_publicationto see the fees, and confirm them with the person before publishing. - Dependencies first. Transformations, conditions and child connectors must
be published before the connector that uses them. Otherwise the call fails and lists them
under
missingormismatched. - One publication at a time per owner. Publications from one address share a nonce, so separate sessions must not publish for the same key in parallel.
- Pending is not failure. If a publication is still pending or its outcome is
unknown, the tool returns
publication_pendingwith the transaction hash. Confirm it with the same record, or withcore.confirm_publication, before doing anything else. - Mined is not instantly executable. Execution reads the chain at a safe block, so a freshly mined connector can take a short while to become available. Retry the execution; do not republish, and never present a simulation as an on-chain result.
Results and errors
Every tool returns the same envelope, as structured content and as JSON text. A successful
call carries data:
{
"name": "core.execute_connector",
"arguments": { "connector_name": "pitch", "particles_count": 4 }
}{
"ok": true,
"data": {
"block_number": 11825265,
"block_hash": "0xfa8ee7fe85e17439d69d98aef0418556a9d9a0d5794d5568fd32de300853acc5",
"runner": "0xe0e70f522b64a6c8d2301697cd7133be33eae77f",
"particles": [{ "path": "/pitch:0", "data": [0, 1, 2, 3] }],
"execution_mode": "chain"
}
}A failed call is marked as an error and carries error instead:
{
"ok": false,
"error": {
"code": "validation_error",
"message": "params.particles_count is required",
"details": { "path": "params.particles_count", "required": true }
}
}| Code | Meaning |
|---|---|
validation_error | Invalid or missing arguments, or a fee or chain check refused to sign. |
auth_configuration_error | The tool needs a key and none, or an invalid one, is configured. |
http_error | The API rejected the request. details.status_code holds the status, and
publication conflicts list missing and mismatched dependencies. |
publication_pending | A publication is pending or its outcome is unknown. details holds the transaction
to confirm. |
tool_not_found, resource_not_found | Unknown tool or resource name. |
internal_tool_error | Unexpected failure inside the server. |
Keys and security
- Use a dedicated key for your agent, funded only with what it should be able to spend. During testing, publications use Sepolia test ETH.
- Give the key to the server through
PRIVATE_KEYor the host's secret settings, not in a prompt. Keep it out of files you commit or share. - Leave the key out entirely if the agent only needs to explore, simulate and execute.
- The server never sends your key anywhere. It signs the login nonce and publication transactions locally.
Tools
All tools live in the core namespace. Every tool that calls the API also accepts api_base and timeout; tools marked Login accept private_key and need a key from it or from the environment.
Discover and read
| Tool and arguments | Description |
|---|---|
core.get_connector name | A connector's definition, owner, address and format hash. |
core.get_transformation name | Name, args_count, owner and address. |
core.get_condition name | Name, args_count, owner and address. |
core.connector_exists name | Whether a connector exists. |
core.transformation_exists name | Whether a transformation exists. |
core.condition_exists name | Whether a condition exists. |
core.list_formats limit, after | Format hashes known to the network. |
core.get_format format_hash, limit, after | Connectors and scalar labels that share one format. |
core.get_account address, limit, after_connectors, after_transformations, after_conditions | What an address has published. |
core.get_feed_page limit, before, type, include_unfinalized | Newest-first page of chain events. |
core.get_feed_stream_replay since_seq, limit | A bounded replay of the live event stream, for catching up. |
core.get_nonce address | The login nonce for an address. |
Create drafts
| Tool and arguments | Description |
|---|---|
core.create_transformation payload | Login Create a transformation draft: name and Solidity body. No gas. |
core.create_condition payload | Login Create a condition draft: name and Solidity body. No gas. |
core.create_connector payload | Login Create a connector draft from dimensions, an optional condition and running instances. No gas. |
core.build_parent_connector name, child_names | Build (but not create) a connector payload with one dimension per child connector. |
Run
| Tool and arguments | Description |
|---|---|
core.simulate_connector connector_name, particles_count, dynamic_ri | Run drafts in the server's local EVM. Returns particles with execution_mode "simulation". |
core.execute_connector connector_name, particles_count, dynamic_ri | Run a published connector on chain at a pinned block. Returns particles with block_number, block_hash, runner and execution_mode "chain". |
Publish
| Tool and arguments | Description |
|---|---|
core.prepare_publication kind, name | Login Show the transaction and fees a publication would need. Signs and sends nothing. |
core.publish_entity kind, name, max_fee_per_gas, max_total_fee, record_path, chain_id, max_confirm_attempts | Login Sign locally, relay once and confirm. Spends the owner's gas. See Publishing safely. |
core.confirm_publication kind, name, content_hash, tx_hash | Login Check the receipt of a publication already sent. Never sends another. |
Helpers
| Tool and arguments | Description |
|---|---|
core.ensure_preflight required_connectors, preferred_transformation_pairs | Login Log in, check that the given connectors exist, and pick an available add/subtract transformation pair. |
core.resolve_transformation_pair pairs | Pick the first add/subtract transformation pair that exists on the network. |
Draft payloads use the same fields as the API: see SDK → Creating operations. Running-instance overrides (dynamic_ri) and step counts (1–65536) work as described in SDK → Executing on chain.
Resources
| Resource | Description |
|---|---|
core.primerdecentralised-art://resource/core.primer | A short primer for agents: connectors, dimensions, running instances, the draft → simulate → publish → execute lifecycle, and the publication rules above. Ask your agent to read it at the start of a session. |
Command line
The same tools can be called without an MCP host, which is useful for scripts and for checking a setup:
cd /path/to/mcp
source .venv/bin/activate
decentralised-art-mcp list-tools # every tool with its input schema
decentralised-art-mcp list-resources
decentralised-art-mcp read-resource core.primer
decentralised-art-mcp invoke core.get_connector '{"name": "pitch"}'
decentralised-art-mcp invoke core.execute_connector '{"connector_name": "pitch", "particles_count": 4}'The repository's make targets wrap the common tasks: make install, make smoke, make test, make stdio (run the server), make mcpb (Claude Desktop bundle), make list-tools and make list-resources.
Versions and source
- Source and issues: github.com/decentralised-art/mcp.
Update with
git pullfollowed bymake install, then restart your host. When upgrading from a version before 0.2.0, follow the upgrade notes in the README: some names changed. - Requests and responses are checked against the OpenAPI contracts in api-spec, packaged with the server.
- Related: the SDK for code, the API reference for endpoints, and API status for the live services.