MCP Server Integration Guide
What is MCP
Model Context Protocol (MCP) is a standard for connecting AI agents to external tools and data sources. Instead of the agent making raw HTTP calls, it invokes named tools with structured parameters. The MCP server handles the implementation details.
Viatika's MCP server gives agents two tools:
pay_for_resource— make HTTP requests with automatic x402 payment handlingcheck_balance— check remaining credit balance
The agent never sees payment signatures, wallet addresses, or blockchain details. It just calls the tool and gets results.
Installation
Build from source
cd ~/src/github.com/viatika-ai/platform
go build -o /usr/local/bin/viatika-mcp ./cmd/agent-mcpVerify installation
viatika-mcp --help
# or just verify it exists:
which viatika-mcpConfiguration
The MCP server reads configuration from environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
VIATIKA_API_URL | yes | http://localhost:8081 | Viatika platform API base URL |
VIATIKA_API_TOKEN | yes | — | API token (format: vt_live_...) |
VIATIKA_ORG_ID | yes | — | Organization UUID |
VIATIKA_ENTITY_ID | yes | — | Entity UUID (user or swarm) |
LOG_LEVEL | no | info | Log verbosity: debug or info |
Setup: Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or equivalent:
{
"mcpServers": {
"viatika": {
"command": "/usr/local/bin/viatika-mcp",
"env": {
"VIATIKA_API_URL": "https://api.viatika.ai",
"VIATIKA_API_TOKEN": "vt_live_abc123456789...",
"VIATIKA_ORG_ID": "550e8400-e29b-41d4-a716-446655440000",
"VIATIKA_ENTITY_ID": "660e8400-e29b-41d4-a716-446655440001"
}
}
}
}Restart Claude Desktop. The tools appear in the tool picker (hammer icon).
Setup: Other MCP-Compatible Agents
Any agent supporting MCP stdio transport can use the server. The key configuration:
- Transport: stdio (stdin/stdout JSON-RPC)
- Command:
/usr/local/bin/viatika-mcp - Environment: set the 4 required variables
The server identifies itself as "Viatika x402 Payment Agent" version "1.0.0".
Tool Reference
pay_for_resource
Make an HTTP request to a URL. If the response is 402 Payment Required, automatically sign the payment through Viatika and retry with payment headers.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | yes | — | The URL to request |
method | string | no | "GET" | HTTP method: GET, POST, PUT, DELETE, etc. |
headers | object | no | {} | HTTP headers as key-value pairs |
body | string | no | "" | Request body (for POST/PUT) |
Return Value
{
"success": true,
"status_code": 200,
"body": "response body content",
"headers": {
"Content-Type": "application/json"
},
"payment_made": true,
"amount_usdc": "1.50"
}| Field | Type | Description |
|---|---|---|
success | boolean | true if final status code is 2xx |
status_code | integer | HTTP status code of final response |
body | string | Response body |
headers | object | Response headers |
payment_made | boolean | true if a 402 was encountered and payment was signed |
amount_usdc | string | USDC amount paid (only if payment_made is true) |
error | string | Error message (only on failure) |
Flow
- Makes the HTTP request to
urlwith specifiedmethod,headers, andbody - If response is not 402 → returns the response directly
- If response is 402:
- Extracts x402 payload from response body or
Payment-Requiredheader - Sends payload to Viatika
/v1/x402/sign-paymentfor policy check + signing - If denied → returns error with denial reason
- If approved → retries original request with
X-PaymentandX-Payment-Signatureheaders - Returns final response with
payment_made: true
- Extracts x402 payload from response body or
Example Usage in Conversation
User: “Fetch the weather data from https://weather-api.example.com/forecast”
Agent calls pay_for_resource:
{
"url": "https://weather-api.example.com/forecast",
"method": "GET"
}Tool returns:
{
"success": true,
"status_code": 200,
"body": "{\"forecast\": \"sunny, 24°C\"}",
"payment_made": true,
"amount_usdc": "0.05"
}Agent: “The forecast is sunny at 24°C. (This required a $0.05 payment which was automatically processed.)”
check_balance
Check the current credit balance for the configured entity.
Parameters
None.
Return Value
{
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"entity_id": "660e8400-e29b-41d4-a716-446655440001",
"balance_credits": 8500,
"balance_usd": "$8.50",
"note": "You have 8500 credits available (1 credit = $0.001)"
}| Field | Type | Description |
|---|---|---|
organization_id | string | Organization UUID |
entity_id | string | Entity UUID |
balance_credits | integer | Balance in credits |
balance_usd | string | Balance formatted as USD |
note | string | Human-readable summary |
Example Usage in Conversation
User: “How much budget do I have left?”
Agent calls check_balance (no arguments).
Tool returns:
{
"organization_id": "550e8400-...",
"entity_id": "660e8400-...",
"balance_credits": 8500,
"balance_usd": "$8.50",
"note": "You have 8500 credits available (1 credit = $0.001)"
}Agent: “You have $8.50 (8,500 credits) remaining.”
Example Conversation Flow
Here's a complete interaction showing how an agent uses both tools:
User: Check my balance, then fetch the premium dataset from
https://data-api.example.com/v2/market-analysis
Agent: Let me check your balance first.
[calls check_balance]
→ You have 15,000 credits ($15.00)
Agent: You have $15.00 available. Now let me fetch that dataset.
[calls pay_for_resource with url="https://data-api.example.com/v2/market-analysis"]
→ {success: true, payment_made: true, amount_usdc: "2.00", body: "..."}
Agent: Got it! The request cost $2.00 in x402 micropayments. You now have
approximately $13.00 remaining. Here's the market analysis data: ...Error Scenarios
Payment denied
{
"success": false,
"status_code": 402,
"payment_made": false,
"error": "Payment signing denied: Daily budget of 5000 credits exceeded"
}The agent should report the denial reason and suggest the user check their budget settings.
No x402 payload in 402
{
"success": false,
"status_code": 402,
"payment_made": false,
"error": "no x402 payload found in response"
}The service returned 402 but didn't include valid x402 payment information.
Network error to Viatika
{
"success": false,
"status_code": 402,
"payment_made": false,
"error": "Payment signing failed: send request: dial tcp: connection refused"
}The agent should report a connectivity issue with the payment service.
Troubleshooting
MCP server doesn't start
Check stderr output (MCP uses stdout for JSON-RPC, logs go to stderr):
VIATIKA_API_URL=https://api.viatika.ai \
VIATIKA_API_TOKEN=vt_live_... \
VIATIKA_ORG_ID=your-org-uuid \
VIATIKA_ENTITY_ID=your-entity-uuid \
viatika-mcp 2>/tmp/viatika-mcp.logCheck /tmp/viatika-mcp.log for errors. Common issues:
- Missing environment variables →
"VIATIKA_API_TOKEN is required" - Binary not found → check path in config
- Permission denied →
chmod +x /usr/local/bin/viatika-mcp
Tools don't appear in Claude Desktop
- Check the config JSON is valid (no trailing commas, correct quotes)
- Restart Claude Desktop completely (quit and reopen)
- Look for error banners in the Claude Desktop UI
- Try running the binary manually to verify it works
Payment always denied
- Check balance: call
check_balanceto verify credits exist - Check token scopes: ensure token has
x402:signandcredits:consume - Check budget policies: the entity may have exhausted their budget period
- Check provider whitelist: the target service may not be whitelisted
Timeout errors
The MCP server has a 30-second HTTP timeout. If the target service or Viatika API is slow:
- Check network connectivity
- The target URL may be unreachable
- Viatika API may be under load (signing takes ~150ms normally)