Capability tools¶
Some things an agent wants to do are heavy: turning a Markdown memory node into a polished PDF needs a headless browser, bundled fonts, and the RAM spikes that come with them. Baking that into the core server would bloat the image, drag the API process into browser-lifecycle management, and couple a privacy-sensitive front door to a noisy dependency.
Hadron keeps the core lean instead. hadron-server stays the front
door — identity, access control, decryption, node loading — and
delegates the heavy work to capability tools: small, stateless,
independently-deployed services that each own one provider-specific
concern and expose a narrow HTTP surface.
The model¶
A capability tool is a separate process (its own container) that implements a pure function over its HTTP inputs:
- No database, no keys, no access-control logic. Everything that
needs identity, secrets, or the graph stays in
hadron-server. The tool only ever sees content that the server has already authorized and decrypted. - Stateless. Give it the same input, get the same output. Nothing to migrate, nothing to back up, trivial to scale horizontally or restart.
- Narrow surface. A handful of endpoints that do one job — "turn this document into that document" — plus health/info.
This is the same isolation boundary described in Architecture, pushed one layer out: the core owns the what and who; a capability tool owns a heavy how.
flowchart TD
A[Agent / Portal] -->|GraphQL| S[hadron-server<br/>auth · ACL · decryption · node loading]
S -->|HTTP · Bearer token| T[Capability tool<br/>stateless · no DB · no keys]
T -->|result| S
S -->|response| A
Why split it out¶
- Keep the core image small. Chromium and its fonts never enter the API container.
- Contain the blast radius. A renderer crash, a memory spike, or a zombie browser process stays in the tool, not the front door.
- Open by design. A capability isn't hard-wired into the server. An agent that needs "render this to PDF" picks a tool advertising that capability, the server routes the request, and permission is checked at the server — more than one tool may offer the same capability. The protocol for how a tool advertises what it can do, and how the server routes to it, is still being worked out; the first tool doubles as the place that protocol gets refined.
The first tool: the PDF service¶
hadrontool-pdf is the first capability tool on the platform. It
converts Markdown → PDF (via marked + Puppeteer/Chromium) and
extracts PDF → Markdown text (via a PDF text-layer reader). It holds
no database, no keys, and no access-control logic — exactly the shape
above.
It is deployed internal-only: hadron-server reaches it by service
name inside the private network, and every request carries a shared
bearer token. It is not exposed to the public internet, so you won't
call it directly — but its HTTP contract is documented for operators and
for the server code that does call it. See
PDF service HTTP API.
A worked example — the Portal's Download → PDF on a node:
sequenceDiagram
participant U as Portal (user)
participant S as hadron-server
participant T as hadrontool-pdf
U->>S: Download node as PDF (GraphQL)
S->>S: access control + decryption + load node → Markdown
S->>T: POST /convert/markdown-to-pdf (Bearer token)
T-->>S: PDF bytes (base64)
S-->>U: triggers browser download
The privacy invariant holds throughout: node plaintext only reaches
the tool after hadron-server has done auth and decryption. The tool
renders; it never decides who may read what.
Transport¶
Today capability tools speak HTTP, with the server and tools co-located in the same private network. A platform message bus (NATS) is the planned transport: when it lands, the same pure render/extract functions can be wrapped behind a request/reply subject without touching the rendering core.
What's next¶
- PDF service HTTP API — the
/convertendpoints, auth, request/response shapes. - Architecture — the entity hierarchy the core front door is built around.