@futarchy402/mcp
v1.0.4
Published
MCP server and adapters for Futarchy402 governance platform with x402 payment-gated voting
Maintainers
Readme
Futarchy402 MCP
Multi-platform AI tools for the Futarchy402 governance platform with x402 payment-gated voting.
Overview
Futarchy402 MCP provides a unified interface for AI agents to interact with the Futarchy402 governance platform across multiple frameworks:
- OpenAI - Function calling
- Anthropic Claude - Tool use
- Model Context Protocol (MCP) - Standard protocol for AI tools
- LangChain - Agent framework integration
All platforms share the same core implementation, including the critical x402 payment-gated voting protocol.
Features
- 🗳️ Full Governance Integration - List polls, get details, check positions
- 💰 x402 Payment Protocol - Execute payment-gated votes on-chain
- 🔌 Multi-Platform Support - Works with OpenAI, Claude, MCP, LangChain
- 🛠️ Type-Safe - Full TypeScript support
- 🧪 Well-Tested - Comprehensive test coverage
- 📦 Tree-Shakeable - Import only what you need
Installation
npm install @futarchy402/mcpQuick Start
OpenAI
import { OpenAIFutarchyAdapter } from '@futarchy402/mcp/adapters/openai';
import OpenAI from 'openai';
const openai = new OpenAI();
const adapter = new OpenAIFutarchyAdapter();
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Show me open polls' }],
tools: adapter.getTools(),
});
// Handle tool calls
for (const toolCall of response.choices[0].message.tool_calls || []) {
const result = await adapter.executeFunction(
toolCall.function.name,
toolCall.function.arguments
);
console.log(result);
}Anthropic Claude
import { ClaudeFutarchyAdapter } from '@futarchy402/mcp/adapters/anthropic';
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic();
const adapter = new ClaudeFutarchyAdapter();
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Show me open polls' }],
tools: adapter.getTools(),
});
// Handle tool uses in response.contentMCP Server (Claude Desktop)
Location: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
Basic Configuration (Mainnet):
{
"mcpServers": {
"futarchy402": {
"command": "node",
"args": ["/absolute/path/to/node_modules/@futarchy402/mcp/dist/adapters/mcp/server.js"],
"env": {
"FUTARCHY_NETWORK": "mainnet"
}
}
}
}Devnet Configuration with Wallet:
{
"mcpServers": {
"futarchy402": {
"command": "node",
"args": ["/absolute/path/to/node_modules/@futarchy402/mcp/dist/adapters/mcp/server.js"],
"env": {
"FUTARCHY_NETWORK": "devnet",
"WALLET_PRIVATE_KEY": "your-devnet-wallet-base58-key"
}
}
}
}⚠️ Security Warning: Only use WALLET_PRIVATE_KEY in config with devnet keys. For mainnet, let Claude ask for the key each time.
After updating config, restart Claude Desktop.
LangChain
import { LangChainFutarchyAdapter } from '@futarchy402/mcp/adapters/langchain';
import { ChatOpenAI } from '@langchain/openai';
import { createToolCallingAgent, AgentExecutor } from 'langchain/agents';
const adapter = new LangChainFutarchyAdapter();
const tools = adapter.getTools();
const llm = new ChatOpenAI({ modelName: 'gpt-4o' });
const agent = await createToolCallingAgent({ llm, tools, prompt });
const executor = new AgentExecutor({ agent, tools });
const result = await executor.invoke({
input: 'What polls are open?',
});Direct SDK Usage
import { Futarchy402Client, executeVote } from '@futarchy402/mcp';
const client = new Futarchy402Client();
// List polls
const { polls } = await client.listPolls({ status: 'open' });
// Get poll details
const poll = await client.getPoll('poll-id');
// Get position
const position = await client.getPosition('poll-id', 'wallet-pubkey');
// Vote (x402 payment-gated)
const result = await executeVote({
pollId: 'poll-id',
side: 'yes',
walletPrivateKey: 'base58-key',
slippage: 0.05,
});Available Tools
All platforms expose these 5 tools:
1. futarchy_list_polls
List governance polls with optional filtering.
Parameters:
status(optional) - Filter by "open" or "resolved"treasury_id(optional) - Filter by treasurylimit(optional) - Max results (default: 20)offset(optional) - Pagination offset
Returns: Array of polls with liquidity, fees, probabilities, vote counts
2. futarchy_get_poll
Get detailed information about a specific poll including all votes.
Parameters:
poll_id(required) - Poll identifier
Returns: Full poll details with proposal info, liquidity stats, all votes
3. futarchy_get_position
Get a wallet's position in a poll with profit/loss projections.
Parameters:
poll_id(required) - Poll identifiervoter_pubkey(required) - Solana wallet public key
Returns: Position details, projections, actual results (if resolved)
4. futarchy_vote
Execute a payment-gated vote using the x402 protocol.
Parameters:
poll_id(required) - Poll to vote onside(required) - "yes" or "no"wallet_private_key(optional) - Base58 encoded private key (can useWALLET_PRIVATE_KEYenv var instead)slippage(optional) - Max slippage tolerance (default: 0.05 = 5%)
Returns: Vote result with transaction signature, amounts, slippage
⚠️ IMPORTANT: This executes a real on-chain transaction that costs USDC.
Wallet Configuration Options:
Prompt for key each time (Most Secure - Recommended for mainnet):
- AI will ask for your wallet key when voting
- Keys are never stored
- You review each vote before providing key
Environment variable (Convenient for testing):
export WALLET_PRIVATE_KEY="your-base58-private-key"- AI uses this key automatically when voting
- Only use with devnet keys for testing
- Never store mainnet keys in environment variables
Provide in tool call:
await adapter.executeFunction('futarchy_vote', { poll_id: 'abc123', side: 'yes', wallet_private_key: 'your-base58-key' });
5. futarchy_get_stats
Get platform-wide statistics.
Returns: Active polls, total projects, total proposals
x402 Payment Protocol
The voting mechanism uses the x402 payment-gated protocol:
- Request vote → Receive 402 Payment Required with payment requirements
- Build SPL token transfer transaction using @solana/spl-token
- Sign transaction with wallet
- Submit signed transaction with
X-Paymentheader to vote endpoint
This is implemented in src/core/x402.ts and handles:
- SPL token transfer transaction building
- Slippage protection
- Duplicate vote prevention
- Transaction confirmation
- Comprehensive error handling
Configuration
Network Selection
The SDK supports both mainnet and devnet. Always test on devnet first!
The network parameter determines which Solana network (mainnet/devnet) is used for transaction signing. The Futarchy402 API URL is the same for both networks.
# Set network (mainnet or devnet)
FUTARCHY_NETWORK=devnet
# API URL (same for both networks)
FUTARCHY_API_URL="https://futarchy402-api-385498168887.us-central1.run.app"Or configure programmatically:
import { Futarchy402Client } from '@futarchy402/mcp';
// Use devnet for testing
const devnetClient = new Futarchy402Client({
network: 'devnet'
});
// Use mainnet for production
const mainnetClient = new Futarchy402Client({
network: 'mainnet'
});Environment Variables
# Network selection (default: mainnet)
FUTARCHY_NETWORK=devnet
# Wallet private key for voting (optional - only use with devnet!)
WALLET_PRIVATE_KEY="your-base58-private-key"
# Override API URL (optional)
FUTARCHY_API_URL="https://custom-api.example.com"
# Override Solana RPC endpoints (optional)
SOLANA_RPC_DEVNET="https://api.devnet.solana.com"
SOLANA_RPC_MAINNET="https://api.mainnet-beta.solana.com"Custom Configuration
import { Futarchy402Client } from '@futarchy402/mcp';
const client = new Futarchy402Client({
apiBaseUrl: 'https://custom-api.example.com',
network: 'devnet',
});Architecture
futarchy402-mcp/
├── src/
│ ├── core/ # Platform-agnostic SDK
│ │ ├── client.ts # API client
│ │ ├── x402.ts # Payment-gated voting
│ │ ├── wallet.ts # Solana utilities
│ │ └── types.ts # Type definitions
│ ├── tools/ # Universal tool definitions
│ │ ├── definitions.ts
│ │ └── handlers.ts
│ └── adapters/ # Platform-specific adapters
│ ├── openai/
│ ├── anthropic/
│ ├── mcp/
│ └── langchain/
└── examples/ # Integration examplesExamples
See the examples/ directory for complete working examples:
Development
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Run tests
npm test
# Lint
npm run lint
# Format
npm run formatSecurity
Critical Security Guidelines
- Never commit private keys to version control (.env files are in .gitignore)
- Never store mainnet keys in environment variables or config files
- Only use
WALLET_PRIVATE_KEYenv var with devnet keys for testing - Review all transactions before signing
- Always test on devnet before using mainnet
- The
futarchy_votetool executes real on-chain transactions that cost USDC
Wallet Key Best Practices
For Devnet Testing:
- ✅ Store devnet keys in
WALLET_PRIVATE_KEYenvironment variable - ✅ Add to MCP server config for convenience
- ✅ Use for automated testing
For Mainnet Production:
- ✅ Let AI prompt for wallet key each time
- ✅ Review poll details before providing key
- ✅ Keep keys in secure password manager
- ❌ Never store in environment variables
- ❌ Never store in config files
- ❌ Never commit to version control
License
MIT
