import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import type { ToolContext } from "../utils/api.js";
const json = (d: unknown) => ({ type: "text" as const, text: JSON.stringify(d, null, 2) });
export function registerDatasources(server: McpServer, ctx: ToolContext): void {
const { api, requireConfig, buildQuery } = ctx;
server.registerTool(
"fetch_datasources",
{
description: "List datasources. Optional per_page, page.",
inputSchema: { per_page: z.number().optional(), page: z.number().optional() },
},
async (a) => {
requireConfig();
const q = buildQuery({ per_page: a?.per_page, page: a?.page });
const d = await api(`/datasources${q}`);
return { content: [json(d)] };
}
);
server.registerTool(
"get_datasource",
{ description: "Get a datasource by ID.", inputSchema: { datasource_id: z.string() } },
async ({ datasource_id }) => {
requireConfig();
const d = await api(`/datasources/${datasource_id}`);
return { content: [json(d)] };
}
);
server.registerTool(
"create_datasource",
{
description: "Create a datasource. Pass name, slug, and optional dimensions.",
inputSchema: { name: z.string(), slug: z.string(), dimensions: z.array(z.string()).optional() },
},
async (body) => {
requireConfig();
const d = await api("/datasources", { method: "POST", body: JSON.stringify({ datasource: body }) });
return { content: [json(d)] };
}
);
server.registerTool(
"update_datasource",
{
description: "Update a datasource.",
inputSchema: { datasource_id: z.string(), name: z.string().optional(), slug: z.string().optional(), dimensions: z.array(z.string()).optional() },
},
async ({ datasource_id, ...rest }) => {
requireConfig();
const d = await api(`/datasources/${datasource_id}`, { method: "PUT", body: JSON.stringify({ datasource: rest }) });
return { content: [json(d)] };
}
);
server.registerTool(
"delete_datasource",
{ description: "Delete a datasource by ID.", inputSchema: { datasource_id: z.string() } },
async ({ datasource_id }) => {
requireConfig();
await api(`/datasources/${datasource_id}`, { method: "DELETE" });
return { content: [json({ success: true })] };
}
);
server.registerTool(
"fetch_datasource_entries",
{
description: "List entries for a datasource. Optional dimension, per_page, page.",
inputSchema: { datasource_id: z.string(), dimension: z.string().optional(), per_page: z.number().optional(), page: z.number().optional() },
},
async ({ datasource_id, dimension, per_page, page }) => {
requireConfig();
const q = buildQuery({ dimension, per_page, page });
const d = await api(`/datasources/${datasource_id}/entries${q}`);
return { content: [json(d)] };
}
);
server.registerTool(
"create_datasource_entry",
{
description: "Create a datasource entry. Pass name, value, and optional dimension.",
inputSchema: { datasource_id: z.string(), name: z.string(), value: z.string(), dimension: z.string().optional() },
},
async ({ datasource_id, ...body }) => {
requireConfig();
const d = await api(`/datasources/${datasource_id}/entries`, { method: "POST", body: JSON.stringify({ datasource_entry: body }) });
return { content: [json(d)] };
}
);
server.registerTool(
"update_datasource_entry",
{
description: "Update a datasource entry.",
inputSchema: { datasource_id: z.string(), entry_id: z.string(), name: z.string().optional(), value: z.string().optional() },
},
async ({ datasource_id, entry_id, ...rest }) => {
requireConfig();
const d = await api(`/datasources/${datasource_id}/entries/${entry_id}`, { method: "PUT", body: JSON.stringify({ datasource_entry: rest }) });
return { content: [json(d)] };
}
);
server.registerTool(
"delete_datasource_entry",
{ description: "Delete a datasource entry.", inputSchema: { datasource_id: z.string(), entry_id: z.string() } },
async ({ datasource_id, entry_id }) => {
requireConfig();
await api(`/datasources/${datasource_id}/entries/${entry_id}`, { method: "DELETE" });
return { content: [json({ success: true })] };
}
);
}