GBLIN on Base for AI agents: risk regime, treasury plan for idle USDC, mint and redeem at NAV. Free.
Model Context Protocol server for the GBLIN protocol on Base mainnet: an on-chain index of cbBTC, WETH and USDC whose shares are minted at NAV and redeemed pro rata in kind. The server reads live state, verifies governance and risk attestations, and returns unsigned calldata to enter, leave and bid. It never holds keys, signs or broadcasts.
Published on npm as @gblin-protocol/mcp-server.
Documentation and quick start: gblin.digital/agents. Starter examples: examples/.
calm / elevated / crash) read from the vault's on-chain Crash Shield, with a severity score and a risk postureoutputSchema on every tool that returns an object, so a client can validate results and generate typesEvery tool is free. The server never charges: revenue comes from the on-chain protocol fee when an agent actually uses GBLIN. Verifiable pay-per-call lives on the HTTP endpoints listed under x402 endpoints.
| Component | Address | Role |
|---|---|---|
| Vault | 0xc2181d975c05c8c724b334bcED0764c0b86B1D53 | The ERC-20 share and the basket. Mints at NAV, redeems in kind, rebalances by Dutch auction, accepts payments by signature (EIP-3009). Never swaps. |
| Lens | 0xfCFea8027019E8551A1f09AD91532471F5D26f61 | Read-only views beside the vault: quotes, configuration, basket rows, auction state. |
| Zap | 0x0E9D6Ceb6D313b021622C121Cda9C62e86e60200 | The only contract that swaps: mints with any token, exits to ETH by redeeming in kind and selling every leg, all or nothing. |
| Timelock | 0x6aBeC8716fFeEcf7C3D6e68255b4797113E8e5Dd | 48-hour minimum delay, 14-day grace period, open executor. Proposer and canceller roles are held by separate addresses. |
Previous deployments (0x36C81d7E1966310F305eA637e761Cf77F90852f0, 0x38DcDB3A381677239BBc652aed9811F2f8496345) are superseded. Nothing is read from them; holders migrate through the web app.
Fees: 0.10% on every mint with ETH or WETH (0.05% stays in the vault and lifts the NAV of every share, 0.05% is minted as shares to the fee recipient); in-kind deposits pay a 0.50% floor plus a deviation tax; a 0.50% yearly management fee accrues as shares; redemption in kind and transfers carry no fee.
A stateless Streamable HTTP server runs at https://mcp.gblin.digital/mcp — no install, no auth, no session, 60 requests per minute per IP. It serves the vault, action and payment tools of this package under two-level names (treasury.*, actions.*, payments.*, governance.state, auction.state, attestation.verify), built from the same source, plus the risk, receipts and coherence tools; the snake_case names below are accepted there as aliases. It also serves search and fetch, the two read-only tools research clients expect (ChatGPT deep research among them): search returns matching documents (the protocol's documentation, one card per tool, the live vault state) and fetch returns one document's full text. Every step returned by the action tools carries both spellings, target/calldata and to/data/chainId, so it maps one to one onto wallet batch APIs such as send_calls. GET-only audit surfaces: /meta, /tools.json, /resources.json, /conformance. Also listed on Smithery.
packages/agent-treasury — npm @gblin-protocol/agent-treasury. Operating cash stays in USDC, the surplus above a
reserve is parked in GBLIN, and USDC is pulled back from GBLIN just in time when an x402 invoice arrives. The x402 client is
Coinbase's reference x402Client with the refill attached to its onBeforePaymentCreation hook, so a 402 for USDC on Base
triggers the refill before the authorization is signed and a price above the cap is refused before anything is signed.
Self-custody, no key leaves the process. Verified end to end on a fork of Base (24 checks: park, refill, cooldown, a
mock invoice with the challenge bytes of gblin.digital and a verified EIP-712 signature, the cap).
export GBLIN_AGENT_PRIVATE_KEY=0x...
npx @gblin-protocol/agent-treasury status --json
npx @gblin-protocol/agent-treasury park --json
npx @gblin-protocol/agent-treasury pay https://gblin.digital/api/x402/attestation --max-amount 3000 --json
The matching agent skill is skills/gblin-agent-treasury (npx skills add gblinproject/gblin-treasury-risk-regime).
Details: packages/agent-treasury/README.md.
get_market_risk_regime
calm, elevated or crash, with severity_pct, a risk_posture (risk_on / reduce / risk_off), the defensive cash weight and one entry per risk assetcrash reading means stand downget_treasury_state
nav_reliable), the yearly management fee, whether an auction is open, Crash Shield status and the basket rows with base and dynamic weightsquote_safe_swap
direction (string): buy or sellamount_in (string): decimal amount of ETH (buy) or GBLIN (sell)swap_gblin_to_usdc_jit
sellGBLINForEth (redeem in kind and sell every leg, all or nothing), then a WETH→USDC swap. Three transactions; ERC-4337 and EIP-7702 wallets batch them into oneusdc_needed (string): decimal USDC amountwallet_address (string): the agent's address, for the cooldown check and as receiverinvest_usdc_to_gblin
usdc_amount (string): decimal USDC amountwallet_address (string): receiver of the sharesanalyze_treasury_health
wallet_address (string)daily_burn_usd (number, optional): average daily spend, enables the runway estimateplan_treasury
max(reserve_usd, daily_burn_usd × days)), the surplus above it, a simulation of minting that surplus at NAV with every fee read live and the estimated value of exiting the same position today (round-trip cost included), the same simulation for a trial amount, the blockers (crash shield, cooldown, ETH for the exit) and the tools to call after a human confirms. Reads only; nothing is executed and nothing is advisedwallet_address (string)daily_burn_usd (number, optional): average daily spend in USDdays (number, optional): days of spend to keep liquid, default 7reserve_usd (number, optional): USD to keep liquid regardless of the burn rate; one of daily_burn_usd or reserve_usd is requiredtrial_usdc (number, optional): trial amount to simulate beside the surplus, default 100https://gblin.digital/api/x402/planget_governance_state
acceptOwnership operationoperation_id (string, optional): a timelock operation id (bytes32) to inspectshare_skill_with_peer
caller_wallet (string)peer_context (string, optional): what the peer does, to tailor the exampleexample_amount_usdc (number, optional)get_auction_state
best is the row with the largest gapprepare_gblin_payment
from (string): the payer, the wallet that will signto (string): the recipientamount_gblin (string) or amount_usd (string): the amount, converted at the live NAV when given in USDmethod (string, optional): receive (default) can be submitted only by the recipient, so nobody can front-run it; transfer can be submitted by anyone, which is what an x402 facilitator doesvalid_for_seconds (number, optional): default 600, maximum 86,400verify_gblin_authorization
authorization (object): from, to, value, validAfter, validBefore, noncesignature (string): produced by the payer's walletmethod (string, optional): receive (default) or transferwould_settle verdict means the payment is good to carryrelay_gblin_payment
https://gblin.digital/api/relay/gblin), which checks both against the chain, simulates them and submits them in one transaction through Multicall3: both settle or neither does. For a payer that holds no ETH and has nobody to carry the paymentpayment (object): { authorization, signature }, method transferfee (object): { authorization, signature } from the relay block of prepare_gblin_payment called with relay: trueprepare_action
action (string): mint_with_eth, mint_with_weth, mint_with_usdc, redeem_in_kind, exit_to_eth, exit_to_usdc or bidwallet_address (string): the wallet that will sign and receiveamount (string): in ETH, WETH or USDC for mints, in shares for redemptions and the ETH exit, the USDC needed for the USDC exit; not used by bidrow (integer, optional): bid only, the basket row; default the largest gappreview_steps
eth_simulateV1, each seeing the state the previous ones left. Returns, per step, success, gas used, whether the given limit is enough, the recommended limit and the decoded revert reason with a hint; and the net token and ETH movements for the walletfrom (string): the wallet that will send the stepssteps (array): the steps as the tools return them: target, calldata, optional value and gasgas_limit_enough is true when the step passes with the limit it carries, false only when that limit is what makes it fail, and null when it fails for another reason (a slippage bound, a cooldown), which error and hint nameget_transaction_status
hash (string)get_nav_history
interval (hour or day, default day), points (2 to 90, default 30)GBLIN_ARCHIVE_RPC_URL to use your ownverify_risk_attestation
attestation (object): the object returned by GET https://gblin.digital/api/x402/attestationexpected_attestor (string, optional): the attestor address to pinseal_action_demo
demo: true) and returns the portable receiptaction (string): a short labelinput_hash (string): SHA-256 of the inputoutput_hash (string, optional)agent_id, tool, meta (string, optional): identifiers, published in clearhow_to_seal_paidget_receipt
index (integer)how_to_seal_paid
Every tool sets MCP tool annotations:
| Tool | readOnlyHint | idempotentHint | destructiveHint | openWorldHint |
|---|---|---|---|---|
| all except the three below | true | true | false | true |
prepare_gblin_payment | true | false | false | true |
seal_action_demo | false | false | false | true |
relay_gblin_payment | false | true | true | true |
Calldata builders are read-only: they return bytes, they do not send them. prepare_gblin_payment is not idempotent because every call draws a fresh nonce. Sealing appends to a public log and is never destructive. relay_gblin_payment moves the payer's funds on chain, so it is marked destructive and clients should confirm before calling it. Every tool also carries a human-readable title.
Every tool except seal_action_demo declares an outputSchema. A successful result carries the same object as structuredContent and as JSON text. The required list of each schema is the contract: fields a successful call always returns. Other fields are described but optional, and the schemas accept additional fields, so adding one is not a breaking change. Errors carry isError: true and no structured content.
| Prompt | What it does |
|---|---|
risk_gate | Reads the regime and applies a rule stated before looking: proceed, halve, or stand down |
pay_in_gblin | Prepare, sign in the payer's wallet, verify, then hand on a gasless GBLIN payment |
pay_invoice_just_in_time | Exit just enough GBLIN to USDC to settle an invoice, after checking cooldown and gas |
seal_and_verify | Seal an action, read the receipt back, and state what it does and does not prove |
| URI | Content |
|---|---|
gblin://contracts | Every contract in service with its role, and the deprecated deployments not to use |
gblin://payments | The EIP-712 domain read live from the token, the x402 payload, and the accepts block a seller publishes |
gblin://keys | The attestor address to pin, and where the log and witness keys are published |
gblin://limits | Price (free by default), the metering switch, and where the limits come from |
Add to claude_desktop_config.json:
{
"mcpServers": {
"gblin": {
"command": "npx",
"args": ["-y", "@gblin-protocol/mcp-server"]
}
}
}
{
"mcpServers": {
"gblin": {
"command": "npx",
"args": ["-y", "@gblin-protocol/mcp-server"],
"env": { "GBLIN_RPC_URL": "https://base-rpc.publicnode.com" }
}
}
}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({ command: "npx", args: ["-y", "@gblin-protocol/mcp-server"] });
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const jit = await client.callTool({
name: "swap_gblin_to_usdc_jit",
arguments: { usdc_needed: "0.50", wallet_address: "0xYourAgent..." },
});
npx -p @gblin-protocol/mcp-server gblin-init
Creates an AGENTS.md from the template at gblin.digital/AGENTS.template.md, or appends a delimited block to an existing one. Idempotent; --dry-run previews, --force refreshes the block. No files are written at install time; set GBLIN_SKIP_HINT=1 to silence the post-install hint.
GBLIN_RPC_URL selects the Base RPC endpoint; the default is https://base-rpc.publicnode.com. For sustained load use a dedicated provider:
export GBLIN_RPC_URL="https://base-mainnet.g.alchemy.com/v2/YOUR_KEY"
npx @gblin-protocol/mcp-server
GBLIN_ATTESTOR_ADDRESS overrides the published attestor address used by verify_risk_attestation.
Pay-per-call data lives on HTTP, settled in USDC on Base through the Coinbase CDP facilitator with gasless EIP-3009 transferWithAuthorization. Clients such as @x402/fetch handle the 402 challenge, the signature and the retry.
| Endpoint | Price | Returns |
|---|---|---|
GET gblin.digital/api/x402/treasury-state | free | NAV, basket weights, Crash Shield status |
GET gblin.digital/api/x402/quote | free | Mint or redemption preview with the dynamic slippage buffer |
GET gblin.digital/api/x402/governance | free | Owner, timelock, pending operations |
GET gblin.digital/api/x402/health | free | Wallet balances, gas runway, allocation advice |
GET gblin.digital/api/x402/invest | free | Unsigned calldata: USDC → GBLIN |
GET gblin.digital/api/x402/jit | free | Unsigned calldata: GBLIN → USDC just in time |
GET gblin.digital/api/x402/attestation | $0.003 | Signed EIP-712 Risk Attestation, valid ten minutes |
POST gblin.digital/api/x402/seal | $0.0045 | A sealed AI Action Receipt |
Machine-readable manifest: https://gblin.digital/.well-known/x402. Payment recipient: 0x0ebA5d314F4f5Dcb7A094953Fa9311a45172dd1B.
GET https://gblin.digital/api/x402/attestation returns a ten-minute, verifiable snapshot of the BTC/ETH risk regime, signed under the EIP-712 domain GBLIN Risk Attestation, version 2, chain 8453, verifying contract = the vault in service. The response embeds its domain, types and message under eip712; a verifier recovers the signer and checks it against the published attestor address, which it should pin. verify_risk_attestation does this offline and also accepts attestations issued under domain version 1.
A public, append-only RFC 6962 transparency log for AI actions. Input and output go in as hashes only; the short action, agent_id, tool and meta strings are published in clear, so put identifiers there, never secrets. Each seal returns a portable receipt:
receipt = canonical payload
+ Ed25519 signature (key: gblin.digital/receipts-log)
+ RFC 6962 inclusion proof (leaf → Merkle root)
+ C2SP signed checkpoint (origin, tree size, root)
Canonicalization is frozen as gblin-canonical-json/1: object keys sorted by UTF-16 code unit, no whitespace, JSON.stringify semantics for primitives, recursion for objects and arrays. Test vector: payload {"b":1,"a":null} → canonical {"a":null,"b":1} → leaf = SHA256(0x00 || canonical_bytes). The receipt signature is Ed25519 over "gblin-receipt/v1\n" + canonical.
POST https://gblin.digital/api/x402/seal, $0.0045 USDC via x402POST <worker>/v1/seal-demo, or the tool seal_action_demo<worker>/v1/receipt/:index, /log, /log/checkpoint, /log/proof/:index, /log/consistency, /log/leaves, and the page /receipt/:index0x9f433a96…)verify-receipt.mjs — node verify-receipt.mjs receipt.jsonThe checkpoint is signed by the log operator and cosigned by an independent witness (Markovian Protocol). A cosignature attests that the log stayed append-only between the sizes the witness saw; it does not attest that a receipt's content is true. A seal proves existence and time; it is not a compliance certificate and not an endorsement. <worker> = https://gblin-mcp.gblin-mcp-worker.workers.dev.
GBLIN pre-registers hash-pinned promises and runs an automaton that probes them every ten minutes and seals each closed day as an EAS attestation on Base. Free report: /coherence. Live promises: uptime of the paid attestation endpoint, and honesty of the public agent-economy counters, with the protocol's own wallets disclosed. GBLIN is a registered ERC-8004 agent (#59286).
get_auction_state exposes it.analyze_treasury_health.transferWithAuthorization, receiveWithAuthorization, cancelAuthorization), so an agent can settle in GBLIN the way it settles in USDC. Transfers carry no fee.isNavReliable is reported alongside.git clone https://github.com/gblinproject/gblin-treasury-risk-regime
cd gblin-treasury-risk-regime
npm install
npm run build
npm test # handler smoke test against Base mainnet, read-only
npm run test:protocol # speaks MCP over stdio: capabilities, instructions, prompts, resources
npm run test:schemas # every tool through the official MCP client, which validates outputSchema
npx tsx scripts/test-hosted.ts <url> # the hosted server over Streamable HTTP, with the same validation
npm start # run the compiled server
Two tests run against a local fork of Base and send transactions there, never on mainnet:
anvil --fork-url <base rpc> --port 8555 &
export GBLIN_RPC_URL=http://127.0.0.1:8555
npm run test:payments # gasless payment: signed, verified, carried by a third party; replay and front-run refused
npm run test:calldata # sends the exit and investment steps exactly as the tools return them
npm run test:actions # every prepare_action, simulated then sent; preview agrees with the chain; gas limits found by bisection
src/
config.ts # addresses, slippage and cache settings
abi.ts # vault, Lens, Zap, timelock, Chainlink and ERC-20 ABIs
client.ts # viem public client and on-chain timestamp
helpers.ts # NAV, basket state, slippage, cooldown, reverse quote
auction.ts # auction state and bid sizing
tools.ts # the treasury, auction and risk tools, and the tool list
payments.ts # gasless payments (EIP-3009): prepare, verify, relay
actions.ts # prepare_action, preview_steps, get_transaction_status, get_nav_history
shared.ts # result envelopes, builder code, Zap routing data and gas limit
version.ts # generated from package.json by scripts/write-version.mjs
receipts.ts # the three receipt tools
output-schemas.ts # the outputSchema of every tool
prompts.ts # the four prompts
resources.ts # the four resources
index.ts # MCP stdio server entry and initialize instructions
init.ts # the gblin-init command
worker/ # the hosted Streamable HTTP server (Cloudflare Workers)
scripts/ # test.ts, test-protocol.ts, test-output-schemas.ts, test-payments-fork.ts, test-calldata-fork.ts
0xc2181d975c05c8c724b334bcED0764c0b86B1D53plugin-gblinMIT © GBLIN Protocol
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @gblin-protocol/mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-gblinproject-gblin-treasury-risk-regime": {
"command": "npx",
"args": [
"-y",
"@gblin-protocol/mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup reference@gblin-protocol/mcp-servernpmio.github.gblinproject/gblin-treasury-risk-regime works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.