OctoBus Local Agent Gateway
A locally running single-binary gateway that lets AI agents securely call approved enterprise APIs, tools, and services.
Per-dimension scores and reasoning
Evidence shows localhost default binding, method-level capset exposure (select-method), and per-capset token checks supporting least privilege (2); but capsets are tokenless by default and there is no human-approval workflow for agent calls (1). NDJSON access logs, catalog metadata, and documented data layout give data-flow transparency (2); tokens stored only as hashes, secrets support fd passing, logs exclude bodies/credentials (2). go.mod pins all dependencies, CI includes trace scanning and static-binary checks; no known critical vulns seen (2). External effects contained, but Docker defaults to 0.0.0.0 and remote exposure is the user's responsibility — deducted (2). Instances support stop/restart/delete but no service-package version rollback is documented (1). SECURITY.md provides contact and response window; npm publish uses provenance (2).
README, CI, SDK tests, and examples are mutually consistent; the service/instance/capset model is coherent (2). But operation hard-depends on node/npm/protoc/git and the npm registry — any unavailable link blocks import/run — and Docker vs source paths invite drift (1). SDK tests verify clear error messages for conflicting and missing args (2).
Targets enterprise agent API gateway scenarios with long-running/on-demand modes and calculator examples (2). Boundaries well documented: streaming gRPC-only, on-demand start/stop errors, new methods not auto-exposed (2). MCP tool naming with --mcp-tool conflict handling shows trigger precision (2). Multi-platform npm optional deps, Docker amd64/arm64, --addr/OCTOBUS_ADDR (2).
README well structured: overview, install, workflow, protocols, development, architecture (3). Three install paths plus external dependencies and GOPROXY troubleshooting documented (3). Schema versioning and consistent npm naming (2). Examples and smoke script exist but no FAQ (2). Some limits documented (streaming) but no consolidated known-limitations section (2). Full GPL-3.0 text present (3). Semver tag validation in CI, but no CHANGELOG file (1). SECURITY.md names an owner email and 3-business-day response (2).
Good output usability: same methods callable via gRPC/Connect/MCP, catalog returns per-protocol metadata, OpenAPI endpoints provided (2). The capset model delivers clear marginal value over raw API exposure (2). Single binary + SQLite + optional Docker keeps deployment cost low (2).
README claims (static binary, CI gates, e2e, npm provenance) are traceable to ci.yml and SDK tests (2). README, workflows, and tests corroborate each other (2). README uses hedged wording ('roughly as follows') separating facts from approximations; no inflated claims found (2). No execution was performed in this review; confidence remains low.
- Capsets require no access token by default; add tokens before connecting agents, otherwise Connect RPC/MCP/gRPC/reflection are publicly accessible.
- For remote exposure (--addr 0.0.0.0 or Docker port mapping), network access control is entirely the user's responsibility; place behind an outer TLS proxy and auth.
- This is a static review with no executed runs; output correctness and test reproducibility were not scored.
- Service packages from npm/Git run as local Node subprocesses — only import trusted packages.
- No CHANGELOG file exists; verify tag/commit diffs before upgrading.
What does this agent do, and when should you use it?
OctoBus is a locally running, single-binary gateway (a Go-built `octobus` program) for managing pluggable Node.js service packages and exposing their gRPC capabilities to clients or agents by capset. The daemon listens on `127.0.0.1:9000` by default, multiplexing the local admin API, gRPC, Connect RPC, MCP streamable HTTP, and gRPC reflection through that one port. Its core model has four layers: service (a Node.js package root with service., protos, and a gRPC implementation), instance (a runtime copy with independent config and workdir), capset (a deterministic capability set scoped to an agent or use case), and method binding (the gRPC methods actually exposed within a capset). Service packages default to a long-running mode supervised as resident Node.js gRPC subprocesses, or can declare on-demand mode to spawn a short-lived `invoke` subprocess per request. State is stored in SQLite, and access logs are written as NDJSON to a 0600-permission access.log that excludes request bodies, secrets, and business metadata. The project is GPL-3.0 licensed and deployable via npm, Docker, or source build.
The OctoBus daemon starts a local control plane and data plane, and the octobus CLI manages services, instances, and capsets via the local admin API. On service import (octobus service import calculator ./examples/calculator-js), it fetches and unpacks npm/local-directory/Git/HTTP-archive sources, compiles proto descriptors with protoc, and prepares runtime directories; sources support a //service-dir suffix to select a service root inside a package, and --recursive imports all discovered service roots. After instance create, long-running instances launch resident Node.js gRPC subprocesses with health checks, while on-demand instances spawn a one-shot invoke subprocess per request exchanging protobuf wire format over stdin/stdout. Once a capset is created and an instance attached via capset add-instance, methods are callable over three protocols: gRPC (original method paths, routed via x-octobus-capset/x-octobus-instance metadata, all four streaming kinds), Connect RPC (POST /capsets/{id}/connect/{instance}/{service}/{method}, unary only), and MCP streamable HTTP (POST /capsets/{capset_id}/mcp, default tool names {service}__{instance}__{method}). Capsets manage access tokens via add-token (only validation hashes persisted, never plaintext); without tokens the endpoints are publicly accessible. The companion @chaitin-ai/octobus-sdk handles the --runtime serve/invoke/dev protocol via runServiceMain, OpenAPI endpoints expose per-method schemas, and octobus logs filters access logs by capset/instance/service.
- Platform engineers who need internal AI agents to call APIs like GitLab without handing agents raw system credentials — capsets plus tokens authorize method subsets per agent
- Teams with existing Node.js internal tooling that want a unified gRPC/Connect/MCP interface for diverse clients — wrap the tools as OctoBus service packages and import them
- Developers providing a controlled toolset to MCP clients locally — integrate through the
POST /capsets/{id}/mcpstreamable HTTP endpoint - Security teams requiring audit trails for agent tool calls — access.log records protocol, capset, method, status, duration in NDJSON without sensitive data
- Operators who want infrequent tools to consume no resident resources — declare packages in on-demand mode and spawn one-shot processes per request
- Scenarios needing differently-scoped tool catalogs per agent — use select-method per capset for precise method-level exposure control
What are this agent's strengths and limitations?
- Multi-protocol on a single port: the same
127.0.0.1:9000serves gRPC (all four streaming kinds), Connect RPC, MCP streamable HTTP, OpenAPI, and gRPC reflection, giving clients flexible choices - Capsets provide a deterministic, enumerable capability authorization model; select-method allows method-level control of what each agent can see, and gRPC reflection is capset-scoped (only the descriptor closure of exposed methods)
- Clear security boundaries: local default binding to 127.0.0.1, tokens persisted only as validation hashes, and access logs explicitly exclude bodies, secrets, and business metadata
- On-demand runtime mode supports one-shot process invocation for infrequent or resource-sensitive tools without resident processes
- Strong engineering: official TypeScript SDK (@chaitin-ai/octobus-sdk), complete long-running and on-demand examples, e2e tests, and CI
- Service packages must be Node.js implementations (node/npm dependent); backends in other languages cannot be hosted directly as OctoBus packages
- Normal import flows hard-require node, npm, protoc, and git on PATH, adding setup friction outside the provided Docker image
- By default, gRPC, Connect RPC, MCP, reflection, and OpenAPI under a capset are publicly accessible until tokens are added; binding to 0.0.0.0 shifts network access control entirely to the operator (stated explicitly in the README)
- Streaming methods are gRPC-only and long-running-only — Connect RPC, MCP, and on-demand paths do not support streaming
- Daemon restart restores only enabled long-running instances; on-demand instances do not support start/stop/restart persistent control, requiring adaptation of ops models
How do you install or deploy this agent?
Three options:
- npm (the main package installs a small Node.js launcher and pulls the matching native Go binary via platform-specific optional dependencies):
bash
npm install -g @chaitin-ai/octobus
octobus serveOr without a global install: npx @chaitin-ai/octobus serve
- Docker:
bash
docker run --rm \
-p 9000:9000 \
-v octobus-data:/var/lib/octobus \
ghcr.io/chaitin/octobus:latestThe container listens on 0.0.0.0:9000 and stores state under /var/lib/octobus.
- Build from a checkout (requires Go 1.26.1 and Task):
bash
task build
./bin/octobus serve --data-dir .octobus --addr 127.0.0.1:9000Normal service import and instance startup also require node, npm, protoc, and git on PATH. Defaults can be overridden via OCTOBUS_DATA_DIR and OCTOBUS_ADDR environment variables.
How do you use this agent?
- Start the daemon and verify CLI connectivity:
./bin/octobus status. - Import the example package:
./bin/octobus service import calculator ./examples/calculator-js(sources support local directories, tgz/tar.gz/zip archives,npm:, and HTTPS Git; append//service-dirto pick a service root). - Create and start an instance:
bash
./bin/octobus instance create calculator-test \
--service calculator \
--config- '{"label":"primary"}' \
--secret- '{"apiToken":"dev-token"}'- Create a capset and attach the instance:
bash
./bin/octobus capset create dev --name DevAgent
./bin/octobus capset add-instance dev calculator-test
./bin/octobus catalog dev --all --- Invoke (Connect RPC example):
bash
curl -X POST \
http://127.0.0.1:9000/capsets/dev/connect/calculator-test/calculator.v1.CalculatorService/Add \
-H 'Content-Type: application/' \
-d '{"left":20,"right":22}'MCP: POST /capsets/dev/mcp with JSON-RPC tools/list / tools/call. gRPC via grpcurl with x-octobus-capset/x-octobus-instance metadata. Optional: capset add-token dev local --token-stdin to enable Bearer auth (gRPC/reflection use identically named metadata); octobus logs --follow to stream access logs.
How does this agent compare with similar options?
The README names no direct competitor, but by positioning OctoBus intersects with MCP server frameworks (e.g., FastMCP-style tools): typical MCP servers register tools in-process, whereas OctoBus is a standalone daemon hosting Node.js service packages with capset-based method-level authorization, tokens, access logs, and multi-protocol exposure (gRPC/Connect/MCP) — suited to enterprise tool governance at the cost of requiring Node.js services and accepting the daemon+SQLite runtime model.
FAQ
Are endpoints public when no token is configured?
Authorization: Bearer <token> (gRPC/reflection use identically named metadata). Only validation hashes are persisted, never plaintext tokens.My tool is not written in Node.js — can I use it?
What resources does it use and where is state stored?
.octobus) holds the SQLite database (octobus.db), service artifacts and runtimes, and per-instance config/secrets/logs. On restart, enabled long-running instances are restored from SQLite and their subprocesses relaunched.Is streaming supported?
Is it safe to expose remotely?
--addr 0.0.0.0:9000 or Docker port mapping, the README states that network access control is your responsibility, and clients should use the https://host:port form when TLS is provided by an outer proxy.