diff --git a/packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts b/packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts index 46266b33cfc..17853adb92e 100644 --- a/packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts +++ b/packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts @@ -83,7 +83,10 @@ describe('McpProtocolService', () => { }, { provide: SkillService, - useValue: { findFlatSkillsByNames: jest.fn().mockResolvedValue([]) }, + useValue: { + findFlatSkillsByNames: jest.fn().mockResolvedValue([]), + findAllFlatSkills: jest.fn().mockResolvedValue([]), + }, }, ], }).compile(); diff --git a/packages/twenty-server/src/engine/api/mcp/services/mcp-protocol.service.ts b/packages/twenty-server/src/engine/api/mcp/services/mcp-protocol.service.ts index ffcab66eac6..80347552a9a 100644 --- a/packages/twenty-server/src/engine/api/mcp/services/mcp-protocol.service.ts +++ b/packages/twenty-server/src/engine/api/mcp/services/mcp-protocol.service.ts @@ -148,8 +148,16 @@ export class McpProtocolService { inputSchema: executeToolInputSchema, }, [LOAD_SKILL_TOOL_NAME]: { - ...createLoadSkillTool((names) => - this.skillService.findFlatSkillsByNames(names, workspace.id), + ...createLoadSkillTool( + (names) => + this.skillService.findFlatSkillsByNames(names, workspace.id), + async () => { + const skills = await this.skillService.findAllFlatSkills( + workspace.id, + ); + + return skills.map((skill) => skill.name); + }, ), inputSchema: zodSchema(loadSkillInputSchema), }, diff --git a/packages/twenty-server/src/engine/core-modules/tool-provider/tools/index.ts b/packages/twenty-server/src/engine/core-modules/tool-provider/tools/index.ts index 5f19c145cea..d55f21d8b9a 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-provider/tools/index.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-provider/tools/index.ts @@ -18,6 +18,7 @@ export { LOAD_SKILL_TOOL_NAME, createLoadSkillTool, loadSkillInputSchema, + type ListAvailableSkillNamesFunction, type LoadSkillFunction, type LoadSkillInput, type LoadSkillResult, diff --git a/packages/twenty-server/src/engine/core-modules/tool-provider/tools/load-skill.tool.ts b/packages/twenty-server/src/engine/core-modules/tool-provider/tools/load-skill.tool.ts index 442f912647b..692613b4c29 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-provider/tools/load-skill.tool.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-provider/tools/load-skill.tool.ts @@ -24,8 +24,12 @@ export type LoadSkillResult = { }; export type LoadSkillFunction = (names: string[]) => Promise; +export type ListAvailableSkillNamesFunction = () => Promise; -export const createLoadSkillTool = (loadSkills: LoadSkillFunction) => ({ +export const createLoadSkillTool = ( + loadSkills: LoadSkillFunction, + listAvailableSkillNames: ListAvailableSkillNamesFunction, +) => ({ description: 'Load specialized skills for complex tasks. Returns detailed step-by-step instructions for building workflows, dashboards, manipulating data, or managing metadata. Call this before attempting complex operations.', inputSchema: loadSkillInputSchema, @@ -35,9 +39,14 @@ export const createLoadSkillTool = (loadSkills: LoadSkillFunction) => ({ const skills = await loadSkills(skillNames); if (skills.length === 0) { + const availableNames = await listAvailableSkillNames(); + return { skills: [], - message: `No skills found with names: ${skillNames.join(', ')}. Available skills: workflow-building, data-manipulation, dashboard-building, metadata-building, research, code-interpreter, xlsx, pdf, docx, pptx.`, + message: + availableNames.length > 0 + ? `No skills found with names: ${skillNames.join(', ')}. Available skills: ${availableNames.join(', ')}.` + : `No skills found with names: ${skillNames.join(', ')}. No skills are currently available.`, }; } diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/services/chat-execution.service.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/services/chat-execution.service.ts index 239e522981b..888c60d426d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/services/chat-execution.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/services/chat-execution.service.ts @@ -200,8 +200,16 @@ export class ChatExecutionService { toolContext, directTools, ), - [LOAD_SKILL_TOOL_NAME]: createLoadSkillTool((skillNames) => - this.skillService.findFlatSkillsByNames(skillNames, workspace.id), + [LOAD_SKILL_TOOL_NAME]: createLoadSkillTool( + (skillNames) => + this.skillService.findFlatSkillsByNames(skillNames, workspace.id), + async () => { + const skills = await this.skillService.findAllFlatSkills( + workspace.id, + ); + + return skills.map((skill) => skill.name); + }, ), };