Skip to content

Your first session

This walks the path every session takes: confirm the node, find an application, select it, call it. Ask your agent to run each tool and show you the result.

Call the node_status tool.

node_status is the one tool that answers every “is this even connected?” question at once:

{
"health": { "status": "healthy" },
"url": "http://localhost:2528",
"nodeName": "default",
"discoverySource": "config-scan",
"authMode": "handoff"
}
  • url / nodeName — which node you actually reached. nodeName is null when nothing on this machine names it (a bare CALIMERO_NODE_URL, or a probed node).
  • discoverySource — how it was found: env, handoff, named, config-scan or probe. If this says probe and you expected a specific node, discovery fell through to guessing at ports.
  • authMode — handoff, token, credentials or none.

The server connects to the node when your client opens the connection, to list the installed apps. A node that is down or credentials that are wrong do not stop the server: they are logged, this is the first call that reports them, and the next call retries rather than leaving the server wedged. A node that hangs instead of refusing delays the client’s handshake by up to the node request timeout.

Call list_applications, then list_contexts.

list_applications returns what is installed, each with an id, a package (reverse-DNS dotted, like com.calimero.kv-store), a name, version and short description. Each entry also carries hasGuide and procedures, the titles of the procedures in the app’s guide.

list_contexts returns the contexts. If it comes back empty, stop here and create one — no amount of selecting will make app calls work without a context:

Call create_context with application "kv-store" and group "<namespace-id>".

You need a namespace first; list_namespaces shows them and create_namespace makes one. See contexts and namespaces.

Call describe_app with app "kv-store".

describe_app shows the app without choosing a context: every method with its parameters and return type, rendered as signatures (below the author’s doc, when the ABI carries one), and an app_handle for planning:

{
"application": "5w8Xy…",
"package": "com.calimero.kv-store",
"appVersion": "0.1.0",
"service": "KvStore",
"contextServices": ["KvStore"],
"methods": [
"[view] get(key: string) -> string | null",
"[mut] set(key: string, value: string) -> unit",
"[view] entries() -> map<string, string>"
],
"app_handle": "eyJwIjoiY29tLmNhbGltZXJvLmt2LXN0b3JlIi..."
}

After the JSON comes the app’s guide, labelled as written by the app’s author, or the line This app ships no guide.

[view] methods are read-only; [mut] methods write. Note the application name: you can pass the full package, the application id, or just the last dotted segment (kv-store) as long as it is unambiguous.

4. Select it: pick the context and get the app_handle

Section titled “4. Select it: pick the context and get the app_handle”
Call select_app with app "kv-store".

The tools already exist: every installed app’s methods are listed from the moment the client connects. select_app picks the context to act in and returns the app_handle every app tool requires, plus the guide:

{
"tools": ["kv_store_entries", "kv_store_get", "kv_store_set"],
"context": "8Hk2...",
"app_handle": "eyJwIjoiY29tLmNhbGltZXJvLmt2LXN0b3JlIi...",
"toolsNote": "These are the server-side tool names. An MCP client may expose them under a prefix of its own..."
}

The tools are named <app>_<method> from the trailing package segment, so com.calimero.kv-store yields kv_store_get. Your client may show them under a prefix of its own — commonly mcp__mero-mcp__kv_store_get.

If the application has exactly one context, select_app chooses it. With several, it returns a note listing the ids and you pass context explicitly.

Use kv_store_set to store "hello" under the key "greeting", then read it back with kv_store_get.

Every call passes that app_handle, which names the context the call runs in. A call without a valid one runs nothing and asks you to call select_app again.

The arguments are validated against the ABI before anything reaches the node, so a wrong type fails locally with a schema error rather than as an opaque node rejection.

  1. Working with applications - app guides and handles, multi-service apps, call vs generated tools.

  2. Contexts and namespaces — creating them, aliasing them, and the deletion order that leaves a mess if you get it wrong.

  3. Tool reference — every tool and its arguments.

  4. Troubleshooting — when a step above did not go this way.