Local MCP stdio bridge for cnx — GPU rental negotiation agent (proxies to the live cnx /mcp HTTP endpoint; signs and pays locally via a disposable wallet keystore so the harness/LLM never sees a private key)
Project description
cnx-mcp
A real, installable local MCP stdio server for cnx, the GPU rental negotiation agent. It bridges any MCP-compatible host (Claude Desktop, Claude Code, etc.) to the live cnx backend over stdio, so you can add cnx to a host with one line instead of hand-rolling an HTTP bridge.
This package is a thin protocol bridge, not a reimplementation. On every
tools/list and tools/call request it forwards straight through to the
live cnx /mcp HTTP endpoint
https://ddlcl1en1j.execute-api.us-east-1.amazonaws.com/production/mcp
and reshapes the JSON-RPC response into the MCP types the SDK's stdio
transport expects. There are no hardcoded tool schemas in this package -
list_tools() always reflects whatever the live backend currently serves,
so this bridge can never drift out of sync with the real tool set.
Install & run
Not yet published to PyPI. Once published, any of these will work:
# No install - run directly
uvx cnx-mcp
# Same idea, via pipx
pipx run cnx-mcp
# Install then run
pip install cnx-mcp
cnx-mcp
Until then, run it from a local checkout of this repo:
# From the repo root
pip install -e ./mcp-server
cnx-mcp
# or, without a persistent install, via uv:
uvx --from ./mcp-server cnx-mcp
Configuring an MCP host
Add cnx to your host's MCP server config. For Claude Desktop
(claude_desktop_config.json), once cnx-mcp is published:
{
"mcpServers": {
"cnx": {
"command": "uvx",
"args": ["cnx-mcp"]
}
}
}
Or, if you installed it with pip install cnx-mcp:
{
"mcpServers": {
"cnx": {
"command": "cnx-mcp"
}
}
}
Before publish, point a host at a local checkout instead:
{
"mcpServers": {
"cnx": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/mcp-server", "cnx-mcp"]
}
}
}
Claude Code (.mcp.json or claude mcp add) uses the same
command/args shape.
Pointing at a different backend
By default cnx-mcp talks to the live production endpoint. Override it with
CNX_MCP_BASE_URL - useful for local development or a staging deployment
without needing a new release of this package:
{
"mcpServers": {
"cnx": {
"command": "uvx",
"args": ["cnx-mcp"],
"env": {
"CNX_MCP_BASE_URL": "https://your-staging-endpoint.example.com/mcp"
}
}
}
}
Or from the shell:
CNX_MCP_BASE_URL=http://localhost:3000/mcp cnx-mcp
Available tools
Most of the tool list is discovered dynamically from the live backend on
every tools/list call - this README is not the source of truth for it. As
of this writing the backend serves 5 tools: rent_compute,
negotiate_price, submit_payment, check_rental_status,
report_unreachable. See the main repo's SKILLS.md for the current,
authoritative description of each.
One additional tool, pay_and_confirm, is added locally by this
package - the backend doesn't know about it. See the next section.
Paying without ever handing your private key to the harness
Settling a real rental means signing an x402 EIP-3009 payment
authorization. Doing that with submit_payment directly requires the
calling harness/LLM to hold your private key in its own context, which is
exactly the thing you don't want to hand an autonomous agent.
pay_and_confirm solves this by moving signing into this local process,
outside the harness's reach entirely:
-
One-time setup, at your own terminal (never through the harness):
cnx-mcp init-walletThis generates a fresh, disposable EOA keypair, asks you to set a password (interactively - never as a command argument or tool call), and writes an encrypted keystore to
~/.cnx/keystore.json(override withCNX_WALLET_KEYSTORE_PATH). It prints the new public address - fund that address yourself with only what you intend to spend on rentals. This should be a purpose-built rental wallet, not your main wallet - there is no separate software spend cap, so the funded balance IS the cap:pay_and_confirmwill pay anything up to whatever the wallet actually holds. -
Set
CNX_WALLET_PASSWORDin your own shell or MCP host config before launching the harness - e.g.:{ "mcpServers": { "cnx": { "command": "uvx", "args": ["cnx-mcp"], "env": { "CNX_WALLET_PASSWORD": "your-password" } } } }
-
From here, the harness's normal flow just works: call
rent_computewithmode="execute", then callpay_and_confirmwith the sametask_idright after. This bridge caches the payment requirement it already saw pass through in step one, signs it locally using the unlocked keystore, submits it via the backend's existingsubmit_paymenttool, and returns the receipt - all without the harness ever seeing the requirement's signature material or the key itself.
What this protects against, and what it doesn't: the private key never
enters the LLM/harness's context or token stream - only a task_id
argument crosses that boundary, and pay_and_confirm's schema has no
password/key parameter of any kind. This protects against the LLM (or a
prompt-injected tool result) ever seeing or exfiltrating the key. It does
not protect against a fully compromised host machine - anything with
read access to this process's memory, or to the keystore file plus your
password, can still get the key. Treat the wallet as disposable and fund
it accordingly.
If you'd rather sign payments yourself from a bare terminal instead of via
MCP, see the main repo's scripts/cnx_pay.py, which this tool's signing
path is ported from.
Development
cd mcp-server
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/pytest tests/ -v
Publishing
Publishing to PyPI (uv publish / twine upload) is a deliberate manual
step, not automated by this package or its build tooling. Verify the PyPI
name cnx-mcp is still available and the built package passes review before
publishing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cnx_mcp-0.2.0.tar.gz.
File metadata
- Download URL: cnx_mcp-0.2.0.tar.gz
- Upload date:
- Size: 16.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaf912b516aebb693d279e8c2904741c48d47ec6bf20f64b5ec58ceedd934cda
|
|
| MD5 |
91c117ab9a5c0718b99d113856c2ba89
|
|
| BLAKE2b-256 |
38bc5a49bbce4aa5db6a74e85719e50ff5e1976976a2f261ab0080deb73feb7f
|
File details
Details for the file cnx_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: cnx_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55516b0a6c507a95d0b36835328ec5eb31c66a995354671a629b496538ea4d89
|
|
| MD5 |
f572c4df567021a0d6ac6e54839a5c38
|
|
| BLAKE2b-256 |
b14bc284683628698732d79da766f82ee4aebc7ca165418565e8a1059b11c77b
|