UNPKG

linkup-mcp-server

Version:

'Linkup MCP server'

89 lines (87 loc) 3.61 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.main = exports.displayHelp = exports.parseArgs = void 0; const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const commander_1 = require("commander"); const linkup_sdk_1 = require("linkup-sdk"); const zod_1 = require("zod"); const package_json_1 = require("../package.json"); const DEFAULT_API_BASE_URL = 'https://api.linkup.so/v1'; const ArgsType = zod_1.z.object({ apiKey: zod_1.z.preprocess(value => value ?? process.env.LINKUP_API_KEY, zod_1.z.string({ message: 'Linkup API key not provided. Please either pass it as an argument --api-key=$KEY or set the LINKUP_API_KEY environment variable.', })), baseUrl: zod_1.z .string() .url({ message: 'Base url must be a valid url.' }) .default(process.env.LINKUP_API_BASE_URL ?? DEFAULT_API_BASE_URL), }); commander_1.program .name(package_json_1.name) .description(package_json_1.description) .version(package_json_1.version) .option('--api-key <key>', 'Your Linkup API key (required unless LINKUP_API_KEY env is set)') .option('--base-url <url>', 'Custom API base URL (default: https://api.linkup.so/v1)') .option('-h, --help'); const parseArgs = (args) => { const result = ArgsType.safeParse(args); if (!result.success) { throw new Error(result.error.errors.map(e => e.message).join('|')); } return result.data; }; exports.parseArgs = parseArgs; const bindTool = (server, linkupClient) => { server.tool('search-web', 'Search the web in real time using Linkup. Use this tool whenever the user needs trusted facts, news, or source-backed information. Returns comprehensive content from the most relevant sources.', { depth: zod_1.z .enum(['standard', 'deep']) .describe("The search depth to perform. Use 'standard' for queries with likely direct answers. Use 'deep' for complex queries requiring comprehensive analysis or multi-hop questions"), query: zod_1.z .string() .describe("Natural language search query. Full questions work best, e.g., 'How does the new EU AI Act affect startups?'"), }, async ({ query, depth }) => await linkupClient .search({ depth, outputType: 'searchResults', query, }) .then(({ results }) => ({ content: [{ text: JSON.stringify(results), type: 'text' }], }))); }; const displayHelp = () => { console.log(` Usage: npx -y linkup-mcp [options] Options: --api-key Your Linkup API key (required unless LINKUP_API_KEY env is set) --base-url Custom API base URL (default: https://api.linkup.so/v1) --help, -h Show this help text `); process.exit(0); }; exports.displayHelp = displayHelp; const main = async () => { const args = commander_1.program.parse(process.argv).opts(); if (args.help) { (0, exports.displayHelp)(); } const { apiKey, baseUrl } = (0, exports.parseArgs)(args); const server = new mcp_js_1.McpServer({ name: package_json_1.name, version: package_json_1.version, }); bindTool(server, new linkup_sdk_1.LinkupClient({ apiKey, baseUrl, })); await server.connect(new stdio_js_1.StdioServerTransport()); }; exports.main = main; if (require.main === module) { (0, exports.main)().catch(e => { console.error(`An error occurred: ${e.message}`); process.exit(1); }); }