custodyops-mcp-python
by TheCodeWulf
README.md
# custodyops-mcp-python
A minimal **Python MCP server** over **Streamable HTTP** using FastAPI + `fastmcp`, ready to deploy on **Render** with HTTPS. It exposes a `ping` tool plus two demo tools (`get_positions`, `list_upcoming_corporate_actions`) you can replace with read‑only adapters to your custody data.
> **Why Streamable HTTP?** It is the recommended transport for **remote/hosted MCP servers**, simplifying bidirectional streaming to a single `POST /mcp` endpoint and making cloud deployment straightforward. See the MCP HTTP quickstart and SDK docs for the canonical patterns.
## Features
- Streamable HTTP endpoint at `POST /mcp`
- **Bearer auth** via `AUTH_TOKEN`
- `/health` endpoint for uptime checks
- Minimal code footprint, easy to extend with more MCP tools
- **One‑click deploy** to Render via `render.yaml`
## Quick start (local)
```bash
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scriptsctivate
pip install -r requirements.txt
export AUTH_TOKEN=devtoken123
export PORT=3000
uvicorn app:app --host 0.0.0.0 --port $PORT
```
Test with cURL:
```bash
# tools/list
curl -s -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -H "Authorization: Bearer devtoken123" -d '{"jsonrpc":"2.0","id":"1","method":"tools/list","params":{}}' | jq
# tools/call ping
curl -s -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -H "Authorization: Bearer devtoken123" -d '{"jsonrpc":"2.0","id":"2","method":"tools/call","params":{"name":"ping","arguments":{}}}' | jq
```
Or run helper script:
```bash
chmod +x scripts/test_locally.sh
AUTH_TOKEN=devtoken123 PORT=3000 ./scripts/test_locally.sh
```
## Deploy to Render (HTTPS)
1. **Fork or push** this repo to your GitHub.
2. In Render: **New → Web Service → Connect repo**.
3. Review settings from `render.yaml` (Python env, free plan). Render auto‑provisions **HTTPS**.
4. Set `AUTH_TOKEN` in Render **Environment** (generated automatically if you use the blueprint).
5. Deploy → your public MCP endpoint is: `https://<your-app>.onrender.com/mcp`.
Test remote:
```bash
APP_URL=https://<your-app>.onrender.com AUTH_TOKEN=<token> ./scripts/test_remote.sh
```
## Using from Claude Desktop (remote MCP)
Add a relay entry to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"custodyops-mcp": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://<your-app>.onrender.com/mcp"],
"env": { "AUTH_TOKEN": "<same-token>" }
}
}
}
```
Restart the app, then ask Claude to list available tools.
## Extend with real custody data
Replace demo tools with read‑only adapters to your data mart or API. Keep responses **small and typed**, and add field provenance where possible.
Example skeleton:
```python
@mcp_tool
def get_positions(account_id: str) -> str:
rows = query_positions(account_id) # your adapter
return json.dumps(rows)
```
## Security notes
- Keep `AUTH_TOKEN` secret; rotate regularly. For enterprise use, move to OAuth/JWT and add per‑account authorization.
- With **HTTP transport**, normal logging is fine, but redact sensitive data and add request IDs.
## License
MIT
This server cannot be deployed