import {
Tool,
ListToolsRequestSchema,
CallToolRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { queryStore } from "../utils/queries.js";
import { listQueries } from "./listQueries.js";
import { serveExamples } from "./getExamples.js";
import { queryDB } from "./queryDB.js";
// Tool Definitions
export const LIST_QUERIES_TOOL: Tool = {
name: "list_queries",
description: "List of recent queries that you performed via the MCP during this session",
inputSchema: {
type: "object",
properties: {
limit: { type: "number", description: "Limit the number of queries" },
},
},
};
export const QUERY_DB_TOOL: Tool = {
name: "query_db",
description: "Execute a database query",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "Valid JSON string with double quotes",
},
name: {
type: "string",
description: "A name for the query",
},
},
required: ["query", "name"],
},
};
export const GET_EXAMPLES_TOOL: Tool = {
name: "get_examples",
description: "Retrieve example queries for reference",
inputSchema: {
type: "object",
properties: {
category: {
type: "string",
description:
"Category of examples to retrieve: admin, reading, linking, modeling",
},
},
required: ["category"],
},
outputSchema: {
type: "object",
properties: {
content: {
type: "array",
items: {
type: "object",
properties: {
type: { type: "string", enum: ["text"] },
text: { type: "string" },
},
required: ["type", "text"],
},
description: "The example content",
},
},
},
};
export const RETURN_QUERY_TOOL: Tool = {
name: "return_query",
description: "Return a query result from recent queries based on an identifier",
inputSchema: {
type: "object",
properties: {
id: {
type: "string",
description: "The query identifier",
},
},
required: ["id"],
},
};
// Aggregated tool definitions
export const REGISTERED_TOOL_DEFINITIONS: Tool[] = [
LIST_QUERIES_TOOL,
QUERY_DB_TOOL,
GET_EXAMPLES_TOOL,
RETURN_QUERY_TOOL,
];
/**
* Registers all tool handlers with the provided MCP Server instance.
* Each module's registration function will set up the necessary request handlers.
*/
export function registerAllTools(server: Server) {
// Register a handler for listing tool definitions
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: REGISTERED_TOOL_DEFINITIONS };
});
// Register a handler for CallToolRequestSchema to log incoming tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const toolName = request.params.name;
const toolArgs = request.params.arguments || {};
console.error(
`[MCP] Received tool call for: ${toolName} with arguments:`,
toolArgs
);
// Create the appropriate request object based on the tool name
try {
switch (toolName) {
case "list_queries":
const limit = toolArgs.limit ? toolArgs.limit : 50;
console.error({ ...limit });
const queries = listQueries(limit as number);
return {
content: [{ type: "text", text: JSON.stringify(queries, null, 2) }],
};
case "query_db":
const queryResult = await queryDB({
name: toolArgs.name as string,
query: toolArgs.query as string,
});
return {
content: [
{
type: "text",
text: JSON.stringify((queryResult as any).content, null, 2),
},
],
};
case "get_examples":
return serveExamples(toolArgs.category as string);
case "return_query":
const query = queryStore.getQuery(toolArgs.id as string);
return {
content: [{ type: "text", text: JSON.stringify(query, null, 2) }],
};
default:
throw new Error(`Unknown tool: ${toolName}`);
}
} catch (error) {
console.error(`[MCP] Error handling tool call for ${toolName}:`, error);
throw error;
}
});
}