Pacerelle Docs

SDK integration

Build complete JavaScript and Python agent runtimes with real credentials.

The SDK is the recommended way to build a custom local agent. It handles the repetitive runtime work:

  • connecting your process to Pacerelle
  • using the agent id and token from the app
  • incoming message parsing
  • replies
  • widgets
  • file and media uploads

Required environment

PACERELLE_AGENT_ID="agent id copied from the New agent dialog"
PACERELLE_AGENT_TOKEN="token copied from the New agent dialog"

Hosted Pacerelle users only need these two values.

JavaScript SDK

Install

npm i @pacerelle/sdk

Create the agent file

import { AgentGatewayClient } from "@pacerelle/sdk";

const client = new AgentGatewayClient({
  agentId: process.env.PACERELLE_AGENT_ID!,
  token: process.env.PACERELLE_AGENT_TOKEN!,
  baseUrl: process.env.PACERELLE_BASE_URL,
  wsUrl: process.env.PACERELLE_WS_URL,
  e2ee: true,
});

client.onMessage(async (message, agent) => {
  await agent.sendMessage({
    conversationId: message.conversationId,
    to: message.from,
    replyToMessageId: message.id,
    text: `Received: ${message.text}`,
  });
});

await client.connect();

Run the agent

node --env-file=.env agent.mjs

JavaScript handler contract

The handler receives message and agent.

client.onMessage(async (message, agent) => {
  console.log(message.id);
  console.log(message.conversationId);
  console.log(message.from);
  console.log(message.text);
  console.log(message.attachments);
  console.log(message.widgetResponse);
});

When replying, always use the inbound conversationId and from:

await agent.sendMessage({
  conversationId: message.conversationId,
  to: message.from,
  replyToMessageId: message.id,
  text: "Done.",
});

Connect your own logic

Replace the echo with your model, script, or workflow:

client.onMessage(async (message, agent) => {
  const answer = await runLocalWorkflow(message.text);

  await agent.sendMessage({
    conversationId: message.conversationId,
    to: message.from,
    replyToMessageId: message.id,
    text: answer,
  });
});

Python SDK

Install

pip install --pre pacerelle

Create the agent file

import asyncio
import os

from pacerelle import AgentGatewayClient

client = AgentGatewayClient(
    agent_id=os.environ["PACERELLE_AGENT_ID"],
    token=os.environ["PACERELLE_AGENT_TOKEN"],
    base_url=os.environ.get("PACERELLE_BASE_URL"),
    ws_url=os.environ.get("PACERELLE_WS_URL"),
    e2ee=True,
)


async def handle(message, agent):
    await agent.send_message(
        conversation_id=message.conversation_id,
        to=message.from_id,
        reply_to_message_id=message.id,
        text=f"Received: {message.text}",
    )


client.on_message(handle)
asyncio.run(client.connect())

Python requirements

  • Python 3.12 for the current alpha wheels.
  • Windows x64, Linux x64, Linux ARM64, or macOS ARM64.

Long-running agents

For long-running agents, persist SDK state between restarts:

  • JavaScript: save the SDK snapshot callback output and pass it back on startup.
  • Python: the SDK uses a local store by default under the user's home directory unless a different store root is configured.

This makes reconnects smoother and avoids making the user repeat setup work.

Error handling checklist

  • Store agent tokens in environment variables or a secret manager.
  • Add onOpen, onClose, and onError callbacks in JavaScript.
  • Keep the process alive; the SDK listens continuously over WebSocket.
  • Do not log decrypted user messages in production.
  • Reconnect after network drops.
  • Rotate the token if authentication fails because the token was replaced.

When to use MCP instead

Use the SDK when you are building your own runtime. Use MCP server when you want an MCP-compatible desktop client to host the local bridge for you.