Expose an app as an MCP tool
Goal: take a managed-runtime app and make it callable by agents/LLMs over MCP. An mcp_enabled app shows up — after publish — as a tool named `ignite_{org}_{name}` whose schema is the input_schema you set and whose description is the app’s description.
Shape:
handler.py ──► app create --mcp-enabled ──► draft save ──► draft publish
(def handler) (+ --description + --input-schema) (code) (version 1)
│
▼
tool: ignite_{org}_{name}
(visible to MCP clients)Prerequisites
- The
dodilCLI installed and authenticated —dodil ignite config set token <token>anddodil ignite config set api_endpoint rpc.dev.dodil.io:443(orexport DODIL_TOKEN=<token>). See CLI Basics. - Your org name. We use
acme-corp.
What makes an app an MCP tool
Three things must be set on the app, then it must be published:
| Field | CLI flag | Why it matters |
|---|---|---|
mcp_enabled | --mcp-enabled | Opts the app into the MCP tool catalog |
description | --description | Becomes the tool description the model reads to decide when to call it |
input_schema | --input-schema | JSON Schema for the tool’s arguments — MCP clients validate against it |
The tool only appears after the first publish (active_version > 0), named `ignite_{org}_{name}`.
1. Write the handler
Same managed-runtime contract as any Python app — def handler(payload, ctx), where payload is the raw body and you parse it yourself. The fields you read should match the input_schema you’ll declare.
Create handler.py:
import json
def handler(payload, ctx):
try:
args = json.loads(payload) if payload else {}
except (TypeError, ValueError):
args = {}
city = args.get("city", "")
units = args.get("units", "celsius")
# ... look up the weather for `city` ...
return {
"city": city,
"units": units,
"summary": f"Clear, 21°{'C' if units == 'celsius' else 'F'}",
}2. Create the app with MCP enabled
Pass --mcp-enabled, a --description (write it for the model — say what the tool does and when to use it), and an --input-schema (a JSON Schema string):
dodil ignite app create weather \
--runtime python \
--mcp-enabled \
--description "Get the current weather summary for a city. Use when the user asks about weather, temperature, or conditions in a named place." \
--input-schema '{
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name, e.g. \"Cairo\"" },
"units": { "type": "string", "enum": ["celsius", "fahrenheit"], "default": "celsius" }
},
"required": ["city"]
}'The app id is now acme-corp:weather.
You can also set these later with
dodil ignite app update acme-corp:weather --mcp-enabled true --input-schema '...'.
3. Save and publish
dodil ignite draft save acme-corp:weather -c ./handler.py
dodil ignite draft publish acme-corp:weatherPublishing cuts the immutable version and registers the MCP tool.
4. Confirm the tool
The tool name is `ignite_{org}_{name}` — for acme-corp:weather that’s `ignite_acme-corp_weather`. There is no ignite mcp command; inspect the tool through the API (Catalog & MCP) or your MCP client.
List the org’s MCP tools over HTTP:
curl -sS "https://api.dev.dodil.io/v1/ignite/app/acme-corp/mcp/tools" \
-H "Authorization: Bearer $DODIL_TOKEN" | jq '.tools[] | {name, description}'You should see an entry named `ignite_acme-corp_weather` — its input_schema and output_schema are exactly what MCP clients validate against. The same tool appears in any MCP client connected to your org.
5. Call it
The tool runs the same active version as a normal invoke — an MCP client calls `ignite_acme-corp_weather` with arguments matching your input_schema. To exercise the underlying app directly:
dodil ignite invoke acme-corp:weather -p '{"city": "Cairo", "units": "celsius"}'{ "city": "Cairo", "units": "celsius", "summary": "Clear, 21°C" }Common gotchas
| Symptom | Cause | Fix |
|---|---|---|
| Tool doesn’t appear in the catalog / MCP client | App not published yet — MCP tools register only after first publish | dodil ignite draft publish acme-corp:weather |
| Tool appears but has no schema / clients won’t call it | input_schema missing | Set --input-schema on create, or dodil ignite app update ... --input-schema '...' then republish |
| Model picks the wrong tool or never calls it | Weak description | Rewrite the --description to state what it does and when to use it |
| Tool name isn’t what you expected | Name is derived: `ignite_{org}_{name}` | Rename the app, or accept the derived name |
See also
- API Reference → Catalog & MCP —
ListMcpTools/GetMcpToolDefinition, theMcpToolDefinitionshape, public catalog - Deploy a Python app — the full managed-runtime flow with dependencies
- Core Concepts → App —
mcp_enabled,description,input_schema,output_schema - Quickstart — first app in 5 minutes