Working with applications
Every installed application’s methods are tools from the start: one tool per method except init, which create_context runs, listed for the whole session.
describe_app and select_app hand over the app’s guide and the app_handle those tools require, and call is the fixed-name route to the same methods.
Naming an application
Section titled “Naming an application”Anywhere a tool takes an application, four forms work:
| Form | Example |
|---|---|
| Application id | 5w8XyQ… (base58) |
| Full package name | com.calimero.kv-store |
| Trailing package segment | kv-store |
Display name, the bundle’s metadata.name, in any case |
Mero Blocks |
An id is tried first, then a full package name, then the two short forms together. A short form that matches more than one installed application, such as one app’s trailing segment and another’s display name, is ambiguous, and the error lists their packages.
The short form is matched on whole segments only, so mero-chat never
resolves to mero-chat-v2. If the segment is ambiguous across installed
applications, the error names the candidates and you disambiguate with the full
package or the id:
Application "chat" is ambiguous: com.calimero.chat, com.example.chat.Pass the full package name or the application id.A name that matches nothing lists what is installed, which is usually faster
than going back to list_applications.
App guides and app handles
Section titled “App guides and app handles”An app can ship a guide: Markdown its author writes, carried in the signed bundle and stored by the node.
list_applications returns one compact row per app: id, package, name, version, a short description, hasGuide and procedures, the ### titles under the guide’s ## Procedures heading.
Icons, blob hashes and the guide itself are left out; pass verbose: true for the full records.
describe_appreturns the app’s methods, the guide (orThis app ships no guide.) and anapp_handlewith no context. It is the way to plan across several apps. Call it before setting up namespaces, groups or contexts for an app you have not used before, since its guide says how that app expects them to be laid out.select_appreturns anapp_handlebound to one context: the one you pass ascontext, or the app’s only context. It repeats neither the methods nor a guide this session has already shown; passverboseto get both.- Every generated tool and
calltake thatapp_handle. It names the context the call runs in, so there is no separate context argument.
The guide arrives as an embedded text/markdown resource, preceded by App guide, provided by the app's author (package <package>, signer <signer id>):, so it reads as the author’s text, not as the server’s own instructions.
Method-level detail lives next to the code: an app’s /// doc comments become its tool descriptions.
Each guide is also a resource at calimero://apps/<application id>/<version>/guide, keyed by application id so two signers of one package never share one.
A call without a valid handle runs nothing.
It returns the guide (when the app has one) and Call select_app for <package> and retry with the returned app_handle.
A handle stops being valid when the app is upgraded, when its guide changes, when its context is gone, or when the server’s handle key changes; select_app issues a fresh one.
A handle from describe_app has no context, and app tools refuse it with a request to select one.
Apps without a guide still need a handle.
Handles are per application, so holding several is how one instruction spans several apps:
Select kv-store and mero-chat, then use each handle for that app's tools.When apps are installed
Section titled “When apps are installed”The tool list is the same for every client and changes only when an app is installed, upgraded or uninstalled.
mero-mcp reads it when a client connects, again right after its own install_application or uninstall_application, and every 30 seconds once a read has reached the node, and announces a change with notifications/tools/list_changed.
When select_app, describe_app or call names an app the list does not have yet, for example because the node was down when the client connected, mero-mcp reads the list again first, which also starts the 30-second refresh.
Selecting an app never changes the list otherwise.
A node holds one version of an app: core keys an app by its package and signer, so an upgrade replaces it in place and makes its old handles stale.
The same package from two signers is two apps, each with its own tools; the one later in application id order carries a suffix from its id.
A package name then matches both, so select_app and describe_app refuse it, list each application id with its signer, and ask for the id.
select_app’s tools lists exactly the tool names of the app it bound, and a handle for one of the two apps is refused by the other’s tools.
Multi-service applications
Section titled “Multi-service applications”An application can bundle several services, each with its own ABI and its own tools, named <app>_<service>_<method>.
A context belongs to one service, so select_app with a context binds that service into the handle, and the other service’s tools refuse it.
Without a context, pass service to describe_app or select_app; omitting it on a multi-service app returns an error from the node naming the services available.
describe_app reports the service names any existing contexts use (contextServices), which is what create_context asks for.
call vs generated tools
Section titled “call vs generated tools”call reaches the same methods through one fixed tool name:
Call the `call` tool with the app_handle, method "set" and args {"key": "greeting", "value": "hello"}.Use it when the generated tools are not visible to your client (see troubleshooting).
Arguments go under args, keyed by parameter name, and are checked against the same ABI-derived schema the generated tools use, after the handle.
Without a handle, pass app so the refusal can show that app’s guide.