casefile-repository-mcp-server
Version:
Vessel casefile management system with MCP integration for maritime operations
120 lines • 4.84 kB
JavaScript
/**
* Casefile Repository MCP Server
* A vessel casefile management system using Model Context Protocol
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { getMongoClient } from "./utils/mongodb.js";
import { getTypesenseClient } from "./utils/typesense.js";
import { config } from "./utils/config.js";
import { toolDefinitions } from "./tools/index.js";
import { resourceList, getUserDetails, getDocumentContent } from "./resources/index.js";
import { promptList, getCasefileToolsInstructions } from "./prompts/index.js";
import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { fetchCompanyImoNumbers, setCompanyImoNumbers } from "./utils/imoUtils.js";
import { filterResponseByCompanyImos } from "./utils/responseFilter.js";
import { logger } from "./utils/logger.js";
async function main() {
// Connect to MongoDB and Typesense
const mongoClient = await getMongoClient(config.mongoUri);
const typesenseClient = getTypesenseClient(config);
// Initialize IMO filtering system
if (config.companyName) {
try {
logger.info(`Initializing IMO filtering for company: ${config.companyName}`);
const imoNumbers = await fetchCompanyImoNumbers(config.companyName);
setCompanyImoNumbers(imoNumbers);
logger.info(`Successfully fetched ${imoNumbers.length} IMO numbers for company: ${config.companyName}`);
}
catch (error) {
logger.error("Failed to fetch IMO numbers:", error);
logger.warn("IMO filtering may be limited. Server will continue with reduced functionality.");
}
}
else {
logger.info("No company name provided. IMO filtering will be disabled.");
}
// Create server
const server = new Server({
name: "casefile-repository-mcp-server",
version: "1.0.0"
}, {
capabilities: {
resources: {
list: true,
read: true,
templates: true
},
tools: {
list: true,
call: true
},
prompts: {
list: true,
get: true
}
}
});
// Resource handlers
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return { resources: resourceList };
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri.startsWith("user://")) {
const userId = uri.replace("user://", "");
const content = await getUserDetails(userId);
return {
content: {
type: "text",
text: content
}
};
}
else if (uri.startsWith("document://")) {
const docId = uri.replace("document://", "");
const content = await getDocumentContent(docId);
return {
content: {
type: "text",
text: content
}
};
}
throw new Error(`Unknown resource URI: ${uri}`);
});
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
return { templates: [] };
});
// Tool handlers
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: toolDefinitions };
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const tool = toolDefinitions.find(t => t.name === name);
if (!tool) {
throw new Error(`Tool not found: ${name}`);
}
// Execute tool and apply IMO filtering to response
const result = await tool.handler(args);
const filteredResult = await filterResponseByCompanyImos(result);
return { content: filteredResult };
});
// Prompt handlers
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return { prompts: promptList };
});
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
const { name } = request.params;
if (name === "casefile_tools_instructions") {
return getCasefileToolsInstructions();
}
throw new Error(`Prompt not found: ${name}`);
});
// Serve the server
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
//# sourceMappingURL=index.js.map