@rolli/mcp
Advanced tools
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| export declare function register(server: McpServer): void; |
| import { z } from "zod"; | ||
| import { apiPost, apiGet } from "../api.js"; | ||
| const POLL_INTERVAL_MS = Number(process.env.ROLLI_POLL_INTERVAL_MS) || 5_000; | ||
| const MAX_POLL_MS = Number(process.env.ROLLI_MAX_POLL_MS) || 10 * 60 * 1_000; | ||
| function sleep(ms) { | ||
| return new Promise((resolve) => setTimeout(resolve, ms)); | ||
| } | ||
| export function register(server) { | ||
| server.tool("list_expert_searches", "List all expert searches. Returns a paginated list filtered by status.", { | ||
| show: z | ||
| .enum(["all", "running", "completed", "failed"]) | ||
| .optional() | ||
| .describe("Filter by status (default: all)"), | ||
| page: z.number().int().positive().optional().describe("Page number (100 results per page)"), | ||
| }, async (params) => { | ||
| try { | ||
| const queryParts = []; | ||
| if (params.show) | ||
| queryParts.push(`show=${params.show}`); | ||
| if (params.page !== undefined) | ||
| queryParts.push(`page=${params.page}`); | ||
| const query = queryParts.length ? `?${queryParts.join("&")}` : ""; | ||
| const data = await apiGet(`/search${query}`); | ||
| return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; | ||
| } | ||
| catch (e) { | ||
| return { content: [{ type: "text", text: String(e) }], isError: true }; | ||
| } | ||
| }); | ||
| server.tool("expert_search", "Find experts matching a natural-language query using Rolli's AI-driven recommendation engine. Polls until the search is complete and returns the full list of recommended experts (name, professional title, location, contact info, expertise keywords, and an AI-generated summary explaining why each expert matches).", { | ||
| query: z | ||
| .string() | ||
| .min(1) | ||
| .max(500) | ||
| .describe("Natural-language description of the topic, expertise area, or expert profile to find (e.g. \"AI ethics researchers\", \"climate scientists who can speak on tipping points\")"), | ||
| }, async (params) => { | ||
| try { | ||
| const createResult = await apiPost("/search", { query: params.query }); | ||
| const searchId = createResult.id ?? createResult.search?.id; | ||
| if (searchId == null) { | ||
| return { content: [{ type: "text", text: JSON.stringify(createResult, null, 2) }] }; | ||
| } | ||
| const startTime = Date.now(); | ||
| while (Date.now() - startTime < MAX_POLL_MS) { | ||
| await sleep(POLL_INTERVAL_MS); | ||
| const data = await apiGet(`/search/${searchId}`); | ||
| const status = data.search?.status ?? data.status; | ||
| if (status === "completed" || status === "failed") { | ||
| return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; | ||
| } | ||
| } | ||
| return { content: [{ type: "text", text: `Expert search ${searchId} timed out after 10 minutes. Use get_expert_search to check status.` }], isError: true }; | ||
| } | ||
| catch (e) { | ||
| return { content: [{ type: "text", text: String(e) }], isError: true }; | ||
| } | ||
| }); | ||
| server.tool("get_expert_search", "Get results for an expert search by ID. Returns search status and, once complete, the array of recommended experts with their profiles and AI-generated match summaries.", { | ||
| id: z.number().int().positive().describe("Expert search ID"), | ||
| }, async (params) => { | ||
| try { | ||
| const data = await apiGet(`/search/${params.id}`); | ||
| return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; | ||
| } | ||
| catch (e) { | ||
| return { content: [{ type: "text", text: String(e) }], isError: true }; | ||
| } | ||
| }); | ||
| } |
+3
-1
@@ -10,5 +10,6 @@ #!/usr/bin/env node | ||
| import { register as registerUsage } from "./tools/usage.js"; | ||
| import { register as registerExperts } from "./tools/experts.js"; | ||
| const server = new McpServer({ | ||
| name: "rolli-mcp", | ||
| version: "1.1.8", | ||
| version: "1.2.0", | ||
| }); | ||
@@ -21,4 +22,5 @@ registerKeywordSearch(server); | ||
| registerUsage(server); | ||
| registerExperts(server); | ||
| const transport = new StdioServerTransport(); | ||
| await server.connect(transport); | ||
| console.error("Rolli MCP server running on stdio"); |
+1
-1
| { | ||
| "name": "@rolli/mcp", | ||
| "version": "1.1.8", | ||
| "version": "1.2.0", | ||
| "mcpName": "ai.rolli/mcp", | ||
@@ -5,0 +5,0 @@ "description": "MCP server for Rolli IQ — social media search and analytics across X, Reddit, YouTube, Facebook, Instagram, Threads, Bluesky, and more", |
26819
17.16%21
10.53%434
20.56%9
28.57%