Local MCP broker: agents call credentials through a daemon without seeing secrets.
Runs on your machine from its package; the steps are below.
At most: moves money, runs code or commands, deletes data, or sends messages for you.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_linux_amd64.mcpb`) — download it and import the bundle in your MCP client.
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_linux_arm64.mcpb`) — download it and import the bundle in your MCP client.
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_darwin_amd64.mcpb`) — download it and import the bundle in your MCP client.
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_darwin_arm64.mcpb`) — download it and import the bundle in your MCP client.
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_windows_amd64.mcpb`) — download it and import the bundle in your MCP client.
Distributed as an MCP bundle (`https://github.com/CharitonMedia/Tremelay/releases/download/v1.0.2/tremelay-mcp_v1.0.2_windows_arm64.mcpb`) — download it and import the bundle in your MCP client.
A local credential broker, so your AI agents can use your credentials without ever seeing them.
You already give agents real authority: read these issues, push this branch, call that API. Today that means pasting a token into a config file, an environment variable, or an MCP server, and hoping nothing logs it, echoes it, or wanders off to the wrong host with it.
Tremelay splits possession of a secret from authority to use it. You keep
credentials in a local encrypted vault. Each agent gets its own identity and its own
narrow, expiring, revocable grants — "GET anything under
https://api.github.com/repos/you/yourrepo with this token", "authenticate to
git.example.com as git with this SSH key". The agent asks Tremelay to perform
the operation; Tremelay performs it with the credential and returns only the result
the grant allows. The agent never receives the secret, there is no getSecret tool
to call, and every attempt — allowed or denied — lands in a hash-chained audit log.
The broker possesses secrets. Agents possess capabilities.
Agents connect over MCP (list_capabilities, describe_capability,
invoke_capability), or over an ssh-agent socket for SSH signing. Everything is
local: one SQLite vault file, one user-only socket or named pipe, no server, no account, no telemetry.
A real session against a throwaway vault. The secret is the literal string
dummy-demo-secret. Every command except vault create also writes one
vault_unlock id=… result=allowed line to stderr; those are trimmed here,
nothing else is.
$ tremelay vault create --path demo.db
vault_create id=d8df6f8230cf55a9a8b1b7c7df424f1a result=allowed
vault created
$ CRED=$(tremelay credential put --path demo.db --label "demo api key" --type api_key --secret-file ./secret)
credential_put id=649cee93880ae731b17ea858a439d7fe type=api_key result=allowed reasons=
health_assess id=649cee93880ae731b17ea858a439d7fe type=api_key result=allowed reasons=
649cee93880ae731b17ea858a439d7fe
$ AGENT=$(tremelay agent create --path demo.db --label claude-code)
agent_create agent=3a0f2de100565eb2e4be158fdb9a8201 grant= result=allowed
3a0f2de100565eb2e4be158fdb9a8201
$ GRANT=$(tremelay grant create --path demo.db --agent $AGENT --credential $CRED \
--operation http_broker --resource https://api.github.com/repos/CharitonMedia/Tremelay \
--method GET --inject bearer --expires 2030-01-01T00:00:00Z)
grant_create agent=3a0f2de100565eb2e4be158fdb9a8201 grant=a0f8b04d64d8ece4a56130feb2607ce9 result=allowed
a0f8b04d64d8ece4a56130feb2607ce9
$ tremelay capability list --path demo.db --agent $AGENT
capability_list agent=3a0f2de100565eb2e4be158fdb9a8201 grant= result=allowed
{"grant_id":"a0f8b04d64d8ece4a56130feb2607ce9","agent_id":"3a0f2de100565eb2e4be158fdb9a8201","credential_id":"649cee93880ae731b17ea858a439d7fe","operations":["http_broker"],"resource":"https://api.github.com/repos/CharitonMedia/Tremelay","created_at":"2026-10-14T04:20:00.618845291Z","expires_at":"2030-01-01T00:00:00Z","status":"active"}
$ tremelay capability authorize --path demo.db --agent $AGENT --credential $CRED \
--operation http_broker --resource https://api.github.com/repos/CharitonMedia/Tremelay
capability_authorize agent=3a0f2de100565eb2e4be158fdb9a8201 grant=a0f8b04d64d8ece4a56130feb2607ce9 result=allowed
allowed a0f8b04d64d8ece4a56130feb2607ce9
$ tremelay capability authorize --path demo.db --agent $AGENT --credential $CRED \
--operation http_broker --resource https://api.github.com/repos/someone/else
capability_authorize agent=3a0f2de100565eb2e4be158fdb9a8201 grant=a0f8b04d64d8ece4a56130feb2607ce9 result=denied_scope
denied_scope
$ tremelay grant revoke --path demo.db --id $GRANT
grant_revoke agent=3a0f2de100565eb2e4be158fdb9a8201 grant=a0f8b04d64d8ece4a56130feb2607ce9 result=allowed
a0f8b04d64d8ece4a56130feb2607ce9
$ tremelay capability authorize --path demo.db --agent $AGENT --credential $CRED \
--operation http_broker --resource https://api.github.com/repos/CharitonMedia/Tremelay
capability_authorize agent=3a0f2de100565eb2e4be158fdb9a8201 grant=a0f8b04d64d8ece4a56130feb2607ce9 result=denied_revoked
denied_revoked
$ tremelay audit list --path demo.db --agent $AGENT --action capability_authorize
{"seq":12,"time":"2026-10-14T04:20:00.755379639Z","action":"capability_authorize","credential_id":"649cee93880ae731b17ea858a439d7fe","credential_type":"api_key","result":"allowed","agent_id":"3a0f2de100565eb2e4be158fdb9a8201","grant_id":"a0f8b04d64d8ece4a56130feb2607ce9","operation":"http_broker","class":"routine","severity":"info","hash":"bcf38c87bf3038dafc6f1b0c52be3cb6b213cd202096d481370373e3abf847ab"}
{"seq":14,"time":"2026-10-14T04:20:00.821094153Z","action":"capability_authorize","credential_id":"649cee93880ae731b17ea858a439d7fe","credential_type":"api_key","result":"denied_scope","agent_id":"3a0f2de100565eb2e4be158fdb9a8201","grant_id":"a0f8b04d64d8ece4a56130feb2607ce9","operation":"http_broker","class":"expected_denial","severity":"low","hash":"2d2432203b7bbacf562c4f0433090f0647037d746e6d689492c44f25e3b2d2b1"}
{"seq":18,"time":"2026-10-14T04:20:00.951247858Z","action":"capability_authorize","credential_id":"649cee93880ae731b17ea858a439d7fe","credential_type":"api_key","result":"denied_revoked","agent_id":"3a0f2de100565eb2e4be158fdb9a8201","grant_id":"a0f8b04d64d8ece4a56130feb2607ce9","operation":"http_broker","class":"replay","severity":"high","hash":"f8b19ee681e76b1b6fc813116232e732e57644d47ebd3afbefab0a8e23ce2cf1"}
$ tremelay audit verify --path demo.db
84d0bf149dc187c9517fd9a0afce2571fb4fad648cac25ebb5298e5cf68e27a4
Both denials exited non-zero, and no row carries a secret. The passphrase came
from TREMELAY_PASSPHRASE; interactively you get a no-echo prompt instead.
Tremelay needs the pinned Go toolchain (1.26.9, see go.mod); go install
switches to it for you.
go install github.com/CharitonMedia/Tremelay/cmd/tremelay@v1.0.2
From a clone, make build or go build -o tremelay ./cmd/tremelay does the same
thing. Check the build with tremelay version (or tremelay --version).
The v1.0.2 release
carries per-platform archives named tremelay_<version>_<os>_<arch>.tar.gz (or
.zip on Windows). Each archive unpacks to a binary named tremelay
(tremelay.exe on Windows) plus LICENSE, along with a CycloneDX SBOM and a
SHA256SUMS file — a checksum detects a corrupt download, not a substituted
release. It also carries one MCP Bundle per platform,
tremelay-mcp_<version>_<os>_<arch>.mcpb, for clients that install MCP Bundles
(see the generic MCP quickstart).
Signed releases are not in v1. make release-dry builds those artifacts
locally; see ADR 0027. Download the archive
you want and SHA256SUMS into one directory, then check that archive by name:
grep tremelay_v1.0.2_linux_amd64.tar.gz SHA256SUMS | sha256sum -c - &&
tar -xzf tremelay_v1.0.2_linux_amd64.tar.gz &&
./tremelay version
On macOS, shasum -a 256 -c - in place of sha256sum -c -.
Name the file you downloaded. sha256sum -c --ignore-missing SHA256SUMS over
the whole list exits 0 when your archive is the one that failed to download
and some other listed file is present.
Copy-paste setup from install to first successful call, one page per client: docs/quickstarts/ (Claude Code, Codex, Hermes, generic MCP).
The shape is the same everywhere. tremelay daemon --vault PATH prompts for
your passphrase at a terminal (non-empty TREMELAY_PASSPHRASE works without a
prompt but is not recommended; see passphrase from the
environment) and then
serves agents on a user-only local socket; tremelay agent create --token-file FILE gives each agent its own bearer
token file, and tremelay agent token issue|rotate|revoke manage it later without
recreating the agent; tremelay mcp --daemon --token-file FILE is the stdio command the
client launches. tremelay lock, the idle timeout, or losing the process
zeroises the key. See the headless daemon guide, or
local stdio MCP for the per-launch pinentry path
instead. For SSH, tremelay ssh-agent publishes an
SSH_AUTH_SOCK that signs with a key that never leaves the daemon.
Read this before you trust it with anything.
tremelay ssh-agent is Linux and
macOS only and fails closed on Windows.http_broker grant returns the
status code, an allowlisted set of response headers, and up to 32 KiB of the
body with the credential redacted in its common encodings (raw, URL, base64,
hex, JSON-escaped). The agent never sees the credential, but it does see the
data that credential unlocks — and anything in that body can be prompt
injection (H1). A hostile upstream that deliberately re-encodes or splits the
credential is not caught; grant only origins you trust with the credential.credential get prints the raw secret. That is the human control plane, by
design — it is not reachable from any agent interface.github_issue_state grant will not unlock until that grant is revoked
with the pre-v1 binary.ARCHITECTURE.md · VISION.md · ADRs · vault lifecycle · HTTP broker · SSH signing · measured client integrations · what is in v1 · milestone history
tremelay --help prints the full command list.
CONTRIBUTING.md. Apache License 2.0; see LICENSE.