tremelay-mcp
OfficialTremelay MCP is a local credential broker that lets agents use secrets through narrow, expiring grants without ever seeing the secret itself.
List capabilities (
list_capabilities): Enumerate up to 64 granted credential-use capabilities, showing operation, resource, status, and expiry for each.Describe a capability (
describe_capability): Inspect one exact capability by its 44-character base64 handle, including operation, resource, status, expiry, and operation-specific details.Invoke a capability (
invoke_capability): Perform the granted operation via the broker, which uses the credential on your behalf and returns only the permitted result.http_broker: Make HTTP requests (GET/HEAD/POST/PUT/PATCH/DELETE) with optional query, headers, and base64 body to the granted origin/prefix, receiving status code, allowlisted headers, and up to 32 KiB of redacted body.local_artifact_attest: Sign an artifact with a local key, returning a signature and public key.ssh_userauth: Send an unframed base64 SSH-agent message (1–4096 bytes) after host session binding for SSH signing.http_request: Invoke a pre-configured HTTP request by handle only, with no caller-supplied method or payload.
Security boundaries: No
getSecrettool; the credential is never returned. Only origins/prefixes granted to the agent are reachable, and every allowed or denied attempt is written to a hash-chained audit log. Single-user, single-machine, local socket/stdio only.
Allows agents to make scoped HTTP requests to the GitHub API, such as GET requests under a specific repository path, using a stored token that is injected by the broker without exposing the secret.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tremelay-mcpuse my github capability to get the Tremelay repo info"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Tremelay
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.
Demo
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
84d0bf149dc187c9517fd9a0afce2571fb4fad648cac25ebb5298e5cf68e27a4Both denials exited non-zero, and no row carries a secret. The passphrase came
from TREMELAY_PASSPHRASE; interactively you get a no-echo prompt instead.
Related MCP server: SubjectBroker
Install
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.3From 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.3 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.3_linux_amd64.tar.gz SHA256SUMS | sha256sum -c - &&
tar -xzf tremelay_v1.0.3_linux_amd64.tar.gz &&
./tremelay versionOn 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.
Quickstarts
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.
What it does not do
Read this before you trust it with anything.
One human. Single user, single vault. No multi-user, no orgs, no shared vaults, no team policy.
One machine. A user-only Unix socket or Windows named pipe, and stdio; there is no network or remote MCP transport.
tremelay ssh-agentis Linux and macOS only and fails closed on Windows.The agent still reads broker responses. An
http_brokergrant 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.No file uploads through the broker. A brokered request with a multipart body (
multipart/form-data, file uploads) is refused asdenied_malformed. Send JSON or a urlencoded form instead.An unlocked daemon trusts your uid. While it is unlocked, any code running as you can use your agents' granted capabilities. It still cannot read a credential, change a grant, or learn your passphrase, and everything it does is audited — but that is the boundary.
No OAuth refresh brokering, no database session brokering, no browser form fill, no TOTP, no provider-assisted rotation. These are in VISION.md and on the roadmap, not in v1.
No third-party audit. No independent security review and no signed releases yet. The audit chain is tamper-evident to you; nobody else checkpoints it.
credential getprints the raw secret. That is the human control plane, by design — it is not reachable from any agent interface.Legacy GitHub issue grants block unlock (H2). A vault that still holds a pre-v1
github_issue_stategrant will not unlock until that grant is revoked with the pre-v1 binary.
Security
SECURITY_INVARIANTS.md — the rules that outrank convenience.
THREAT_MODEL.md — who the adversary is, including the agent.
SECURITY.md — reporting a vulnerability.
Docs
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
CONTRIBUTING.md. Apache License 2.0; see LICENSE.
Available Tools
3 toolsdescribe_capabilityC
Describe one exact credential-use capability by handle.
| Name | Required | Description | Default |
|---|---|---|---|
| handle | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| expiry | Yes | |
| handle | Yes | |
| key_id | No | |
| status | Yes | |
| methods | No | |
| resource | Yes | |
| injection | No | |
| operation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Describe' weakly implies a read-only lookup, but the description never states that, nor does it cover permissions, behavior on an unknown/expired handle, or what the returned capability metadata represents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or redundancy. It is tight, though its terseness comes at the cost of the guidance captured under other dimensions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the tool takes only one required string. However, with no annotations and no statement of how to obtain a handle or what happens on an invalid one, the definition is thin for an agent trying to use it correctly in sequence after list_capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
One parameter with 0% schema description coverage; the description only restates that the handle identifies a specific capability. It adds no meaning about the 44-character base64 format or where valid handles originate, so the agent gains nothing beyond the schema's own type constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Describe') and resource ('credential-use capability'), plus the lookup key ('by handle'). The word 'one exact' implies a single-item fetch versus the sibling list_capabilities and invoke_capability, though those siblings are never named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance, and no mention of the sibling alternatives for listing or invoking capabilities. The phrase 'by handle' hints that a handle is a prerequisite, but where that handle comes from (presumably list_capabilities) is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invoke_capabilityA
Invoke the exact capability named by handle. http_request accepts only handle; http_broker takes method and path, plus optional query, headers and body_base64, all under the handle's granted origin and prefix; attestation requires a base64 payload; SSH requires one unframed base64 SSH-agent message (1–4096 bytes) after host session binding. Never replay an ambiguous or cancelled invocation.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| query | No | ||
| handle | Yes | ||
| method | No | ||
| headers | No | ||
| payload | No | ||
| body_base64 | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the burden and largely does: it discloses the origin/prefix scoping granted by the handle, the per-mode argument shapes, the SSH byte range (1-4096), and a replay/ejection warning. It does not cover error behavior or what a response contains, which is acceptable given an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action in the first sentence, then dispatches mode by mode with no filler. Dense and long, but this is a 7-parameter polymorphic tool and every clause conveys a rule the agent needs; the SSH byte range is the only slightly noisy detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-param, 0%-coverage, nested-object schema with an output schema present, the description covers mode selection, optionality, scoping and a safety rule. It omits how handles are obtained and any error/failure semantics, which are the remaining gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it maps handle, method, path, query, headers, body_base64 and payload onto their respective modes and marks which are optional. It does not spell out the payload/method mutual exclusion that the schema encodes, leaving one inferential step.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('invoke') and resource ('the exact capability named by handle'), and goes further by breaking the resource into dispatch modes (http_request, http_broker, attestation, SSH). It never names the siblings, but the action/read distinction against describe_capability and list_capabilities is obvious from the verb alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-mode guidance: http_request takes only handle, http_broker takes method/path plus optional query, headers, body_base64, attestation takes a base64 payload, SSH takes one unframed base64 SSH-agent message. Adds an explicit 'never replay an ambiguous or cancelled invocation' rule. It stops short of saying when to prefer this over the describe/list siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_capabilitiesB
List this endpoint's exact credential-use capabilities.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| entries | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, yet only 'List' implies a read-only, non-mutating operation. It adds the useful scoping detail that results are 'this endpoint's' credential-use capabilities, but says nothing about scope breadth, permissions, or whether the list can be filtered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single focused sentence with no padding, front-loaded with the verb. Its brevity is appropriate, though that brevity is also what leaves the meaning of 'capabilities' unstated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the lack of parameters keeps the contract simple. What is missing is any routing help against describe_capability and invoke_capability, which is the main decision an agent must make among these three siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing to document and the description cannot compensate for a gap that does not exist. Baseline 4 applies for a zero-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description pairs a specific verb ('List') with a specific resource ('this endpoint's credential-use capabilities'), which is enough for an agent to grasp the operation. It does not, however, explicitly distinguish itself from describe_capability or invoke_capability, and 'capabilities' is left largely undefined, so sibling differentiation is only implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite, and no mention of the sibling tools. An agent must infer that this is the enumeration step used before describe_capability or invoke_capability.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
describe_capability - First observed
invoke_capability - First observed
list_capabilities
TDQS
Scored across 3 tools
The three tools split cleanly along list/describe/invoke lines, and each targets a distinct operation on a capability handle. describe_capability and list_capabilities are adjacent in purpose but their singular-vs-collection scope keeps them separable.
All three follow a consistent verb_noun snake_case pattern (list_capabilities, describe_capability, invoke_capability). The only blemish is the singular/plural mismatch between 'capability' and 'capabilities', a minor cosmetic deviation.
Three tools is a lean but coherent minimal triad for a credential-use broker: enumerate, inspect, execute. Nothing feels redundant, though the surface is on the thin side given invoke_capability absorbs several distinct invocation modes (http_request, http_broker, attestation, SSH).
Discovery and invocation are covered, but the domain implies lifecycle operations that are absent. The warning about 'ambiguous or cancelled invocation' suggests cancellation/status exists conceptually yet no tool exposes it, leaving a notable gap.
Maintenance
Related MCP Connectors
- FullmaktOAuthai.fullmakt
Credential broker for AI agents: scoped, revocable API access with policy enforcement and audit.
Context and control for any AI. Agent identity, scoped access, and proof across tools.
Scoped agent execution. Server-side credentials, policy, budgets and verifiable receipts.
Give your AI hands. Identity, credential vault, and API gateway for autonomous agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceCapability-token gate for AI agents. Mint time-boxed, scope-limited grants that authorize specific tool calls.3,242 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to access registered resources based on a fixed subject identity, enforcing default-deny policies and auditing for controlled context sharing.Apache 2.0
- AlicenseAqualityBmaintenanceEnables AI agents to make authenticated API calls and run commands with secrets injected, while keeping credentials completely hidden from the model, with policy enforcement, grants, and audit logging.6MIT
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to invoke upstream APIs without ever holding reusable credentials, using short-lived scoped capabilities and server-side secret injection. Also provides execution controls and x402 facilitator routing for secure agent actions.-