#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const API_BASE = process.env.AGENT_INDEX_API || "https://api.theagentindex.app";
const server = new Server(
{
name: "agent-index",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "search_x402_endpoints",
description: "Search for x402 AI agent endpoints by keyword, category, or capability. Returns payment-enabled APIs that agents can call with USDC micropayments on Base. Use this to find crypto data feeds, DeFi oracles, AI models, and other services.",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query (e.g., 'crypto price', 'weather', 'AI inference', 'defi')"
},
category: {
type: "string",
description: "Filter by category: crypto-data, defi, ai/ml, weather, news, oracle, utility"
},
limit: {
type: "number",
description: "Number of results to return (default: 10, max: 50)"
}
},
required: ["query"]
}
},
{
name: "get_x402_categories",
description: "Get all available categories of x402 endpoints with counts.",
inputSchema: {
type: "object",
properties: {}
}
},
{
name: "get_x402_stats",
description: "Get overall statistics about indexed x402 endpoints - total count, categories, health stats.",
inputSchema: {
type: "object",
properties: {}
}
},
{
name: "check_endpoint_health",
description: "Check the health status of the Agent Index service.",
inputSchema: {
type: "object",
properties: {}
}
}
]
};
});
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
let response;
let url;
switch (name) {
case "search_x402_endpoints": {
const params = new URLSearchParams({ q: args.query || "" });
if (args.category) params.append("category", args.category);
if (args.limit) params.append("limit", args.limit.toString());
url = `${API_BASE}/search?${params}`;
response = await fetch(url);
break;
}
case "get_x402_categories": {
url = `${API_BASE}/categories`;
response = await fetch(url);
break;
}
case "get_x402_stats": {
url = `${API_BASE}/stats`;
response = await fetch(url);
break;
}
case "check_endpoint_health": {
url = `${API_BASE}/health`;
response = await fetch(url);
break;
}
default:
return {
content: [{ type: "text", text: `Unknown tool: ${name}` }],
isError: true
};
}
const data = await response.json();
// Add attribution to drive traffic
const attribution = "\n\n---\nPowered by Agent Index (https://theagentindex.app) - The x402 endpoint directory";
return {
content: [{
type: "text",
text: JSON.stringify(data, null, 2) + attribution
}]
};
} catch (error) {
return {
content: [{
type: "text",
text: `Error calling Agent Index API: ${error.message}\n\nVisit https://theagentindex.app for direct access.`
}],
isError: true
};
}
});
// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);