import { z } from "zod";
import { CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { loadBot } from "../api.js";
import { saveGlif } from "../saved-glifs.js";
import { logger } from "../utils.js";
import type { ToolResponse } from "./index.js";
type CallToolRequest = z.infer<typeof CallToolRequestSchema>;
export const schema = z.object({
id: z.string(),
prefix: z.string().optional(),
});
export const definition = {
name: "save_bot_skills_as_tools",
description: "Save all skills from a bot as individual tools",
inputSchema: {
type: "object",
properties: {
id: {
type: "string",
description: "The ID of the bot whose skills to save",
},
prefix: {
type: "string",
description: "Optional prefix to add to tool names (e.g., 'tshirt_')",
},
},
required: ["id"],
},
};
export async function handler(request: CallToolRequest): Promise<ToolResponse> {
try {
const args = schema.parse(request.params.arguments);
const bot = await loadBot(args.id);
if (!bot.spellsForBot || bot.spellsForBot.length === 0) {
return {
content: [
{
type: "text",
text: `Bot "${bot.name}" has no skills to save.`,
},
],
};
}
const prefix = args.prefix || "";
const savedSkills = [];
// Save each skill as a tool
for (const skill of bot.spellsForBot) {
const skillName = skill.spell?.name || "Unknown Skill";
const spellId = skill.spell?.id || `unknown-${Date.now()}`;
// Sanitize the tool name to match the pattern ^[a-zA-Z0-9_-]{1,64}$
const toolName = `${prefix}${skillName
.replace(/\s+/g, "_")
.replace(/[^a-zA-Z0-9_-]/g, "")
.toLowerCase()}`
.substring(0, 64)
.replace(/_+$/, ""); // Remove trailing underscores
const description =
skill.customDescription || `Skill from ${bot.name} bot`;
const savedGlif = {
id: spellId,
toolName,
name: skill.customName || skillName,
description,
createdAt: new Date().toISOString(),
};
await saveGlif(savedGlif);
savedSkills.push({
name: skillName,
toolName,
});
}
const formattedSkills = savedSkills
.map((s) => `- ${s.name} → Tool: "${s.toolName}"`)
.join("\n");
return {
content: [
{
type: "text",
text: `Successfully saved ${savedSkills.length} skills from bot "${bot.name}" as tools:\n\n${formattedSkills}\n\nYou can now use these tools directly.`,
},
],
};
} catch (error) {
logger.error("Error saving bot skills:", error);
return {
content: [
{
type: "text",
text: `Error saving bot skills: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
}