websearch-mcp
Version:
A Model Context Protocol (MCP) server implementation that provides real-time web search capabilities through a simple API
146 lines (145 loc) • 7.16 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const zod_1 = require("zod");
const axios_1 = __importDefault(require("axios"));
// Configuration
const API_URL = process.env.API_URL || "http://localhost:3001";
const MAX_SEARCH_RESULT = parseInt(process.env.MAX_SEARCH_RESULT || "5", 10);
// Main function to set up and run the MCP server
function main() {
return __awaiter(this, void 0, void 0, function* () {
// Create an MCP server
const server = new mcp_js_1.McpServer({
name: "WebSearch-MCP",
version: "1.0.0",
});
// Add a web_search tool
server.tool("web_search", "Search the web for information.\n"
+ "Use this tool when you need to search the web for information.\n"
+ "You can use this tool to search for news, blogs, or all types of information.\n"
+ "You can also use this tool to search for information about a specific company or product.\n"
+ "You can also use this tool to search for information about a specific person.\n"
+ "You can also use this tool to search for information about a specific product.\n"
+ "You can also use this tool to search for information about a specific company.\n"
+ "You can also use this tool to search for information about a specific event.\n"
+ "You can also use this tool to search for information about a specific location.\n"
+ "You can also use this tool to search for information about a specific thing.\n"
+ "If you request search with 1 result number and failed, retry with bigger results number.", {
query: zod_1.z.string().describe("The search query to look up"),
numResults: zod_1.z
.number()
.optional()
.describe(`Number of results to return (default: ${MAX_SEARCH_RESULT})`),
language: zod_1.z
.string()
.optional()
.describe("Language code for search results (e.g., 'en')"),
region: zod_1.z
.string()
.optional()
.describe("Region code for search results (e.g., 'us')"),
excludeDomains: zod_1.z
.array(zod_1.z.string())
.optional()
.describe("Domains to exclude from results"),
includeDomains: zod_1.z
.array(zod_1.z.string())
.optional()
.describe("Only include these domains in results"),
excludeTerms: zod_1.z
.array(zod_1.z.string())
.optional()
.describe("Terms to exclude from results"),
resultType: zod_1.z
.enum(["all", "news", "blogs"])
.optional()
.describe("Type of results to return"),
}, (params) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
try {
console.error(`Performing web search for: ${params.query}`);
// Prepare request payload for crawler API
const requestPayload = {
query: params.query,
numResults: (_a = params.numResults) !== null && _a !== void 0 ? _a : MAX_SEARCH_RESULT,
language: params.language,
region: params.region,
filters: {
excludeDomains: params.excludeDomains,
includeDomains: params.includeDomains,
excludeTerms: params.excludeTerms,
resultType: params.resultType,
},
};
// Call the crawler API
console.error(`Sending request to ${API_URL}/crawl`);
const response = yield axios_1.default.post(`${API_URL}/crawl`, requestPayload);
// Format the response for the MCP client
const results = response.data.results.map((result) => ({
title: result.title,
snippet: result.excerpt,
text: result.text,
url: result.url,
siteName: result.siteName || "",
byline: result.byline || "",
}));
return {
content: [
{
type: "text",
text: JSON.stringify({
query: response.data.query,
results: results,
}, null, 2),
},
],
};
}
catch (error) {
console.error("Error performing web search:", error);
if (axios_1.default.isAxiosError(error)) {
const errorMessage = ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) || error.message;
return {
content: [{ type: "text", text: `Error: ${errorMessage}` }],
isError: true,
};
}
return {
content: [
{
type: "text",
text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
}));
// Start receiving messages on stdin and sending messages on stdout
console.error("Starting WebSearch MCP server...");
console.error(`Using API_URL: ${API_URL}`);
const transport = new stdio_js_1.StdioServerTransport();
yield server.connect(transport);
console.error("WebSearch MCP server started");
});
}
// Start the server
main().catch((error) => {
console.error("Failed to start WebSearch MCP server:", error);
process.exit(1);
});