OPPA is the Open Printer Proxy Agent: a lightweight desktop application that connects a cloud application to printers available on a local computer or private network.
OpenPrinter is the generic protocol and server SDK ecosystem used to integrate OPPA into an existing application:
@openprinter/protocol— canonical schemas, codecs, and TypeScript types@openprinter/server— authenticated WebSocket sessions and delivery
OPPA does not contain restaurant, branch, kitchen, billing, tenant, or other integrating-application business concepts. The host application owns authorization policy, durable server-side jobs, retry schedules, and logical printer routing.
flowchart LR
A["Host application<br/>durable queued job"] --> B["@openprinter/server<br/>validated delivery"]
B --> C["OPPA agent<br/>durable local receipt"]
C --> D["Renderer<br/>printer-ready output"]
D --> E["Spooler<br/>local submission"]
C -->|received| A
E -->|submitted or failed| A
The safety-critical ordering is:
receive → validate → persist → acknowledge → render → submit → persist result → report
submitted means a local backend accepted the job. It does not universally prove that paper was
physically printed.
apps/
oppa/ Tauri + React desktop host
www/ Fumadocs landing and documentation site
crates/
oppa-agent/ shell-independent runtime and state machine
oppa-auth/ PKCE pairing and credential lifecycle
oppa-core/ typed IDs, timestamps, and shared domain primitives
oppa-discovery/ provider isolation, normalization, and inventory changes
oppa-platform/ credentials, paths, startup, notifications, identity
oppa-printer/ printer descriptors, fingerprints, capabilities, backends
oppa-product/ compile-time product validation and embedding
oppa-protocol/ Rust OpenPrinter wire types and validation
oppa-renderer/ structured receipt rendering
oppa-spooler/ system queue, raw TCP, and virtual submission
oppa-storage/ SQLite migrations, idempotency, and recovery
oppa-transport/ authenticated WebSocket transport and reconnect state
packages/
protocol/ @openprinter/protocol
server/ @openprinter/server
protocol/
fixtures/ shared cross-language payloads
schema/ generated language-neutral JSON Schema
examples/
node-server/ local development authorization and integration
products/
default/ default open-source product definition
- Node.js 22 or newer
- pnpm 11
- Rust stable with
rustfmtand Clippy - the native prerequisites for Tauri on the target platform
pnpm installRun the development server:
pnpm --filter openprinter-node-example devIn another terminal, launch the desktop agent with the default local product:
OPPA_PRODUCT_DIR=products/default pnpm oppa:devAuthorize the agent, create a virtual printer, and send a test job from the example endpoint. See the Getting Started guide for the complete walkthrough.
Run the documentation site:
pnpm docs:devpnpm build # JavaScript applications/packages and Cargo workspace
pnpm test # Vitest and Rust tests
pnpm lint # ESLint and Clippy
pnpm format # Prettier and rustfmt
pnpm format:check # non-mutating format validation
pnpm typecheck # TypeScript project checks
pnpm protocol:generate # regenerate the canonical JSON SchemaPhysical printers are not required in CI. Renderer, storage, lifecycle, SDK, and compatibility tests use mocks, fixtures, and virtual printers.
import { createOpenPrinterServer } from "@openprinter/server";
const openPrinter = createOpenPrinterServer({
authenticateAgent: async ({ token, request }) => {
const agent = await verifyAgentToken(token, request);
return agent
? {
agentId: agent.id,
metadata: { organizationId: agent.organizationId },
}
: null;
},
onJobReceived({ agent, message }) {
jobs.markReceived(agent.agentId, message.payload.jobId);
},
onJobSubmitted({ agent, message }) {
jobs.markSubmitted(agent.agentId, message.payload.jobId);
},
});
httpServer.on("upgrade", openPrinter.handleUpgrade);The application stores a job before calling sendJob. If an agent is offline, the SDK returns a
structured unavailable result and the application retains the queued job.
Product configuration is versioned, validated, and embedded at compile time:
OPPA_PRODUCT_DIR=products/default pnpm oppa:buildA product definition controls branding, application identity, the provider-registered OAuth client
ID, authorization/token/gateway endpoints, support links, update endpoint, and supported feature
switches. It cannot enable a capability that was not compiled into the binary, and OPPA never
trusts an editable runtime product.json.
OPPA is a privileged local bridge and deliberately exposes a narrow command surface:
- documented protocol messages only
- no arbitrary shell, script, filesystem, SQL, or generic proxy commands
- bounded messages, documents, images, queues, and diagnostic history
- loopback-only PKCE authorization callback with validated state
- credentials stored through operating-system secure storage, never SQLite
- production
https:andwss:product endpoints - explicit printer and network timeouts
- sanitized diagnostics without tokens or full print payloads
See the security documentation before deploying an agent gateway.
Read AGENTS.md and the scoped guidance in the workspace unit you are changing. Use
conventional commits, update public documentation with API behavior, and run:
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm buildSee CONTRIBUTING.md for the contribution workflow.
Git Cliff groups conventional commits into a root CHANGELOG.md:
pnpm changelog:unreleased
pnpm changelogThe detailed process is documented in the release guide.
OPPA and OpenPrinter are available under the MIT License.