botrelay-mcp
Local stdio MCP server for BotRelay. Cursor (or another MCP client) launches
this process on your machine. It uses the BotRelay Python SDK
(Client(api_key, vault_key, base_url)), calls the BotRelay REST API, and
decrypts ciphertext locally.
The Marketplace plugin that launches this server is botrelay-ai/botrelay-plugin. This package is a local process, not a hosted decryption service.
Architecture
Cursor / agent --stdio JSON-RPC--> botrelay-mcp (this process)
| Authorization: Bearer BOTRELAY_API_KEY
v
BotRelay API (ciphertext only)
|
v
decrypt with BOTRELAY_VAULT_KEY
(never leaves this process)
BOTRELAY_API_KEYandBOTRELAY_VAULT_KEYstay in the local process environment.- The vault key is never sent to staging, production, or any decryption host.
- No Ansible playbook, Docker Compose, or droplet container change is required. The existing Ansible deploy remains responsible only for the BotRelay API (and web UI). This MCP server does not run on the droplet.
Stdout is the MCP protocol. Diagnostics go to stderr. Tools never log secret values or keys.
Customer install (PyPI / PATH)
After release to PyPI, botrelay-mcp installs its matching botrelay SDK
automatically. No BotRelay checkout or MCP config file edit is required. Use
Python 3.11 or newer:
python3 -m venv ~/.venvs/botrelay
source ~/.venvs/botrelay/bin/activate
python -m pip install --upgrade pip
python -m pip install botrelay-mcp
botrelay agent configure
botrelay-mcp 0.1.1 depends on botrelay-cli (>=0.1.0,<0.2), so this
installs the botrelay console script into the same virtualenv. The CLI does
not depend on the MCP server. botrelay-cli is not on PyPI yet; publish
0.1.0 before this 0.1.1 release (commands in
apps/cli/README.md).
botrelay agent configure writes ~/.config/botrelay/agent.env (mode 0600,
or $BOTRELAY_HOME/agent.env). examples/launch.sh
loads that file when BOTRELAY_API_KEY and BOTRELAY_VAULT_KEY are unset.
Environment variables override the file. The MCP process itself still reads
those variables from its environment; it does not open agent.env.
The activated environment puts botrelay-mcp on PATH. The command starts
the local stdio server and is meant to be launched by an MCP client, so it
waits for JSON-RPC on standard input:
botrelay-mcp
Press Ctrl-C to stop a manual smoke run. The server does not contact the API
until a tool is called.
API URL
Point the client at the BotRelay API and keep keys local:
export BOTRELAY_API_URL=https://api.botrelay.ai
export BOTRELAY_API_KEY=brt_live_... # agent token from vault create
export BOTRELAY_VAULT_KEY=... # standard base64 of the 32-byte vault key
Create those values with the CLI (botrelay vault create);
vault_key is printed once and never stored by the API.
Configure an MCP client
Use the installed console script in the client configuration. Keep the
environment above active when the client starts, or otherwise make
botrelay-mcp available on its PATH.
Cursor mcp.json
User-level: ~/.cursor/mcp.json. Project-level: .cursor/mcp.json (do not
commit filled values). The default configuration runs the PyPI console script:
{
"mcpServers": {
"botrelay": {
"command": "botrelay-mcp",
"args": [],
"env": {
"BOTRELAY_API_URL": "https://api.botrelay.ai",
"BOTRELAY_API_KEY": "YOUR_AGENT_TOKEN",
"BOTRELAY_VAULT_KEY": "YOUR_BASE64_VAULT_KEY"
}
}
}
}
Never put real tokens in git.
From source / developers
For local package development, from the monorepo root:
python3 -m venv .venv
source .venv/bin/activate
pip install -e packages/sdk-python -e apps/cli -e apps/mcp
botrelay agent configure
apps/mcp/examples/launch.sh is an optional wrapper around the installed
console script. It loads agent.env when the keys are unset and defaults
BOTRELAY_API_URL to https://api.botrelay.ai.
Tools
There is no safer remote “action” API. The agent contract is metadata listing
plus local decrypt-on-get (Client.secrets.get).
| Tool | Returns |
|---|---|
get_vault |
Vault id, name, labels |
list_secrets |
{ "secrets": [ { id, vault_id, label, secret_type, version } ] } |
get_secret |
Typed secret (Password / ApiKey / Contact as a dict) |
get_secret is sensitive: the plaintext goes to the calling agent. Do not
paste it into logs or chat. Prefer list_secrets when you only need labels.
Security limitations
- The MCP client (and the model context) sees whatever
get_secretreturns. - Keys in
mcp.jsonare as sensitive as the vault. Restrict file mode (0600). - This server does not add step-up MFA (backlog item 4). Do not store high-sensitivity types on staging until that exists.
- Ciphertext listing is stripped; do not treat metadata as authorization.
- The Marketplace plugin is botrelay-ai/botrelay-plugin. This package does not ship a Cursor plugin.
Tests
pip install -e packages/sdk-python -e apps/cli -e apps/mcp
pytest apps/mcp/tests
Release files for botrelay-mcp 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| botrelay_mcp-0.1.1.tar.gz | 15.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| botrelay_mcp-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.9 kB
Release files / botrelay_mcp-0.1.1.tar.gz
| Download URL | botrelay_mcp-0.1.1.tar.gz |
|---|---|
| Size | 15.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
548e33ff0924eef6f5e1fda6fc6eefc76c2eae4409dade6b29d9efe7809f45c0
|
|
BLAKE2b-256 checksum How to use checksums |
b3a309904cccccb705d4fb9e77d5014757b6534c3129db0dfaabef480a1d3841
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / botrelay_mcp-0.1.1-py3-none-any.whl
| Download URL | botrelay_mcp-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0b5f53ee44dc992a68e1ae1440f5748b0d0ca2cfcf5e3589adeae06328f33ee
|
|
BLAKE2b-256 checksum How to use checksums |
6c282e2a2786a2a54a8fa43f814b5321cfbb38f424398854810c1ed6d7efdd47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|