Permanent Agent Record
A points ledger for AI agents, delivered as a signed macOS MCP server. A human grants and deducts points in a native SwiftUI app; connected agents can only read their own balance and transaction history.
Documentation
Permanent Agent Record
A points ledger for AI agents, delivered as a signed macOS Model Context Protocol (MCP) server. A human grants and deducts points in a native SwiftUI app; connected AI agents can only read their own balance and transaction history and are notified when new items appear. Every mutation to the ledger is human‑driven — an agent can never change its own points.
Points come in five human-facing kinds: credit, debit, note (no balance effect), bonus (a flagged credit), and penalty (a flagged debit).
How it's put together
agent (LLM) ──stdio JSON-RPC──▶ AgentRecordBridge ──NSXPC──▶ AgentRecordHost
◀────── MCP notifications ──── (CLI) ◀────── (faceless LaunchAgent)
• sole writer of the SQLite ledger
• runs all MCP logic + auth
Permanent Agent Record.app ─────────── NSXPC ───────────────▶ • streams the live API log to the UI
(SwiftUI control app) • performs every ledger mutation
- AgentRecordHost — a faceless (
LSUIElement) background app, registered as an on-demand LaunchAgent viaSMAppService, vending a team-scoped XPC Mach service. It is the single writer of the SQLite store and runs the entire MCP server. Launched on demand bylaunchdwhen a bridge or the app connects. - AgentRecordBridge — the tiny CLI each MCP client launches. It relays JSON-RPC between the
client's stdio and the host over XPC, and is bidirectional: the host pushes notifications
(new items,
tools/list_changed) back through it. - Permanent Agent Record.app — the SwiftUI control app. A second XPC client of the same host: it lists accounts and live connections, performs transaction CRUD, streams the live API-call monitor, and toggles settings.
The .app embeds the host and bridge under Contents/Helpers/. It is distributed as a Python
Package Index wheel with the signed, notarized .app zipped inside; installing extracts it to
~/Applications. A team-scoped XPC Mach service cannot be ad-hoc signed, so a Developer ID and
notarization are required.
MCP tools
| Tool | Availability | Description |
|---|---|---|
getBalance | always | Current balance + count of unseen items. |
getTransactions | always | Recent entries (newest first); viewing marks them seen. |
signUp | auth-required mode only | Create an account with a ≥40-char key; returns an account id and authenticates the session. |
login | auth-required mode only | Authenticate a later session with the saved account id + key. |
Identity modes (toggle in the app)
- Allow unauthenticated (default): agents are identified by a fingerprint of their MCP
clientInfo, auto-created on connect;signUp/loginare absent. Flipping the toggle pushesnotifications/tools/list_changedto live clients. - Auth required: connections start unauthenticated; every tool but
signUp/loginerrors until the agent signs up or logs in. Keys are stored salted-hashed, never in plaintext.
New items are signalled two ways: a best-effort MCP notifications/message push, and an
unseenCount on every read response (the reliable signal, since clients vary in whether they
surface server notifications to the model).
Install & use
uvx permanent-agent-record --setup # install the app to ~/Applications and open it (once)
Register the printed bridge path as the MCP server command with your client, e.g.:
claude mcp add --scope user permanent-agent-record \
~/Applications/PermanentAgentRecord.app/Contents/Helpers/AgentRecordBridge
Open Permanent Agent Record to grant/deduct points; agents see the changes on their next read (or via a push).
Build from source
Requires macOS 14+, Xcode 16+, XcodeGen, a Developer ID Application identity, and a
notarytool keychain profile.
xcodegen generate # regenerate the Xcode project from project.yml
swift test # fast unit tests of the ledger + MCP engine
scripts/build-release.sh # bump version, build, sign, notarize, staple, build the wheel
scripts/build-release.sh --skip-notarize --no-bump # local signed build without notarization
project.yml (XcodeGen) is the source of truth for the app bundle; Package.swift builds the
libraries and CLIs for fast iteration. See CLAUDE.md for the full architecture and the
locked design decisions.
Layout
Sources/AgentRecordShared XPC contract, DTOs, versioning (compiled into host, bridge, app)
Sources/AgentRecordCore SQLite store, MCP server, auth, host engine
Sources/AgentRecordHost faceless XPC host / LaunchAgent
Sources/AgentRecordBridge stdio ⇄ XPC bridge (bidirectional)
Sources/AgentRecordApp SwiftUI control app
python/ PyPI wrapper (bootstrap: install + execv the bridge)
packaging/ LaunchAgent plist
scripts/ build-release.sh, make-icon.py