limitless-ai-mcp-server
Version:
MCP server for integrating Limitless AI Pendant recordings with AI assistants
125 lines • 5.27 kB
JavaScript
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const limitless_client_1 = require("./core/limitless-client");
const handlers_1 = require("./tools/handlers");
const definitions_1 = require("./tools/definitions");
const manager_1 = require("./resources/manager");
const handlers_2 = require("./resources/handlers");
const handlers_3 = require("./prompts/handlers");
const handlers_4 = require("./sampling/handlers");
const logger_1 = require("./utils/logger");
// Server metadata
const SERVER_INFO = {
name: 'limitless-ai-mcp-server',
version: '0.0.1',
description: 'MCP server for integrating Limitless AI Pendant recordings with AI assistants',
};
// Environment variable names
const API_KEY_ENV = 'LIMITLESS_API_KEY';
const BASE_URL_ENV = 'LIMITLESS_BASE_URL';
const TIMEOUT_ENV = 'LIMITLESS_TIMEOUT';
async function main() {
// Get configuration from environment
const apiKey = process.env[API_KEY_ENV];
if (!apiKey) {
logger_1.logger.error(`Missing required environment variable: ${API_KEY_ENV}`);
process.exit(1);
}
const baseUrl = process.env[BASE_URL_ENV];
const timeout = process.env[TIMEOUT_ENV] ? parseInt(process.env[TIMEOUT_ENV], 10) : undefined;
// Initialize client
const client = new limitless_client_1.LimitlessClient({
apiKey,
baseUrl,
timeout,
});
const toolHandlers = new handlers_1.ToolHandlers(client);
const resourceManager = new manager_1.ResourceManager(client);
const resourceHandlers = new handlers_2.ResourceHandlers(resourceManager);
const promptHandlers = new handlers_3.PromptHandlers();
const samplingHandlers = new handlers_4.SamplingHandlers(client);
// Create MCP server with discovery support
// The Server class automatically handles the initialize request
// and responds with server info and capabilities
const server = new index_js_1.Server({
name: SERVER_INFO.name,
version: SERVER_INFO.version,
}, {
capabilities: {
tools: {},
resources: {
subscribe: false,
listChanged: false,
},
prompts: {
listChanged: false,
},
sampling: {},
},
});
// Register handlers
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
logger_1.logger.debug('Listing available tools');
return {
tools: definitions_1.toolDefinitions,
};
});
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
logger_1.logger.debug(`Tool call received: ${request.params.name}`);
return toolHandlers.handleToolCall(request);
});
// Register resource handlers
server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async (request) => {
logger_1.logger.debug('Listing resources');
return resourceHandlers.handleListResources(request);
});
server.setRequestHandler(types_js_1.ListResourceTemplatesRequestSchema, async (request) => {
logger_1.logger.debug('Listing resource templates');
return resourceHandlers.handleListResourceTemplates(request);
});
server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
logger_1.logger.debug(`Reading resource: ${request.params.uri}`);
return resourceHandlers.handleReadResource(request);
});
// Register prompt handlers
server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async (request) => {
logger_1.logger.debug('Listing prompts');
return promptHandlers.handleListPrompts(request);
});
server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
logger_1.logger.debug(`Getting prompt: ${request.params.name}`);
return promptHandlers.handleGetPrompt(request);
});
// Register sampling handler
server.setRequestHandler(types_js_1.CreateMessageRequestSchema, async (request) => {
logger_1.logger.debug('Handling sampling request');
return samplingHandlers.handleCreateMessage(request);
});
// Error handling
server.onerror = (error) => {
logger_1.logger.error('Server error:', error);
};
process.on('uncaughtException', (error) => {
logger_1.logger.error('Uncaught exception:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
logger_1.logger.error('Unhandled rejection at:', promise, 'reason:', reason);
process.exit(1);
});
// Start server
const transport = new stdio_js_1.StdioServerTransport();
logger_1.logger.info(`Starting ${SERVER_INFO.name} v${SERVER_INFO.version}`);
await server.connect(transport);
logger_1.logger.info('Server connected and ready');
}
// Run the server
main().catch((error) => {
logger_1.logger.error('Failed to start server:', error);
process.exit(1);
});
//# sourceMappingURL=index.js.map