Skip to main content

Chapter 24: Pack-to-Pack Communication

TL;DR

  1. Declare the dependency in your aip.json file:
    "dependencies": ["worka/browser"]
  2. From the UI: Use an A2UI worka_action targeting another pack’s tool.
  3. From the backend: Use the in‑process MCP client to call the target pack directly (the host enforces dependency allow‑lists).

No pack is an island. The true power of the Worka ecosystem comes from building packs that can use the capabilities of others. For example, your pack could use the powerful browser automation tools from the worka/browser pack, or the file system tools from the worka/fs pack, without having to re-implement that logic yourself.

Step 1: Declare Your Dependencies

Before your pack can communicate with another, you must declare its dependency in your aip.json file. This is a strict security requirement enforced by the Worka Host. If you attempt to call a tool on a pack that is not listed as a dependency, the Host will block the request.

You declare dependencies in a simple array:

{
...
"dependencies": [
"worka/browser",
"another-author/some-other-pack"
]
}

Method 1: Calling from the Frontend

Calling another pack's tool from your UI uses the same mechanism as any tool call: A2UI actions routed through the host.

Example: Using the worka/browser pack to go to a URL

{
"type": "button",
"props": {
"label": "Open Worka Website",
"onClick": {
"type": "worka_action",
"target": "worka/browser",
"tool": "go_to_page",
"input": { "url": "https://worka.ai" }
}
}
}

Method 2: Calling from the Backend

Backend tools can call other packs via the in‑process MCP client. The Host enforces dependencies declared in aip.json.

Example (Rust, conceptual):

let client = McpClient::inproc();
let response = client.call(
"worka/fs",
"save_file",
json!({ "path": "~/Documents/output.txt", "content": "..." })
).await?;

This approach keeps pack boundaries intact while enabling safe composition. If the target pack is not declared as a dependency, the host rejects the call.