mcp-server
by nanceeyngo
README.md
# Thinking Agent — Stage 6: True Cosine CRAG & Bidirectional x402 Monetization
Stage 6 replaces Stage 4's keyword-scored CRAG with true cosine-similarity retrieval, adds an
Algorithmic FinOps governance layer that halts runaway multi-step LLM chains before they exceed a
budget ceiling, and wires bidirectional x402 stablecoin monetization into both the MCP server
(paywalled tools) and the agent client (a reciprocal shield for its own LLM cycles).
This README reflects what actually worked, end to end, after a long empirical debugging pass
against the live Xpay Staging Gateway — not just the intended design. Where the real facilitator's
behavior differed from its own documentation, that's called out explicitly, because it mattered.
---
## 1. Prerequisites
- Everything from Stage 5 (Supabase, Redis, `uv`) still applies and is unchanged.
- A **fresh, disposable testnet-only wallet** — see §3.
- Test USDC on Base Sepolia from the Circle faucet — see §3.
- `eth-account` and `httpx` installed in `agent_client`; `httpx` in `mcp_server`; `redis` in
`mcp_server` (new in this stage, for cross-process FinOps telemetry — previously `mcp_server` had
zero Redis/DB dependency by design, since it holds no LLM or cache of its own).
```bash
uv add --package agent-client eth-account httpx
uv add --package mcp-server httpx redis
uv lock
uv sync
```
## 2. Apply the code changes
This delivery is a set of new modules plus precise patches against the existing Stage 5 files —
see `INTEGRATION_STAGE6.md` for the exact diffs against `server.py`, `client.py`, and `app.py`. New
standalone files (drop in as-is):
```
mcp_server/src/mcp_server/x402_middleware.py
mcp_server/src/mcp_server/cosine_crag.py
mcp_server/src/mcp_server/finops_governance.py
agent_client/src/agent_client/wallet.py
agent_client/src/agent_client/x402_client.py
agent_client/src/agent_client/finops_governance.py
analysis_dashboard/src/analysis_dashboard/finops_tools.py
```
## 3. Generate and fund a wallet
A wallet is not something any service issues you — it's a private/public key pair you generate
locally, with no signup required:
```bash
uv run --package agent-client python -c "from eth_account import Account; a = Account.create(); print('WALLET_PRIVATE_KEY=' + a.key.hex()); print('WALLET_ADDRESS=' + a.address)"
```
Paste both lines into `.env`. Then fund the **address** (never the private key — nobody but you
should ever see that) at **https://faucet.circle.com/**, selecting Base Sepolia. Confirm it landed
at `https://sepolia.basescan.org/address/<your address>` before running anything — every x402
error this stage's debugging log walks through, right up until the very last one, turned out to be
a real, fixable bug; the wallet needing funds was the one genuinely external precondition.
## 4. Configure `.env`
Append everything in `.env.stage6.additions` to your existing `.env`. Fields worth understanding
rather than blindly copying:
| Variable | What it actually controls |
|---|---|
| `WALLET_PRIVATE_KEY` / `WALLET_ADDRESS` | Your generated wallet (§3) |
| `X402_SERVER_WALLET` | A **separate** wallet the server gets paid to — must differ from your payer wallet for a meaningful settlement, and must be a real address, not left blank (an empty `payTo` will crash the signer) |
| `USDC_CONTRACT_ADDRESS` | The token contract (`0x036CbD53842c5426634e7929541eC2318f3dCF7e`) — **not** a wallet address; mixing these up produces a nonsensical `asset` field in the 402 challenge |
| `X402_NETWORK_NAME` | `base-sepolia` — the facilitator's own `/supported` endpoint (`curl https://facilitator.xpay.sh/supported`) confirms this plain-string form is what's registered for x402 v1, while the CAIP-2 form (`eip155:84532`) is registered separately under v2. Mixing versions and network-string conventions produces "no facilitator registered" |
| `X402_DOMAIN_NAME` / `X402_DOMAIN_VERSION` | The EIP-712 domain fields for the USDC contract, carried in `paymentRequirements.extra` (**not** in the signed payload itself — see REFLECTION_STAGE6.md §2 for why the facilitator needs them there specifically) |
| `X402_SHIELD_SAMPLING_ENABLED` | Leave `false` for the integrated demo. See the docstring on `X402Settings.x402_shield_sampling_enabled` in `x402_client.py` — enabling it makes the client reciprocally 402-challenge its *own* already-paid mcp_server's internal sampling calls, which breaks the reflection loop since the server has no mechanism to pay a second, nested challenge |
| `FINOPS_MAX_USD_PER_CHAIN` | `0.05` by default, matching the task spec's example ceiling |
| `COSINE_SIMILARITY_THRESHOLD` | `0.35` — tune based on your own retrieval corpus, not a credential |
## 5. Run (same three terminals as before)
```bash
# Terminal 1
uv run --package mcp-server start-server
# Terminal 2
uv run --package agent-client start-agent
# Terminal 3
uv run --package analysis-dashboard streamlit run analysis_dashboard/src/analysis_dashboard/app.py
```
## 6. What a fully working run looks like
```
[X402][LEDGER] challenge_received | ...
[X402] Signed transferWithAuthorization | from=0x... to=0x...
[X402][LEDGER] facilitator_verify | verified: True
[SERVER] Reflection tool invoked...
[SERVER] Running CRITIC pass 1/2 ...
[CLIENT] MCP Sampling request | request_id=0
[CLIENT] [CACHE][TIER1] semantic_cache_miss | ... LLM call executed
[SERVER] Critic evaluation complete — is_sufficient=False | N problem(s) found.
```
The signal that everything is actually working — not just verifying — is that the **server's own
Critic/Corrector log lines appear with real content**, not a JSON 402 blob. If `corrected_answer` in
the final tool output is itself a stringified `402_payment_required` challenge, the reciprocal
sampling shield is enabled and firing against your own server — check `X402_SHIELD_SAMPLING_ENABLED`.
## 7. Known limitations of this delivery
- No live network access existed in the sandbox this was built in, so nothing here was tested
against a real facilitator by me directly — every fix in this stage came from iterating against
*your* live logs, turn by turn, against the real `https://facilitator.xpay.sh`.
- `finops_compliance_audit.json` is written automatically at the end of each `agent_client` run
(`export_x402_ledger()`); regenerate it after a fully successful settlement for a submission-ready,
genuinely live-captured trace rather than the placeholder originally shipped.
- No screenshots are included — capture the dashboard's 💵 FinOps tab (wallet balance, spend
velocity, chronological x402 audit stream) after a real successful run, with a visible system
clock, per the task's requirement.
- The reciprocal sampling shield (`X402_SHIELD_SAMPLING_ENABLED=true`) is implemented and correct in
isolation but will cause every sampling call in the reflection loop to fail with a 402 in this
single-server demo, since the server has no code path to pay a second, nested challenge — see
REFLECTION_STAGE6.md and the settings docstring for the full reasoning. It's a real, working
capability that simply isn't the right thing to enable against your own trusted server.This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues