@spmos/local-proxy
v0.1.2
Published
Loopback-only SPM memory and compression proxy with local provider credentials
Maintainers
Readme
SPM Local Proxy
SPM Local Proxy is a standalone terminal application that keeps the upstream provider credential on the user's machine while using hosted SPM memory and deterministic context compression.
Codex / Claude Code / SDK
|
| local harness token
v
http://127.0.0.1:8765/v1
|
+-- SPM key ------> api.spmos.ai memory
|
+-- provider key -> configured provider Base URLThe proxy owns only the provider Base URL, provider API key, SPM key, and local
listener authentication. It does not select, validate, cache, or rewrite a
model. Downstream harnesses can call GET /v1/models through the proxy and
send their selected model unchanged in Chat Completions, Responses, or
Anthropic Messages requests.
Install
npm install --global @spmos/local-proxy
spmThe first run opens an English-only terminal wizard with blue SPM ASCII art.
Provider search is derived from the models.dev models.json dataset delivered
through jsDelivr, so it remains reachable in environments where models.dev
cannot be fetched directly. Catalog model counts are discovery metadata only;
model selection is never written to Local Proxy configuration.
Commands
spm setup
spm start
spm catalog --refresh
spm config
spm config path
spm config token
spm doctor
spm print-config codex
spm print-config claudeBYO provider configuration
The Custom BYO flow accepts:
- HTTPS Base URL
- OpenAI-compatible or Anthropic Messages wire API
- bearer,
x-api-key, orapi-keyauthentication - API key
- custom headers as JSON
- query parameters as JSON
Use the literal value $API_KEY in a custom header or query parameter when the
provider requires its secret outside the standard authentication header.
Secret handling
The configuration is written atomically to
$SPM_CONFIG_HOME/local-proxy.json, $XDG_CONFIG_HOME/spm/local-proxy.json, or
~/.config/spm/local-proxy.json, with mode 0600 where supported. Secrets are
masked by spm config and request/response bodies are never logged.
The following environment variables override stored secrets:
SPM_API_KEY
SPM_LOCAL_PROVIDER_API_KEY
SPM_LOCAL_PROXY_TOKENFor the strongest process boundary, run the proxy in a dedicated shell or user service and remove the provider/SPM keys from the downstream harness process.
Protocol and security behavior
- Listener binds only to
127.0.0.1,::1, orlocalhost. - Browser
Originrequests and unexpectedHostvalues are rejected. - Provider endpoints must use HTTPS and resolve only to public addresses.
- Client, edge, cookie, and SPM headers are removed before provider egress.
- OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages are supported.
- Codex zstd request bodies are decoded locally.
- Provider JSON response bytes and SSE chunks are relayed without reserialization.
previous_response_idrequests bypass recall mutation and compression.- If hosted recall fails, the complete original request is forwarded unchanged.
SPM still receives recall queries and memory content. This package keeps the provider credential local; it is not an offline or zero-disclosure memory mode.
Continuity and capture hygiene in 0.1.1
Version 0.1.1 adds a stricter continuity contract:
- keep the two most recent eligible complete exchanges;
- remove older history only when recall returns
status=recalled,gate_reason=passed, and evidence from the exact removal set; - preserve the full request on empty, degraded, unrelated, protected-context, or provider-managed recall paths;
- emit
x-spm-continuity-statewith the commit or safe-bypass reason; - transport
source_kindandrole_spansto hosted ingest while retaining a stable identity for exact repeated content.
The same release narrows streamed assistant capture to visible Chat content,
Responses output_text, and Anthropic text_delta. Reasoning/thinking, tool
arguments, signatures, and partial JSON are not sent to memory. These changes
are covered by the repository's 32-test Local Proxy suite. The continuity gate
also recognizes deterministic input identities created by 0.1.0, so an
upgrade does not require old content to be re-ingested before it can prove
continuity.
Tool-output elision in 0.1.2
Version 0.1.2 ports the hosted gateway's tool-output elision to the local
path, across all three protocols (Chat Completions tool messages, Responses
function_call_output, Anthropic tool_result blocks):
- tool outputs older than
proxy.elisionKeepRoundsassistant rounds (default 4) become candidates; - a candidate is replaced by a bounded stub only when the identical content is already persisted in hosted SPM and extraction-ready (readiness is checked per request through the memory status tool); otherwise the full output is kept and captured in the background so a later turn can elide it;
- Anthropic
tool_use/tool_resultpairing is never broken: only the block content is stubbed, and blocks carryingcache_controlbreakpoints are never touched; - responses carry
x-spm-elided-items/x-spm-elided-tokens, andx-spm-continuity-statereportselided_tool_outputwhen a request was served with stubs.
Configuration (all optional):
proxy.elisionEnabled(defaulttrue);proxy.elisionKeepRounds(default4);proxy.elisionCaptureLimit(default8, bounds background capture work per request).
Elision is best-effort: any readiness-check or capture failure leaves the request body untouched.
