Transport-level routing for MCP/ACP protocols

We appreciate your patience. The service is temporarily operating in an external runtime environment.

Registry Launcher

Universal worker for spawning agents from the ACP Registry on demand.

Getting Started

Registry Launcher

Overview

The Registry Launcher provides dynamic agent routing capabilities by integrating with the ACP Registry. It automatically discovers available agents, manages their lifecycle as child processes, and routes messages based on the requested agentId. This enables a single stdio Bus deployment to support multiple agents without manual configuration.

Location: workers-registry/acp-worker/src/registry-launcher/

Features

  • Automatic Agent Discovery: Fetches and caches the latest agent list from the ACP Registry
  • Dynamic Process Management: Spawns and manages agent processes on-demand
  • API Key Injection: Securely injects API keys from configuration into agent environments
  • Session Affinity Routing: Ensures messages with the same sessionId route to the same agent instance
  • Multi-Agent Support: Handle requests for multiple different agents simultaneously
  • Graceful Shutdown: Cleanly terminates agent processes on shutdown signals

Available Agents

The Registry Launcher can route to any agent in the ACP Registry, including:

  • claude-acp - Claude Agent
  • goose - Goose
  • cline - Cline
  • github-copilot - GitHub Copilot
  • And many more from the ACP Registry

The full list of available agents is dynamically fetched from the registry at runtime.

Configuration

Basic Configuration

Create a configuration file for stdio Bus kernel:

{
"pools": [
{
"id": "registry-launcher",
"command": "npx",
"args": [
"@stdiobus/workers-registry",
"registry-launcher"
],
"instances": 1
}
]
}
Code block in JSON, 13 lines

Configuration with API Keys

For agents that require API keys (like Claude), provide a separate API keys file:

{
"pools": [
{
"id": "registry-launcher",
"command": "npx",
"args": [
"@stdiobus/workers-registry",
"registry-launcher",
"./api-keys.json"
],
"instances": 1
}
]
}
Code block in JSON, 14 lines

API Keys File Format (api-keys.json):

{
"agents": {
"claude-acp": {
"apiKey": "sk-ant-...",
"env": {}
},
"goose": {
"apiKey": "sk-...",
"env": {}
},
"github-copilot": {
"apiKey": "ghp_...",
"env": {}
}
},
"version": "1.0.0"
}
Code block in JSON, 17 lines

The Registry Launcher will use these API keys and environment variables for spawned agent processes.

Production Configuration

For production deployments with resource limits:

{
"pools": [
{
"id": "registry-launcher",
"command": "npx",
"args": [
"@stdiobus/workers-registry",
"registry-launcher",
"./api-keys.json"
],
"instances": 2
}
],
"limits": {
"max_input_buffer": 2097152,
"max_output_queue": 8388608,
"max_restarts": 10,
"restart_window_sec": 120,
"backpressure_timeout_sec": 90
}
}
Code block in JSON, 21 lines

Configuration Fields

FieldTypeDescription
idstringUnique identifier for the worker pool
commandstringPath to Node.js executable
argsstring[]Arguments: launcher path, "registry-launcher", optional API keys file
instancesnumberNumber of launcher instances (≥1)

ACP Registry Integration

Registry Discovery

The Registry Launcher automatically fetches the agent registry from:

https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json
Code block in Text, 1 line

The registry contains metadata for each agent including:

  • Agent ID and display name
  • Installation command
  • Required environment variables
  • Supported capabilities

Agent Metadata

Each agent in the registry includes:

{
"id": "claude-acp",
"name": "Claude Agent",
"command": "npx",
"args": ["@agentclientprotocol/claude-acp"],
"env": {
"ANTHROPIC_API_KEY": "required"
}
}
Code block in JSON, 9 lines

The Registry Launcher uses this metadata to spawn and configure agent processes.

Caching

The registry is cached locally to minimize network requests. The cache is refreshed:

  • On startup
  • When an unknown agent is requested
  • After cache expiration (configurable)

Dynamic Agent Discovery and Management

Agent Lifecycle

The Registry Launcher manages agent processes through the following lifecycle:

  1. Client sends request with agentId
  2. Launcher checks if agent process is already running
  3. If not running, launcher fetches agent metadata from registry
  4. Launcher spawns new agent process with proper configuration
  5. API keys are injected into agent environment
  6. Request is routed to the agent process
  7. Agent response is returned to client

Process Management

The Registry Launcher manages agent processes:

  1. On-Demand Spawning: Agents are spawned only when first requested
  2. Process Pooling: Multiple instances of the same agent can run concurrently
  3. Health Monitoring: Monitors agent process health and restarts on failure
  4. Resource Cleanup: Terminates idle agents after timeout (configurable)
  5. Graceful Shutdown: Sends SIGTERM to all agents on launcher shutdown

Session Affinity

Messages with the same sessionId are routed to the same agent instance:

{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"agentId": "claude-acp",
"clientInfo": {
"name": "my-client",
"version": "1.0.0"
}
},
"sessionId": "sess-abc123"
}
Code block in JSON, 13 lines

All subsequent messages with sessionId: "sess-abc123" will route to the same Claude agent instance.

Agent Routing

Specifying the Agent

Include the agentId in the request parameters:

{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"agentId": "claude-acp",
"clientInfo": {
"name": "test-client",
"version": "1.0.0"
}
}
}
Code block in JSON, 12 lines

Routing Flow

  1. Client sends request with agentId parameter
  2. Registry Launcher receives request via stdio Bus
  3. Launcher checks if agent process exists for this agentId
  4. If not, launcher spawns new agent process using registry metadata
  5. Request is forwarded to agent process via stdin
  6. Agent response is returned to client via stdio Bus

Multi-Agent Scenarios

The Registry Launcher can handle multiple agents simultaneously:

# Client 1 requests Claude
{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"agentId":"claude-acp"}}
 
# Client 2 requests Goose
{"jsonrpc":"2.0","id":"2","method":"initialize","params":{"agentId":"goose"}}
 
# Both agents run concurrently, managed by the same launcher
Code block in Bash, 7 lines

Protocol Messages

Initialize with Agent ID

{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"agentId": "claude-acp",
"clientInfo": {
"name": "my-client",
"version": "1.0.0"
}
}
}
Code block in JSON, 12 lines

Initialize Response

{
"jsonrpc": "2.0",
"id": "1",
"result": {
"serverInfo": {
"name": "claude-acp",
"version": "1.0.0"
},
"capabilities": {
"prompts": true,
"tools": true
}
}
}
Code block in JSON, 14 lines

Prompt with Session Affinity

{
"jsonrpc": "2.0",
"id": "2",
"method": "prompt",
"sessionId": "sess-abc123",
"params": {
"agentId": "claude-acp",
"prompt": "What is the weather today?",
"context": {}
}
}
Code block in JSON, 11 lines

Testing

Test Registry Launcher

Start stdio Bus with the Registry Launcher:

docker run \
--name stdiobus-registry-test \
-p 9000:9000 \
-v $(pwd):/stdiobus:ro \
-v $(pwd)/config.json:/config.json:ro \
-v $(pwd)/api-keys.json:/api-keys.json:ro \
stdiobus/stdiobus:latest \
--config /config.json --tcp 0.0.0.0:9000
Code block in Bash, 8 lines

Send Test Message

echo '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"agentId":"claude-acp","clientInfo":{"name":"test"}}}' | nc localhost 9000
Code block in Bash, 1 line

Expected Response

The Registry Launcher will spawn the Claude agent and return its initialization response:

{"jsonrpc":"2.0","id":"1","result":{"serverInfo":{"name":"claude-acp","version":"1.0.0"},"capabilities":{"prompts":true,"tools":true}}}
Code block in JSON, 1 line

Cleanup

docker stop stdiobus-registry-test && docker rm stdiobus-registry-test
Code block in Bash, 1 line

Programmatic Usage

Module Import

// Import registry launcher
import { registryLauncher } from '@stdiobus/workers-registry/workers';
Code block in JavaScript, 2 lines

TypeScript Types

import type { RegistryAgent } from '@stdiobus/workers-registry/workers/registry-launcher';
 
// Use types for type-safe development
const agent: RegistryAgent = /* ... */;
Code block in TypeScript, 4 lines

Troubleshooting

Agent Not Found

If the Registry Launcher cannot find an agent:

{"jsonrpc":"2.0","id":"1","error":{"code":-32602,"message":"Agent not found: unknown-agent"}}
Code block in JSON, 1 line

Solution: Verify the agent ID exists in the ACP Registry.

API Key Missing

If an agent requires an API key that is not provided:

{"jsonrpc":"2.0","id":"1","error":{"code":-32603,"message":"Missing required API key: ANTHROPIC_API_KEY"}}
Code block in JSON, 1 line

Solution: Add the required API key to your api-keys.json file.

Registry Fetch Failure

If the Registry Launcher cannot fetch the registry:

# Check network connectivity
curl https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json
Code block in Bash, 2 lines

Solution: Ensure the launcher has internet access to fetch the registry.

Next Steps

stdioBus
© 2026 stdio Bus. All rights reserved.