Summary
Introduce a client-server model for 2keychains. A long-running server daemon manages secrets, handles Discord approval, tracks grants with TTL, and exposes a local HTTP API. The CLI becomes a thin client that communicates with the server. A configuration file (~/.2kc/config.json) determines the operating mode: standalone (current local-only behavior) or client (connects to a remote server).
Motivation
The current design assumes all operations happen in-process within the CLI. A client-server split enables:
- Persistent state: The server daemon can maintain in-memory grant tracking, Discord bot connections, and secret store caches across CLI invocations
- Multi-agent support: Multiple AI agents (or CLI sessions) can share a single approval server
- Remote operation: The server can run on a different machine or in a container
- Backwards compatibility: Standalone mode preserves the current local-only behavior for simple setups
Architecture
┌──────────────────┐
┌─────────────┐ HTTP/JSON │ 2kc server │
│ 2kc CLI │ ◄────────────────────► │ (daemon) │
│ (client) │ Bearer token auth │ │
└─────────────┘ │ SecretStore │
│ GrantManager │
┌─────────────┐ │ Workflow │
│ 2kc CLI │ standalone mode │ Discord │
│ (standalone)│ (direct, no server) └──────────────────┘
└─────────────┘
Key Design Decisions
- Transport: HTTP/JSON via Fastify (lightweight, TypeScript-native, good DX)
- Auth: Bearer token (shared secret in config) -- sufficient for local/trusted network
- Daemon: PID file +
child_process.fork for backgrounding
- Mode abstraction: Service interface pattern -- commands call an interface that has both
LocalService (standalone) and RemoteService (client) implementations
- Config:
~/.2kc/config.json with defaults that preserve standalone behavior
Relationship to Other Issues
Child Issues
See child issues below for the implementation breakdown.
Summary
Introduce a client-server model for 2keychains. A long-running server daemon manages secrets, handles Discord approval, tracks grants with TTL, and exposes a local HTTP API. The CLI becomes a thin client that communicates with the server. A configuration file (
~/.2kc/config.json) determines the operating mode:standalone(current local-only behavior) orclient(connects to a remote server).Motivation
The current design assumes all operations happen in-process within the CLI. A client-server split enables:
Architecture
Key Design Decisions
child_process.forkfor backgroundingLocalService(standalone) andRemoteService(client) implementations~/.2kc/config.jsonwith defaults that preserve standalone behaviorRelationship to Other Issues
Child Issues
See child issues below for the implementation breakdown.