OpenClaw Integration Guide
Build AI agents that automatically select the most reliable MCP servers using MCPulse.
What is OpenClaw?
OpenClaw is an open-source framework for building autonomous AI agents with MCP tool access. It handles agent orchestration, tool calling, memory, and execution loops.
This guide shows how to integrate MCPulse reliability scoring so your agents automatically choose the best MCP servers.
Prerequisites
- OpenClaw installed (npm install openclaw or equivalent)
- Node.js 18+ or Python 3.10+ (depending on your OpenClaw implementation)
- MCPulse account with API key (sign up at /signup)
- At least 2 monitored MCP servers registered in MCPulse
- Basic understanding of OpenClaw agent configuration
Step 1: Install Required Packages
Install both MCPulse monitor and the API client:
Node.js/TypeScript:
npm install mcpulse-monitor axios
Python:
pip install mcpulse httpx
Step 2: Monitor Your MCP Servers
First, wrap your MCP servers with monitoring (same as other platforms):
// weather-server.js
import { McpServer } from '@modelcontextprotocol/sdk';
import { wrapMcpServer } from 'mcpulse-monitor';
const server = new McpServer({
name: 'weather-api',
version: '1.0.0'
});
server.tool('get_weather', async ({ location }) => {
// Weather API logic
return { temperature: 72, conditions: 'sunny' };
});
const monitored = wrapMcpServer(server, {
serverId: 'weather-server-id',
reportInterval: 60000,
batchSize: 50
});
monitored.start();
Repeat this for all MCP servers your OpenClaw agents might use.
Step 3: Build a Server Selection Module
Create a module that queries MCPulse and selects the best server:
reliability-selector.js
import axios from 'axios';
export class ReliabilitySelector {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://stacks.polsia.app/api';
}
async selectBestServer(serverIds, options = {}) {
const {
minReliability = 95.0,
maxLatency = 500,
window = '24h'
} = options;
try {
// Query MCPulse API for reliability scores
const response = await axios.get(`${this.baseUrl}/reliability`, {
headers: {
'Authorization': `Bearer ${this.apiKey}`
},
params: {
server_ids: serverIds.join(','),
window
}
});
// Filter by requirements
const eligible = response.data.servers.filter(s =>
s.reliability_score >= minReliability &&
s.avg_response_time <= maxLatency &&
s.status === 'healthy'
);
if (eligible.length === 0) {
throw new Error('No servers meet reliability requirements');
}
// Sort by composite score: reliability (70%) + speed (30%)
eligible.sort((a, b) => {
const scoreA = (a.reliability_score * 0.7) +
((1000 - a.avg_response_time) / 1000 * 100 * 0.3);
const scoreB = (b.reliability_score * 0.7) +
((1000 - b.avg_response_time) / 1000 * 100 * 0.3);
return scoreB - scoreA;
});
return eligible[0];
} catch (error) {
console.error('Reliability check failed:', error.message);
// Fallback: return first server
return { server_id: serverIds[0] };
}
}
async getServerHealth(serverId) {
const response = await axios.get(
`${this.baseUrl}/reliability/${serverId}`,
{
headers: { 'Authorization': `Bearer ${this.apiKey}` }
}
);
return response.data;
}
}
Step 4: Use in Your OpenClaw Agent
Integrate the selector into your agent's server selection logic:
agent.js
import { Agent } from 'openclaw';
import { ReliabilitySelector } from './reliability-selector.js';
const selector = new ReliabilitySelector(process.env.MCPULSE_API_KEY);
const agent = new Agent({
name: 'WeatherAssistant',
description: 'Provides weather information using reliable MCP servers',
// Define available servers
mcpServers: {
weatherApi1: 'weather-server-id-1',
weatherApi2: 'weather-server-id-2',
weatherApi3: 'weather-server-id-3'
},
// Custom server selection before each task
async selectServer(task) {
const serverIds = Object.values(this.mcpServers);
// Let MCPulse choose the most reliable server
const best = await selector.selectBestServer(serverIds, {
minReliability: 95.0,
maxLatency: 500,
window: '24h'
});
console.log(
`Selected ${best.name} (${best.reliability_score}% reliable, ` +
`${best.avg_response_time}ms avg latency)`
);
return best.server_id;
},
async execute(task) {
// Select best server for this execution
const serverId = await this.selectServer(task);
// Call the selected server's tool
const result = await this.callTool(serverId, 'get_weather', {
location: task.location
});
return result;
}
});
// Run the agent
agent.start();
Advanced: Failover & Retry Logic
Build resilient agents with automatic failover to backup servers:
export class ResilientAgent extends Agent {
constructor(config) {
super(config);
this.selector = new ReliabilitySelector(config.apiKey);
}
async executeWithFailover(task, maxRetries = 3) {
const serverIds = Object.values(this.mcpServers);
// Get ranked list of servers
const ranked = await this.selector.selectBestServer(serverIds);
for (let i = 0; i < Math.min(maxRetries, serverIds.length); i++) {
const serverId = serverIds[i];
try {
const result = await this.callTool(
serverId,
task.tool,
task.params
);
// Success! Log and return
console.log(`✓ ${serverId} succeeded on attempt ${i + 1}`);
return result;
} catch (error) {
console.warn(
`✗ ${serverId} failed (attempt ${i + 1}): ${error.message}`
);
// Try next server if available
if (i < serverIds.length - 1) {
console.log(`→ Failing over to ${serverIds[i + 1]}...`);
await new Promise(r => setTimeout(r, 1000)); // Brief delay
}
}
}
throw new Error('All servers failed after retries');
}
}
Step 6: Monitor Agent-Level Metrics
Track which servers your agents prefer over time:
export class MetricsCollector {
constructor() {
this.selections = {};
this.successes = {};
this.failures = {};
}
recordSelection(serverId) {
this.selections[serverId] = (this.selections[serverId] || 0) + 1;
}
recordSuccess(serverId) {
this.successes[serverId] = (this.successes[serverId] || 0) + 1;
}
recordFailure(serverId) {
this.failures[serverId] = (this.failures[serverId] || 0) + 1;
}
getReport() {
const report = [];
for (const serverId in this.selections) {
const total = this.selections[serverId];
const success = this.successes[serverId] || 0;
const failure = this.failures[serverId] || 0;
report.push({
serverId,
selections: total,
successRate: (success / total * 100).toFixed(1) + '%',
failures: failure
});
}
return report.sort((a, b) => b.selections - a.selections);
}
}
// Usage in agent:
const metrics = new MetricsCollector();
async function executeTask(task) {
const serverId = await selector.selectBestServer(serverIds);
metrics.recordSelection(serverId);
try {
const result = await callTool(serverId, task);
metrics.recordSuccess(serverId);
return result;
} catch (error) {
metrics.recordFailure(serverId);
throw error;
}
}
// Periodic reporting
setInterval(() => {
console.table(metrics.getReport());
}, 3600000); // Every hour
Expected Results
After integration, you should see:
✓ Automatic Server Selection
Your agents will prefer servers with higher reliability scores, automatically routing away from degraded servers.
✓ Lower Failure Rates
By avoiding unreliable servers, your agent success rate should improve by 5-15%.
✓ Faster Response Times
The selector balances reliability and speed, preferring faster servers when reliability is equal.
✓ Visibility in Dashboard
See which servers are chosen most often, and compare their performance side-by-side.
Troubleshooting
❌ API authentication errors
- Verify your API key is correct (generate one at /dashboard)
- Check that Authorization: Bearer YOUR_KEY header is set
- API keys must be from a paid plan (Free tier has limited API access)
- Test authentication manually: curl -H "Authorization: Bearer KEY" https://stacks.polsia.app/api/reliability
⚠️ No servers meet reliability threshold
- Lower minReliability threshold (try 90.0 instead of 95.0)
- Increase maxLatency if all servers are slightly slow
- Check MCPulse dashboard to see actual server health
- Implement fallback logic to select any available server if none are "good enough"
🔍 Selector always picks same server
- Expected if one server is significantly more reliable than others
- Add randomization for servers within 2% reliability: if (Math.abs(a.score - b.score) < 2) return Math.random() - 0.5
- Consider load balancing across top 2-3 servers instead of always using #1
- Check if other servers are actually online and monitored
🐢 Server selection is slow
- Cache reliability scores for 1-5 minutes (they don't change that fast)
- Query MCPulse API in parallel with agent startup, not per-request
- Use window: '1h' instead of '7d' for faster queries
- Consider pre-selecting servers at agent initialization instead of per-task
Best Practices for OpenClaw + MCPulse
-
✓
Cache reliability scores: Don't query MCPulse on every single agent action. Cache for 1-5 minutes.
-
✓
Implement failover: Always have backup servers. If the "best" server fails, try the second-best.
-
✓
Balance reliability and speed: Use composite scoring (70% reliability, 30% speed) for best UX.
-
✓
Monitor your agent: Track which servers your agent prefers and their success rates.
-
✓
Set reasonable thresholds: Don't require 99.9% reliability unless you truly need it. 95% is excellent for most use cases.
-
✓
Use appropriate time windows: 24h is good for production; 1h reacts faster to outages.
Example Use Cases
🔍 Research Agent
Use 3-5 web search MCP servers. MCPulse selects the one with best uptime and speed for each query.
💬 Customer Support Bot
Multiple knowledge base MCP servers. Failover ensures users never see "server unavailable" errors.
📊 Data Pipeline Agent
ETL tasks across redundant database MCP servers. MCPulse routes to least-loaded server automatically.
🤖 Multi-Cloud Deployment
Same MCP server deployed to AWS, GCP, and Azure. Agent picks the region with best performance for user's location.
Full API Reference
For complete API documentation including all endpoints, authentication, rate limits, and response schemas:
View Full API Docs →