Credentials
The CLI stores host bearer tokens in ~/.agentproto/credentials.json, mode 0600, one file per OS user with many hosts inside. Tokens come from agentproto auth login (RFC 8628 device flow) — see [verbs/
Credentials
The CLI stores host bearer tokens in ~/.agentproto/credentials.json,
mode 0600, one file per OS user with many hosts inside. Tokens come
from agentproto auth login (RFC 8628 device flow) — see
verbs/auth.md for the flow itself.
Where
- Path:
$AGENTPROTO_HOME/credentials.json(defaults to~/.agentproto/credentials.json). - File mode:
0600enforced on every write. Skipped on Windows (per-user profile directory is already private). - Never logged. The CLI scrubs token values from any output it produces.
Format
{
"version": 1,
"hosts": {
"wss://guilde.work/api/v1/agentproto/tunnel": {
"token": "eyJ…",
"tokenType": "Bearer",
"expiresAt": "2026-08-08T12:34:56.000Z",
"refreshToken": "rt_…",
"scope": "tunnel:connect",
"subject": "user_abc",
"obtainedAt": "2026-05-10T08:21:11.000Z",
"deviceLabel": "jeremy@laptop",
"revocationId": "jti_…"
}
}
}Full per-field schema in
reference/credentials-format.md.
Per-host keying
Hosts are keyed by the URL you passed to agentproto auth login --host <url>, trailing slash stripped. The same key powers:
agentproto serve --connect <url>— looks up the token when--tokenisn't supplied.- Plugin code reading credentials via
@agentproto/cli/util/credentials— same lookup semantics, so a plugin that talks to its vendor's MCP can reuse the cli's auth store.
The host URL is matched verbatim against the file's keys. If you
logged in to https://example.com but a plugin probes
https://example.com/api/v1, the plugin must walk back to the host
root (or expose a --host flag) — there's no path-stripping done
automatically.
Reading from plugin code
import {
loadCredentials,
normaliseHost,
isExpired,
} from "@agentproto/cli/util/credentials"
const all = await loadCredentials()
const cred = all.hosts[normaliseHost("https://example.com")]
if (cred && !isExpired(cred)) {
// use cred.token
}This is the supported way for plugins to share the auth store. Don't
read ~/.agentproto/credentials.json directly — the format may evolve
across major versions and the helpers track it.
Refresh
Some hosts issue a refreshToken alongside the access token. The CLI
doesn't auto-refresh today — auth status shows whether a credential
is expired, and auth login --host <url> mints a fresh one. A plugin
that needs proactive refresh can use the refreshToken field
according to its host's OAuth flow (RFC 6749 § 6).
Logout
agentproto auth logout --host <url>Removes the host from the file. If the host exposed a revocationId,
the CLI sends it back so the server-side row gets revoked, not just
the local copy.
Adapters
An **agent-CLI adapter** is the npm-installable definition of how to drive a specific CLI agent — claude-code, hermes, opencode, gemini-cli, goose, and whatever your team ships. Adapters declare:
Plugins
A **plugin** extends agentproto run-swarm's runtime registry with new substrates, dispatchers, participant executors, or state stores — the four port kinds the MultiAgentRuntime kernel composes per sw