How to Integrate Prime Agent with External Systems Using RPC Mode
Prime Agent can be integrated with external systems by launching it in RPC mode, which enables headless operation via JSON-Lines communication over standard streams, allowing programmatic control through the RpcClient class.
Prime Agent from PrimeIntellect-ai/prime-agent supports a Remote Procedure Call (RPC) mode that transforms the agent into a headless service controllable via standard input and output streams. This architecture enables seamless integration with web servers, CI pipelines, microservices, and custom automation scripts without requiring a terminal user interface. By leveraging the RPC mode components, you can send commands, receive streaming events, and handle extension UI requests through a typed, event-driven API.
Understanding the RPC Architecture
The RPC implementation relies on a JSON-Lines protocol where each message is a single JSON object terminated by a newline. The architecture separates concerns between the client driver, the agent runtime, and UI bridging capabilities.
RpcClient
The RpcClient class, located in packages/coding-agent/src/modes/rpc/rpc-client.ts, serves as the primary interface for external systems. It spawns the agent process with the --mode rpc argument and manages the full lifecycle of the connection. The client handles request-response correlation, event subscription routing, and clean shutdown sequences.
RpcMode
RpcMode (implemented in packages/coding-agent/src/modes/rpc/rpc-mode.ts via the runRpcMode function) represents the agent-side execution loop. This component reads JSON-Lines from stdin, executes received commands, and writes responses or extension UI requests back to stdout. It also forwards internal agent events such as session_event and extension_error to the client.
RpcExtensionUiBridge
When running headless, the RpcExtensionUiBridge (found in packages/coding-agent/src/modes/rpc/rpc-extension-ui-context.ts) provides a minimal UI context that satisfies extension requests for dialogs and notifications. Responses are serialized as JSON-Lines and sent back through the communication channel, allowing programmatic handling of user interface interactions.
JSONL Helper
The jsonl.ts file in packages/coding-agent/src/modes/rpc/jsonl.ts provides utility functions attachJsonlLineReader and serializeJsonLine that handle the low-level newline-delimited JSON serialization and parsing required by the protocol.
How RPC Communication Works
Process Launch
The integration begins when RpcClient.start() spawns a Node.js process executing dist/cli.js with the arguments --mode rpc along with any provider or model configuration overrides.
Message Flow
Communication follows a strict request-response pattern:
- The client writes an
RpcCommand(such as{type:"prompt",message:"Hello"}) to the child process's stdin usingserializeJsonLine - The agent reads the line, executes the command, and emits either an
RpcResponseor anRpcExtensionUIRequest - Agent events including
session_eventandextension_errorare wrapped as JSON-Lines and streamed upstream
Request Correlation
Each outbound command receives a unique id identifier. The client stores a promise in an internal pendingRequests map and resolves it when the matching response arrives, enabling asynchronous request tracking.
Extension UI Handling
When the agent requires UI interaction (such as selection dialogs or confirmations), the bridge creates a temporary promise that resolves with an RpcExtensionUIResponse. In pure RPC deployments, you can supply default values or implement custom UI handlers to respond programmatically.
Graceful Shutdown
Calling RpcClient.stop() closes the JSONL reader, terminates the child process, and clears all pending request state, ensuring clean resource cleanup.
Implementation Examples
Basic RPC Client Setup
To integrate Prime Agent into your application, instantiate the RpcClient and subscribe to streaming events:
import { RpcClient } from "prime-agent/src/modes/rpc/rpc-client.js";
async function demo() {
const client = new RpcClient({
provider: "openai",
model: "gpt-4o"
});
await client.start();
// Listen for streaming events (agent_start, tool_call, finish)
const unsub = client.onEvent((ev) => console.log("EVENT:", ev));
// Send a prompt command
await client.prompt("Explain quantum entanglement in one sentence.");
// Cleanup
await client.stop();
unsub();
}
demo().catch(console.error);
Capturing Agent Responses
To receive the final result directly rather than through event streaming:
import { RpcClient } from "prime-agent/src/modes/rpc/rpc-client.js";
async function askAndGetResult() {
const client = new RpcClient();
await client.start();
const respPromise = new Promise((resolve) => {
client.onEvent((ev) => {
if (ev.type === "agent_finish") resolve(ev);
});
});
await client.prompt("What is the capital of France?");
const result = await respPromise;
console.log("Answer:", result.data?.message);
await client.stop();
}
In-Process Integration
For scenarios requiring tighter coupling without process isolation, embed the RPC handler directly using an existing AgentSessionRuntime:
import { runRpcModeWithConnection } from "prime-agent/src/modes/rpc/rpc-mode.js";
import { InProcessAgentConnection } from "prime-agent/src/modes/agent-connection/in-process-agent-connection.js";
import { AgentSessionRuntime } from "prime-agent/src/core/agent-session-runtime.js";
async function embedRpc() {
const runtime = new AgentSessionRuntime(/* configuration */);
const connection = new InProcessAgentConnection(runtime);
// This call runs the RPC loop indefinitely
await runRpcModeWithConnection(connection);
}
Handling UI Dialogs Programmatically
When extensions request user interface interactions, respond programmatically using the client methods:
import { RpcClient } from "prime-agent/src/modes/rpc/rpc-client.js";
async function automatedSelect() {
const client = new RpcClient();
await client.start();
// Intercept UI requests and provide automated responses
client.onObservedSessionEvent((ev) => {
if (ev.type === "extension_ui_request" && ev.method === "select") {
client.respondToExtensionUiRequest(ev.id, { value: "option-2" });
}
});
// Continue with normal operation
await client.prompt("Select the best option from the list.");
}
Summary
- Prime Agent's RPC mode enables headless operation via JSON-Lines over stdin/stdout, eliminating the need for terminal UI interaction
- The RpcClient class manages process lifecycle and provides typed methods for sending commands and subscribing to events
- Request correlation uses unique identifiers to match responses with outbound commands in asynchronous workflows
- RpcExtensionUiBridge allows programmatic handling of extension UI requests when running without a graphical interface
- In-process embedding via
runRpcModeWithConnectionsupports scenarios requiring tighter integration than separate process spawning - All RPC communication relies on the JSON-Lines protocol implemented in
jsonl.tsfor reliable message framing
Frequently Asked Questions
What is RPC mode in Prime Agent?
RPC mode is a headless operational mode where Prime Agent runs as a child process accepting JSON-Lines commands via stdin and emitting responses and events via stdout. According to the PrimeIntellect-ai/prime-agent source code, this mode is activated by passing the --mode rpc argument to the CLI, enabling programmatic integration without graphical user interface dependencies.
How does Prime Agent handle UI interactions in headless mode?
When extensions require user input (such as confirmation dialogs or selection menus), the RpcExtensionUiBridge creates a pending promise that awaits a programmatic response. The client receives an extension_ui_request event through the JSON-Lines stream and can resolve the interaction by calling respondToExtensionUiRequest() with the appropriate response ID and data, allowing fully automated operation of otherwise interactive features.
Can I run Prime Agent RPC without spawning a separate process?
Yes. While the standard approach uses RpcClient.start() to spawn a subprocess, you can embed the RPC handler directly in your application using runRpcModeWithConnection() from packages/coding-agent/src/modes/rpc/rpc-mode.ts. This accepts an InProcessAgentConnection wrapping an existing AgentSessionRuntime instance, eliminating process overhead while maintaining the same JSON-Lines communication protocol.
What protocol does Prime Agent use for RPC communication?
Prime Agent uses a JSON-Lines (JSONL) protocol where each message is a single JSON object terminated by a newline character. The serializeJsonLine function in packages/coding-agent/src/modes/rpc/jsonl.ts handles outgoing serialization, while attachJsonlLineReader manages inbound parsing. This format supports streaming events and request-response correlation through standard POSIX streams.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →