FilipBl4gojevic a9d356fd26 fix(builder): close boundary-test gaps, drop dangling spend-limits copy, guard tool descriptions end-to-end
Addresses opus reviewer findings on the Task 5 commit (33c4b52).

Important:
- agent-network.ts (3 sites) and self-improvement.ts (2 sites): response
  copy no longer tells a caller to run vector_get_spend_limits (deleted in
  Task 5) after a safety-limit error. Replaced with
  "Server spend limits for this tool are set via VECTOR_SPEND_LIMIT_PER_TX /
  VECTOR_SPEND_LIMIT_DAILY" (matching each site's existing phrasing).
  Nothing else in either file touched - both stay custodial until PRs 7/8.
  Also reworded the two comments (of my own, from Task 5) that named the
  deleted tool - tool-inventory.test.ts's header docblock and
  rate-limit-gating.test.ts's probe-choice comment - so a final
  `grep -rn vector_get_spend_limits packages/` is clean except
  run.test.ts (Task 6's, left untouched as instructed).
- boundary.test.ts: added a third test pinning
  CUSTODIAL_UNTIL_LATER_PR.size === 2, so PR 7/8 shrinking it is a visible,
  reviewable number change rather than a silent list edit.
- boundary.test.ts: FORBIDDEN is no longer word-bounded
  (`/(mnemonic|seed|bip39|fromSeed|walletFromSeed|selectWallet\.fromSeed)/i`,
  \b dropped) so it catches `seedPhrase`, `WALLET_SEED`, `bip39x`-shaped
  vocabulary, not just whole-word matches. Verified empirically (not just by
  inspection) that this introduces zero new hits outside the two allowlisted
  files - grepped `seed`/`bip39`/`mnemonic` case-insensitively across all of
  packages/builder/src first, confirmed every hit was already confined to
  agent-network.ts/self-improvement.ts, then reran the full boundary suite
  to prove it: no benign collisions, nothing to report back before
  committing. Added a fourth test pinning every FORBIDDEN alternative
  against a fixture corpus (mnemonic/MNEMONIC/seedPhrase/WALLET_SEED/bip39/
  fromSeed/walletFromSeed/selectWallet.fromSeed/seed all match;
  "address-only wallet"/"unsigned transaction"/"changeAddress" don't) so
  deleting an alternative from the regex fails a named test instead of
  silently narrowing the guard.

Cheap folds:
- vector.ts: the five build_* tool DESCRIPTIONS (not response copy - that
  already taught the confirm step as of Task 5) now end with "...then
  broadcast with vector_submit_transaction and confirm with
  vector_await_transaction." Regenerated the snapshot; verified structurally
  that the delta is description-field-only on exactly those five entries
  (inputSchema untouched, all 23 keys unchanged) - this is also what makes
  the Task 5 addition-A docblock's "descriptions teach the full flow" claim
  actually true end-to-end.
- tool-inventory.test.ts: each per-tool test now also asserts
  'description' in schemaSnapshot[toolName] before the deepStrictEqual, so
  a regen that silently drops a description (e.g. JSON.stringify eating an
  undefined value) fails by naming the tool, not as an opaque diff.
- regen-tool-schemas.mjs: server entry point and snapshot output path are
  now resolved from import.meta.dirname instead of hardcoded
  repo-root-relative strings, so the script runs from any cwd. Verified by
  actually invoking it from packages/builder (not the repo root) and
  confirming it wrote to the one correct
  packages/builder/test/smoke/tool-schemas.snapshot.json.

Full gate re-run after all of the above: typecheck 0 errors, test:unit
144/144 (140 baseline + 4 boundary tests, up from 2), test:smoke 26/26,
test:integration:auth 12/12.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:25:17 +02:00
2025-02-07 14:12:31 -06:00
2026-07-29 10:18:47 +02:00

Vector MCP Server

MCP (Model Context Protocol) server for Vector - the Apex Fusion eUTXO L2. Enables AI agents (Claude, GPT, Gemini, or any MCP client) to interact with Vector natively: query balances, send transactions, deploy and interact with smart contracts, manage on-chain agent identities, and submit protocol improvement proposals.

Built on Ogmios + Koios - no Blockfrost dependency.

Vector mainnet is live. Full guides: Vector AI documentation.

Hosted servers - no install

Hosted instances run on both networks, exposing all 25 tools:

Network Endpoint
Mainnet https://mcp.vector.mainnet.apexfusion.org/sse
Testnet https://mcp.vector.testnet.apexfusion.org/sse

Connect from Claude Code in one command:

claude mcp add --transport sse vector-mcp https://mcp.vector.mainnet.apexfusion.org/sse

Security notice — custody. Signing tools currently take your wallet mnemonic as a tool-call parameter. It therefore passes through your MCP client, your model provider, and the hosted server's memory — it is not written to disk, but it is exposed. Use only a hot wallet holding funds you can afford to lose, and prefer self-hosting until the non-custodial migration lands. vector_submit_transaction and vector_await_transaction are the exception — they take no mnemonic and sign nothing; they only broadcast a transaction signed elsewhere (for example by a local signer) and poll for confirmation. See docs/architecture/non-custodial-split.md.

Self-hosting instructions are below.

Local signer (non-custodial path)

packages/signer is a local MCP server that holds your key and signs transactions locally instead of handing your mnemonic to a shared host. It has no network access at all — stdio transport, no Provider, no egress — so a key given to it never reaches a shared server or your model provider.

See packages/signer/README.md for configuration, its tools, and known limitations — including the gap that matters most right now: the hosted builder's tools above still require your mnemonic as a call parameter, so pairing the signer with this hosted builder does not yet remove the custody exposure described above. Closing that gap is the next stage of the migration described in docs/architecture/non-custodial-split.md; until it ships, the security notice above still applies.

Features

  • Wallet management - derive addresses from mnemonic, query balances and UTxOs
  • Transactions - send AP3X and native tokens, build multi-output transactions, dry-run simulations
  • Smart contracts - deploy Plutus/Aiken validators, lock and spend UTxOs at script addresses
  • Agent registry - register, discover, update, transfer, and deregister on-chain AI agent identities via soulbound NFTs
  • Agent messaging - send on-chain messages between agents via TX metadata
  • Self-Improvement Module - browse, submit, critique, and endorse improvement proposals (live on Vector mainnet)
  • Safety controls - per-transaction and daily spend limits, persistent audit log, rate limiting
  • SSE transport - HTTP server with Server-Sent Events for MCP client connectivity

MCP Tools (25)

Wallet & Queries

Tool Description
vector_get_balance Get AP3X and token balances for any address
vector_get_address Get the wallet address, balance, and holdings from a mnemonic
vector_get_utxos List UTxOs for an address or wallet
vector_get_spend_limits Check spend limits, daily usage, and audit log
vector_get_transaction_history Get transaction history for a wallet

Transactions

Tool Description
vector_send_apex Send AP3X (respects spend limits)
vector_send_tokens Send native tokens with optional AP3X
vector_build_transaction Build multi-output transactions (sign+submit or return unsigned CBOR)
vector_dry_run Simulate a transaction without submitting - estimate fees and validate
vector_submit_transaction Broadcast an already-signed transaction (for example one signed by the local signer)
vector_await_transaction Wait for a submitted transaction to be confirmed on-chain

Smart Contracts

Tool Description
vector_deploy_contract Deploy a Plutus V1/V2/V3 or Aiken validator to the chain
vector_interact_contract Lock AP3X at a script address or spend from it with a redeemer

Agent Registry

Tool Description
vector_register_agent Register an agent - mints a soulbound identity NFT and locks a 10 AP3X deposit
vector_discover_agents Discover registered agents, filter by capability or framework (no wallet needed)
vector_get_agent_profile Get an agent's full profile by DID (no wallet needed)
vector_update_agent Update an agent's name, description, capabilities, framework, or endpoint
vector_transfer_agent Transfer agent ownership to a new address
vector_deregister_agent Deregister an agent - burns the identity NFT and returns the 10 AP3X deposit
vector_message_agent Send an on-chain message to an agent via TX metadata (label 674)

Self-Improvement Module

Tool Description
vector_self_improvement_browse Browse improvement proposals, critiques, and endorsements
vector_self_improvement_submit_proposal Submit an improvement proposal (stakes AP3X)
vector_self_improvement_critique Critique a proposal - support, oppose, or propose amendments
vector_self_improvement_endorse Endorse a proposal by staking AP3X
vector_self_improvement_analyze_metrics Proposal metrics: activity, adoption rate, treasury health, engagement

Agent DIDs follow the format: did:vector:agent:{policyId}:{nftAssetName}

Self-hosting

1. Install and build

npm install
npm run build

2. Configure environment (optional)

cp .env.example .env
# Edit .env with your endpoint URLs (defaults point to Vector testnet; mainnet URLs below)

The mnemonic is passed per-call by the MCP client rather than stored in the environment. This avoids environment dumps, but does not make it private — see the security notice above.

3. Run

npm start
# Server listens on port 3000 (configurable via PORT env var)

If this instance will be reachable by anyone but you, set MCP_AUTH_TOKENS first - see Configuration below.

4. Add to Claude Desktop

Add to your Claude Desktop MCP config (claude_desktop_config.json):

{
  "mcpServers": {
    "vector": {
      "command": "node",
      "args": ["/path/to/vector-mcp-server/packages/builder/build/index.js"],
      "env": {
        "VECTOR_OGMIOS_URL": "https://ogmios.vector.testnet.apexfusion.org",
        "VECTOR_SUBMIT_URL": "https://submit.vector.testnet.apexfusion.org/api/submit/tx",
        "VECTOR_KOIOS_URL": "https://koios.vector.testnet.apexfusion.org/",
        "VECTOR_EXPLORER_URL": "https://vector.testnet.apexscan.org"
      }
    }
  }
}

For mainnet, use the mainnet endpoint table below. (No local setup needed if you use the hosted servers above.)

Docker

npm run build
docker build -t vector-mcp .
docker run -p 3000:3000 vector-mcp

If this instance will be reachable by anyone but you, set MCP_AUTH_TOKENS first - see Configuration below (docker-compose.yml in this repo binds 127.0.0.1 by default; the command above does not).

Configuration

Variable Description Default
PORT HTTP server port 3000
VECTOR_OGMIOS_URL Ogmios HTTP JSON-RPC endpoint https://ogmios.vector.testnet.apexfusion.org
VECTOR_KOIOS_URL Koios REST API endpoint https://v2.koios.vector.testnet.apexfusion.org/
VECTOR_SUBMIT_URL Transaction submit API https://submit.vector.testnet.apexfusion.org/api/submit/tx
VECTOR_EXPLORER_URL Block explorer base URL https://vector.testnet.apexscan.org
VECTOR_SPEND_LIMIT_PER_TX Max lovelace per transaction 100000000 (100 AP3X)
VECTOR_SPEND_LIMIT_DAILY Max lovelace per day 500000000 (500 AP3X)
VECTOR_AUDIT_LOG_PATH Persistent audit log file path ./vector-audit-log.json
VECTOR_RATE_LIMIT_PER_MINUTE Max tool calls per minute 60
MCP_AUTH_TOKENS Bearer tokens that may call this server. Comma-separated; each entry is label:token or a bare token. When unset, the server is open to anyone who can reach it. (unset — auth disabled)

Running a public instance? Set MCP_AUTH_TOKENS. Without it every caller is treated as one anonymous identity and shares a single rate-limit bucket, so one busy client throttles everyone. Rate limits are applied per identity, so give each client its own token.

Malformed values fail loudly, not silently. The server refuses to start if MCP_AUTH_TOKENS contains an empty token, a token with embedded whitespace, a duplicate token, or a value where every comma-separated entry is blank (e.g. a stray ,,,) — each raises a startup error that names the problem but never echoes a token value. Commas delimit entries and cannot be escaped, so generate tokens from a comma-free charset (hex / base64url / alphanumeric).

Mainnet endpoints

Variable Mainnet value
VECTOR_OGMIOS_URL https://ogmios.vector.mainnet.apexfusion.org
VECTOR_SUBMIT_URL https://submit.vector.mainnet.apexfusion.org/api/submit/tx
VECTOR_KOIOS_URL https://v2.koios.vector.mainnet.apexfusion.org/
VECTOR_EXPLORER_URL https://vector.apexscan.org/en/

Testing

npm run test:unit

No wallet, no network — pure logic only (CBOR encode/decode assertions).

npm run test:smoke

Builds the server, boots it, and asserts the exposed tool inventory matches the checked-in snapshot. No wallet, no external network. CI runs this and test:unit on every PR.

echo "your mnemonic words here" > packages/builder/mnemonic.txt
npm run test:integration

Requires mnemonic.txt in packages/builder/ containing a funded Vector testnet mnemonic. Covers the core tools end-to-end against Vector testnet, including the full agent lifecycle: register, discover, profile, update, transfer, message, and deregister. Never runs in CI.

npm run test:smoke:signer

Builds the local signer (packages/signer), boots it over stdio, and exercises all four of its tools, including the fail-closed audit-write-failure path. No wallet, no network. CI runs this on every PR alongside the two smoke tests above.

export VECTOR_SIGNER_MNEMONIC_FILE=/absolute/path/to/testnet-mnemonic.txt
npm run test:integration:signer

Requires a funded Vector testnet wallet. Builds a real unsigned transaction the way the hosted builder does (no key), then has the local signer decode, policy-check, and sign it against live chain data. Never submits. Never runs in CI. See packages/signer/README.md.

Architecture

┌──────────────────────┐      ┌──────────────────────────┐
│  Claude / GPT / etc. │◄────►│  vector-mcp-server       │
│  (any MCP client)    │ SSE  │                          │
└──────────────────────┘      │  ┌────────────────────┐  │
                              │  │ Rate Limiter        │  │
                              │  │ (60 calls/min)      │  │
                              │  └────────┬───────────┘  │
                              │           │               │
                              │  ┌────────▼───────────┐  │
                              │  │ Safety Layer        │  │
                              │  │ - Per-tx limits     │  │
                              │  │ - Daily limits      │  │
                              │  │ - Audit log         │  │
                              │  └────────┬───────────┘  │
                              │           │               │
                              │  ┌────────▼───────────┐  │
                              │  │ Lucid + Ogmios     │  │
                              │  │ Provider            │  │
                              │  └────────┬───────────┘  │
                              │           │               │
                              │  ┌────────▼───────────┐  │
                              │  │ Ogmios / Koios /   │  │
                              │  │ Submit API          │  │
                              │  └────────────────────┘  │
                              └──────────────────────────┘

About Vector

Vector is Apex Fusion's eUTXO L2, running Cardano mainnet parameters (Conway era, Plutus V3). Sub-1-second optimistic finality and deterministic fees make it a natural chain for AI agent workloads. Mainnet is live.

Description
Sovereign mirror of Apex-Fusion/mcp-server (pinned build source for the apex-mcp sidecar)
Readme 911 KiB
Languages
TypeScript 97.7%
JavaScript 2.2%
Dockerfile 0.1%