import { z } from "zod";
import { createApiKey, listApiKeys, revokeApiKey, UserRole } from "../db.js";
import crypto from "crypto";
// --- Tool Definitions ---
export const generateApiKeySchema = {
name: "generate_api_key",
description:
"Generate a new API key for a user (Admin Only). The key is shown ONCE and never stored in plaintext.",
inputSchema: z.object({
role: z
.enum(["user", "admin"])
.default("user")
.describe("Role to assign (default: user)"),
description: z
.string()
.optional()
.describe("Description/Name of the user owner"),
}),
};
export const listApiKeysSchema = {
name: "list_api_keys",
description:
"List all active API keys showing only prefixes for security (Admin Only)",
inputSchema: z.object({}),
};
export const revokeApiKeySchema = {
name: "revoke_api_key",
description: "Revoke/Delete an API key (Admin Only). Requires the full key.",
inputSchema: z.object({
key: z.string().describe("The full API Key to revoke"),
}),
};
// --- Handlers ---
function generateKey(): string {
return "sk-" + crypto.randomBytes(24).toString("hex");
}
export const generateApiKeyHandler = async (args: {
role?: UserRole;
description?: string;
}) => {
const plaintextKey = generateKey();
const { key, record } = await createApiKey(
plaintextKey,
args.role || "user",
args.description,
);
return {
content: [
{
type: "text",
text: `🔐 Generated New API Key (SAVE THIS - it will NOT be shown again!):\n\nKey: ${key}\nRole: ${record.role}\nDescription: ${record.description || "N/A"}\n\n⚠️ This key is hashed in database and cannot be recovered.`,
},
],
};
};
export const listApiKeysHandler = async () => {
const keys = await listApiKeys();
const table = keys
.map((k) => `- ${k.key_prefix} (${k.role}) [${k.description || "No Desc"}]`)
.join("\n");
return {
content: [
{
type: "text",
text: `Active API Keys (prefixes only for security):\n${table}`,
},
],
};
};
export const revokeApiKeyHandler = async (args: { key: string }) => {
const success = await revokeApiKey(args.key);
if (!success) {
throw new Error("Key not found or could not be revoked");
}
return {
content: [{ type: "text", text: `Successfully revoked API key` }],
};
};