@flowdot.ai/mcp-server 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +162 -162
- package/bin/flowdot-mcp.js +15 -15
- package/dist/api-client.d.ts +2 -344
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +2 -784
- package/dist/api-client.js.map +1 -1
- package/dist/resources/index.d.ts +12 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +2204 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +19 -10
- package/dist/server.js.map +1 -1
- package/dist/tools/add-recipe-step.d.ts +23 -0
- package/dist/tools/add-recipe-step.d.ts.map +1 -0
- package/dist/tools/add-recipe-step.js +196 -0
- package/dist/tools/add-recipe-step.js.map +1 -0
- package/dist/tools/add-recipe-store.d.ts +19 -0
- package/dist/tools/add-recipe-store.d.ts.map +1 -0
- package/dist/tools/add-recipe-store.js +116 -0
- package/dist/tools/add-recipe-store.js.map +1 -0
- package/dist/tools/agent-toolkits.d.ts +57 -0
- package/dist/tools/agent-toolkits.d.ts.map +1 -0
- package/dist/tools/agent-toolkits.js +1712 -0
- package/dist/tools/agent-toolkits.js.map +1 -0
- package/dist/tools/append-app-code.d.ts +12 -0
- package/dist/tools/append-app-code.d.ts.map +1 -0
- package/dist/tools/append-app-code.js +83 -0
- package/dist/tools/append-app-code.js.map +1 -0
- package/dist/tools/browse-recipes.d.ts +16 -0
- package/dist/tools/browse-recipes.d.ts.map +1 -0
- package/dist/tools/browse-recipes.js +102 -0
- package/dist/tools/browse-recipes.js.map +1 -0
- package/dist/tools/clone-app.js +20 -20
- package/dist/tools/create-app-file.d.ts +11 -0
- package/dist/tools/create-app-file.d.ts.map +1 -0
- package/dist/tools/create-app-file.js +83 -0
- package/dist/tools/create-app-file.js.map +1 -0
- package/dist/tools/create-app.d.ts.map +1 -1
- package/dist/tools/create-app.js +47 -29
- package/dist/tools/create-app.js.map +1 -1
- package/dist/tools/create-knowledge-category.d.ts +16 -0
- package/dist/tools/create-knowledge-category.d.ts.map +1 -0
- package/dist/tools/create-knowledge-category.js +71 -0
- package/dist/tools/create-knowledge-category.js.map +1 -0
- package/dist/tools/create-recipe.d.ts +16 -0
- package/dist/tools/create-recipe.d.ts.map +1 -0
- package/dist/tools/create-recipe.js +92 -0
- package/dist/tools/create-recipe.js.map +1 -0
- package/dist/tools/delete-app-file.d.ts +11 -0
- package/dist/tools/delete-app-file.d.ts.map +1 -0
- package/dist/tools/delete-app-file.js +52 -0
- package/dist/tools/delete-app-file.js.map +1 -0
- package/dist/tools/delete-app.js +3 -3
- package/dist/tools/delete-knowledge-category.d.ts +12 -0
- package/dist/tools/delete-knowledge-category.d.ts.map +1 -0
- package/dist/tools/delete-knowledge-category.js +40 -0
- package/dist/tools/delete-knowledge-category.js.map +1 -0
- package/dist/tools/delete-knowledge-document.d.ts +12 -0
- package/dist/tools/delete-knowledge-document.d.ts.map +1 -0
- package/dist/tools/delete-knowledge-document.js +40 -0
- package/dist/tools/delete-knowledge-document.js.map +1 -0
- package/dist/tools/delete-recipe-step.d.ts +14 -0
- package/dist/tools/delete-recipe-step.d.ts.map +1 -0
- package/dist/tools/delete-recipe-step.js +65 -0
- package/dist/tools/delete-recipe-step.js.map +1 -0
- package/dist/tools/delete-recipe-store.d.ts +14 -0
- package/dist/tools/delete-recipe-store.d.ts.map +1 -0
- package/dist/tools/delete-recipe-store.js +65 -0
- package/dist/tools/delete-recipe-store.js.map +1 -0
- package/dist/tools/delete-recipe.d.ts +13 -0
- package/dist/tools/delete-recipe.d.ts.map +1 -0
- package/dist/tools/delete-recipe.js +59 -0
- package/dist/tools/delete-recipe.js.map +1 -0
- package/dist/tools/edit-app-code.d.ts +12 -0
- package/dist/tools/edit-app-code.d.ts.map +1 -0
- package/dist/tools/edit-app-code.js +110 -0
- package/dist/tools/edit-app-code.js.map +1 -0
- package/dist/tools/favorite-recipe.d.ts +13 -0
- package/dist/tools/favorite-recipe.d.ts.map +1 -0
- package/dist/tools/favorite-recipe.js +53 -0
- package/dist/tools/favorite-recipe.js.map +1 -0
- package/dist/tools/fork-recipe.d.ts +13 -0
- package/dist/tools/fork-recipe.d.ts.map +1 -0
- package/dist/tools/fork-recipe.js +56 -0
- package/dist/tools/fork-recipe.js.map +1 -0
- package/dist/tools/get-app-file.d.ts +11 -0
- package/dist/tools/get-app-file.d.ts.map +1 -0
- package/dist/tools/get-app-file.js +76 -0
- package/dist/tools/get-app-file.js.map +1 -0
- package/dist/tools/get-app-template.d.ts.map +1 -1
- package/dist/tools/get-app-template.js +65 -21
- package/dist/tools/get-app-template.js.map +1 -1
- package/dist/tools/get-app.js +54 -54
- package/dist/tools/get-knowledge-document.d.ts +12 -0
- package/dist/tools/get-knowledge-document.d.ts.map +1 -0
- package/dist/tools/get-knowledge-document.js +71 -0
- package/dist/tools/get-knowledge-document.js.map +1 -0
- package/dist/tools/get-knowledge-storage.d.ts +10 -0
- package/dist/tools/get-knowledge-storage.d.ts.map +1 -0
- package/dist/tools/get-knowledge-storage.js +54 -0
- package/dist/tools/get-knowledge-storage.js.map +1 -0
- package/dist/tools/get-recipe-definition.d.ts +15 -0
- package/dist/tools/get-recipe-definition.d.ts.map +1 -0
- package/dist/tools/get-recipe-definition.js +70 -0
- package/dist/tools/get-recipe-definition.js.map +1 -0
- package/dist/tools/get-recipe.d.ts +12 -0
- package/dist/tools/get-recipe.d.ts.map +1 -0
- package/dist/tools/get-recipe.js +88 -0
- package/dist/tools/get-recipe.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +301 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/insert-app-code.d.ts +12 -0
- package/dist/tools/insert-app-code.d.ts.map +1 -0
- package/dist/tools/insert-app-code.js +97 -0
- package/dist/tools/insert-app-code.js.map +1 -0
- package/dist/tools/link-app-workflow.js +21 -21
- package/dist/tools/link-recipe.d.ts +14 -0
- package/dist/tools/link-recipe.d.ts.map +1 -0
- package/dist/tools/link-recipe.js +76 -0
- package/dist/tools/link-recipe.js.map +1 -0
- package/dist/tools/list-app-files.d.ts +11 -0
- package/dist/tools/list-app-files.d.ts.map +1 -0
- package/dist/tools/list-app-files.js +84 -0
- package/dist/tools/list-app-files.js.map +1 -0
- package/dist/tools/list-apps.js +8 -8
- package/dist/tools/list-knowledge-categories.d.ts +14 -0
- package/dist/tools/list-knowledge-categories.d.ts.map +1 -0
- package/dist/tools/list-knowledge-categories.js +107 -0
- package/dist/tools/list-knowledge-categories.js.map +1 -0
- package/dist/tools/list-knowledge-documents.d.ts +15 -0
- package/dist/tools/list-knowledge-documents.d.ts.map +1 -0
- package/dist/tools/list-knowledge-documents.js +129 -0
- package/dist/tools/list-knowledge-documents.js.map +1 -0
- package/dist/tools/list-recipe-steps.d.ts +12 -0
- package/dist/tools/list-recipe-steps.d.ts.map +1 -0
- package/dist/tools/list-recipe-steps.js +69 -0
- package/dist/tools/list-recipe-steps.js.map +1 -0
- package/dist/tools/list-recipe-stores.d.ts +12 -0
- package/dist/tools/list-recipe-stores.d.ts.map +1 -0
- package/dist/tools/list-recipe-stores.js +87 -0
- package/dist/tools/list-recipe-stores.js.map +1 -0
- package/dist/tools/list-recipes.d.ts +12 -0
- package/dist/tools/list-recipes.d.ts.map +1 -0
- package/dist/tools/list-recipes.js +92 -0
- package/dist/tools/list-recipes.js.map +1 -0
- package/dist/tools/list-user-teams.d.ts +11 -0
- package/dist/tools/list-user-teams.d.ts.map +1 -0
- package/dist/tools/list-user-teams.js +56 -0
- package/dist/tools/list-user-teams.js.map +1 -0
- package/dist/tools/move-document-to-category.d.ts +13 -0
- package/dist/tools/move-document-to-category.d.ts.map +1 -0
- package/dist/tools/move-document-to-category.js +42 -0
- package/dist/tools/move-document-to-category.js.map +1 -0
- package/dist/tools/prepend-app-code.d.ts +12 -0
- package/dist/tools/prepend-app-code.d.ts.map +1 -0
- package/dist/tools/prepend-app-code.js +79 -0
- package/dist/tools/prepend-app-code.js.map +1 -0
- package/dist/tools/publish-app.js +7 -7
- package/dist/tools/query-knowledge-base.d.ts +18 -0
- package/dist/tools/query-knowledge-base.d.ts.map +1 -0
- package/dist/tools/query-knowledge-base.js +144 -0
- package/dist/tools/query-knowledge-base.js.map +1 -0
- package/dist/tools/rename-app-file.d.ts +11 -0
- package/dist/tools/rename-app-file.d.ts.map +1 -0
- package/dist/tools/rename-app-file.js +64 -0
- package/dist/tools/rename-app-file.js.map +1 -0
- package/dist/tools/reprocess-document.d.ts +12 -0
- package/dist/tools/reprocess-document.d.ts.map +1 -0
- package/dist/tools/reprocess-document.js +40 -0
- package/dist/tools/reprocess-document.js.map +1 -0
- package/dist/tools/search-apps.js +13 -13
- package/dist/tools/search.d.ts +14 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +86 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/set-app-entry-file.d.ts +11 -0
- package/dist/tools/set-app-entry-file.d.ts.map +1 -0
- package/dist/tools/set-app-entry-file.js +56 -0
- package/dist/tools/set-app-entry-file.js.map +1 -0
- package/dist/tools/transfer-document-ownership.d.ts +15 -0
- package/dist/tools/transfer-document-ownership.d.ts.map +1 -0
- package/dist/tools/transfer-document-ownership.js +66 -0
- package/dist/tools/transfer-document-ownership.js.map +1 -0
- package/dist/tools/unlink-app-workflow.js +2 -2
- package/dist/tools/unpublish-app.js +2 -2
- package/dist/tools/update-app-file.d.ts +11 -0
- package/dist/tools/update-app-file.d.ts.map +1 -0
- package/dist/tools/update-app-file.js +73 -0
- package/dist/tools/update-app-file.js.map +1 -0
- package/dist/tools/update-app.d.ts.map +1 -1
- package/dist/tools/update-app.js +8 -1
- package/dist/tools/update-app.js.map +1 -1
- package/dist/tools/update-knowledge-category.d.ts +15 -0
- package/dist/tools/update-knowledge-category.d.ts.map +1 -0
- package/dist/tools/update-knowledge-category.js +74 -0
- package/dist/tools/update-knowledge-category.js.map +1 -0
- package/dist/tools/update-recipe-step.d.ts +22 -0
- package/dist/tools/update-recipe-step.d.ts.map +1 -0
- package/dist/tools/update-recipe-step.js +97 -0
- package/dist/tools/update-recipe-step.js.map +1 -0
- package/dist/tools/update-recipe-store.d.ts +20 -0
- package/dist/tools/update-recipe-store.d.ts.map +1 -0
- package/dist/tools/update-recipe-store.js +98 -0
- package/dist/tools/update-recipe-store.js.map +1 -0
- package/dist/tools/update-recipe.d.ts +18 -0
- package/dist/tools/update-recipe.d.ts.map +1 -0
- package/dist/tools/update-recipe.js +98 -0
- package/dist/tools/update-recipe.js.map +1 -0
- package/dist/tools/upload-document-from-url.d.ts +16 -0
- package/dist/tools/upload-document-from-url.d.ts.map +1 -0
- package/dist/tools/upload-document-from-url.js +73 -0
- package/dist/tools/upload-document-from-url.js.map +1 -0
- package/dist/tools/upload-text-document.d.ts +17 -0
- package/dist/tools/upload-text-document.d.ts.map +1 -0
- package/dist/tools/upload-text-document.js +77 -0
- package/dist/tools/upload-text-document.js.map +1 -0
- package/dist/tools/vote-recipe.d.ts +13 -0
- package/dist/tools/vote-recipe.d.ts.map +1 -0
- package/dist/tools/vote-recipe.js +54 -0
- package/dist/tools/vote-recipe.js.map +1 -0
- package/dist/types.d.ts +3 -666
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/script-validator.d.ts.map +1 -1
- package/dist/utils/script-validator.js +5 -1
- package/dist/utils/script-validator.js.map +1 -1
- package/package.json +62 -54
|
@@ -0,0 +1,1712 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Toolkit MCP Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing MCP agent toolkits - creating, installing, and using
|
|
5
|
+
* custom tool collections for AI agents.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================
|
|
8
|
+
// Discovery & Browsing Tools
|
|
9
|
+
// ============================================
|
|
10
|
+
export const listAgentToolkitsTool = {
|
|
11
|
+
name: 'mcp__flowdot__list_agent_toolkits',
|
|
12
|
+
description: `List your own MCP agent toolkits with optional filtering.
|
|
13
|
+
|
|
14
|
+
Toolkits are collections of custom tools that can be installed and used by AI agents. Each toolkit can contain multiple related tools with shared credentials and configuration.`,
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
search: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Filter toolkits by name or description',
|
|
21
|
+
},
|
|
22
|
+
category: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Filter by category (e.g., "api-integration", "data-processing", "automation")',
|
|
25
|
+
},
|
|
26
|
+
limit: {
|
|
27
|
+
type: 'number',
|
|
28
|
+
description: 'Maximum number of results (default: 50, max: 100)',
|
|
29
|
+
},
|
|
30
|
+
page: {
|
|
31
|
+
type: 'number',
|
|
32
|
+
description: 'Page number for pagination (default: 1)',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export async function handleListAgentToolkits(api, args) {
|
|
38
|
+
try {
|
|
39
|
+
const options = {};
|
|
40
|
+
if (args.search)
|
|
41
|
+
options.search = String(args.search);
|
|
42
|
+
if (args.category)
|
|
43
|
+
options.category = String(args.category);
|
|
44
|
+
if (args.limit)
|
|
45
|
+
options.limit = Number(args.limit);
|
|
46
|
+
if (args.page)
|
|
47
|
+
options.page = Number(args.page);
|
|
48
|
+
const result = await api.listAgentToolkits(options);
|
|
49
|
+
if (!result.data || result.data.length === 0) {
|
|
50
|
+
return {
|
|
51
|
+
content: [{
|
|
52
|
+
type: 'text',
|
|
53
|
+
text: 'No toolkits found. Create your first toolkit using mcp__flowdot__create_agent_toolkit.'
|
|
54
|
+
}],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const toolkitsInfo = result.data.map((toolkit) => {
|
|
58
|
+
const tags = toolkit.tags?.length ? `[${toolkit.tags.join(', ')}]` : '';
|
|
59
|
+
const status = toolkit.visibility === 'public' ? 'Public' : 'Private';
|
|
60
|
+
const verified = toolkit.is_verified ? '✓ Verified' : '';
|
|
61
|
+
return `- **${toolkit.title}** (${toolkit.name})
|
|
62
|
+
ID: ${toolkit.id}
|
|
63
|
+
${toolkit.description || 'No description'}
|
|
64
|
+
Category: ${toolkit.category} | Status: ${status} ${verified}
|
|
65
|
+
Tools: ${toolkit.tools_count} | Installations: ${toolkit.installation_count}
|
|
66
|
+
${tags ? `Tags: ${tags}` : ''}`;
|
|
67
|
+
});
|
|
68
|
+
const text = `Found ${result.total || result.data.length} toolkit(s):
|
|
69
|
+
|
|
70
|
+
${toolkitsInfo.join('\n\n')}`;
|
|
71
|
+
return { content: [{ type: 'text', text }] };
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: 'text', text: `Error listing toolkits: ${message}` }],
|
|
77
|
+
isError: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export const searchAgentToolkitsTool = {
|
|
82
|
+
name: 'mcp__flowdot__search_agent_toolkits',
|
|
83
|
+
description: `Search the public MCP toolkit marketplace for toolkits created by other users.
|
|
84
|
+
|
|
85
|
+
Discover reusable tool collections for various use cases like API integrations, data processing, automation, and more.`,
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
query: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Search query (searches name, title, and description)',
|
|
92
|
+
},
|
|
93
|
+
category: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'Filter by category',
|
|
96
|
+
},
|
|
97
|
+
tags: {
|
|
98
|
+
type: 'array',
|
|
99
|
+
items: { type: 'string' },
|
|
100
|
+
description: 'Filter by tags',
|
|
101
|
+
},
|
|
102
|
+
verified_only: {
|
|
103
|
+
type: 'boolean',
|
|
104
|
+
description: 'Only show verified toolkits (default: false)',
|
|
105
|
+
},
|
|
106
|
+
sort: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
enum: ['trending', 'popular', 'recent', 'most_installed'],
|
|
109
|
+
description: 'Sort order (default: trending)',
|
|
110
|
+
},
|
|
111
|
+
limit: {
|
|
112
|
+
type: 'number',
|
|
113
|
+
description: 'Maximum results per page (default: 20, max: 100)',
|
|
114
|
+
},
|
|
115
|
+
page: {
|
|
116
|
+
type: 'number',
|
|
117
|
+
description: 'Page number (default: 1)',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
export async function handleSearchAgentToolkits(api, args) {
|
|
123
|
+
try {
|
|
124
|
+
const options = {};
|
|
125
|
+
if (args.query)
|
|
126
|
+
options.query = String(args.query);
|
|
127
|
+
if (args.category)
|
|
128
|
+
options.category = String(args.category);
|
|
129
|
+
if (args.tags && Array.isArray(args.tags)) {
|
|
130
|
+
options.tags = args.tags.map(t => String(t));
|
|
131
|
+
}
|
|
132
|
+
if (args.verified_only)
|
|
133
|
+
options.verified_only = Boolean(args.verified_only);
|
|
134
|
+
if (args.sort)
|
|
135
|
+
options.sort = args.sort;
|
|
136
|
+
if (args.limit)
|
|
137
|
+
options.limit = Number(args.limit);
|
|
138
|
+
if (args.page)
|
|
139
|
+
options.page = Number(args.page);
|
|
140
|
+
const result = await api.searchPublicAgentToolkits(options);
|
|
141
|
+
if (!result.data || result.data.length === 0) {
|
|
142
|
+
return {
|
|
143
|
+
content: [{
|
|
144
|
+
type: 'text',
|
|
145
|
+
text: 'No toolkits found matching your search criteria.'
|
|
146
|
+
}],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const toolkitsInfo = result.data.map((toolkit) => {
|
|
150
|
+
const verified = toolkit.is_verified ? '✓ Verified' : '';
|
|
151
|
+
const featured = toolkit.is_featured ? '⭐ Featured' : '';
|
|
152
|
+
return `### ${toolkit.title} ${verified} ${featured}
|
|
153
|
+
- **ID:** ${toolkit.id}
|
|
154
|
+
- **Name:** ${toolkit.name}
|
|
155
|
+
- **Description:** ${toolkit.description || 'No description'}
|
|
156
|
+
- **Category:** ${toolkit.category}
|
|
157
|
+
- **Tools:** ${toolkit.tools_count}
|
|
158
|
+
- **Installations:** ${toolkit.installation_count} | **Votes:** ${toolkit.vote_count || 0}
|
|
159
|
+
- **Author:** ${toolkit.user_name || 'Unknown'}
|
|
160
|
+
${toolkit.tags?.length ? `- **Tags:** ${toolkit.tags.join(', ')}` : ''}
|
|
161
|
+
`;
|
|
162
|
+
});
|
|
163
|
+
const text = `## Toolkit Search Results
|
|
164
|
+
|
|
165
|
+
Found ${result.total || result.data.length} toolkit(s):
|
|
166
|
+
|
|
167
|
+
${toolkitsInfo.join('\n')}`;
|
|
168
|
+
return { content: [{ type: 'text', text }] };
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
172
|
+
return {
|
|
173
|
+
content: [{ type: 'text', text: `Error searching toolkits: ${message}` }],
|
|
174
|
+
isError: true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export const getAgentToolkitTool = {
|
|
179
|
+
name: 'mcp__flowdot__get_agent_toolkit',
|
|
180
|
+
description: `Get detailed information about a specific agent toolkit.
|
|
181
|
+
|
|
182
|
+
Returns comprehensive toolkit details including tools, credentials, and metadata.`,
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
toolkit_id: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'The toolkit ID (hash)',
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
required: ['toolkit_id'],
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
export async function handleGetAgentToolkit(api, args) {
|
|
195
|
+
try {
|
|
196
|
+
const toolkitId = String(args.toolkit_id);
|
|
197
|
+
const toolkit = await api.getAgentToolkit(toolkitId);
|
|
198
|
+
const verified = toolkit.is_verified ? '✓ Verified' : '';
|
|
199
|
+
const text = `# ${toolkit.title} ${verified}
|
|
200
|
+
|
|
201
|
+
**ID:** ${toolkit.id}
|
|
202
|
+
**Name:** ${toolkit.name}
|
|
203
|
+
**Category:** ${toolkit.category}
|
|
204
|
+
**Version:** ${toolkit.version}
|
|
205
|
+
**Visibility:** ${toolkit.visibility}
|
|
206
|
+
**Author:** ${toolkit.user_name || 'Unknown'}
|
|
207
|
+
|
|
208
|
+
**Description:**
|
|
209
|
+
${toolkit.description || 'No description'}
|
|
210
|
+
|
|
211
|
+
**Stats:**
|
|
212
|
+
- Tools: ${toolkit.tools_count}
|
|
213
|
+
- Installations: ${toolkit.installation_count}
|
|
214
|
+
- Votes: ${toolkit.vote_count || 0}
|
|
215
|
+
- Copies: ${toolkit.copy_count}
|
|
216
|
+
|
|
217
|
+
${toolkit.tags?.length ? `**Tags:** ${toolkit.tags.join(', ')}` : ''}
|
|
218
|
+
|
|
219
|
+
${toolkit.tools && toolkit.tools.length > 0 ? `
|
|
220
|
+
**Tools:**
|
|
221
|
+
${toolkit.tools.map(tool => `- ${tool.name}: ${tool.description}`).join('\n')}
|
|
222
|
+
` : ''}
|
|
223
|
+
|
|
224
|
+
Created: ${toolkit.created_at}
|
|
225
|
+
Updated: ${toolkit.updated_at}`;
|
|
226
|
+
return { content: [{ type: 'text', text }] };
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
230
|
+
return {
|
|
231
|
+
content: [{ type: 'text', text: `Error getting toolkit: ${message}` }],
|
|
232
|
+
isError: true,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export const getToolkitCommentsTool = {
|
|
237
|
+
name: 'mcp__flowdot__get_toolkit_comments',
|
|
238
|
+
description: `Get comments on a toolkit.
|
|
239
|
+
|
|
240
|
+
View community feedback and discussions about a toolkit.`,
|
|
241
|
+
inputSchema: {
|
|
242
|
+
type: 'object',
|
|
243
|
+
properties: {
|
|
244
|
+
toolkit_id: {
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: 'The toolkit ID (hash)',
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
required: ['toolkit_id'],
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
export async function handleGetToolkitComments(api, args) {
|
|
253
|
+
try {
|
|
254
|
+
const toolkitId = String(args.toolkit_id);
|
|
255
|
+
const comments = await api.getToolkitComments(toolkitId);
|
|
256
|
+
if (!comments || comments.length === 0) {
|
|
257
|
+
return {
|
|
258
|
+
content: [{
|
|
259
|
+
type: 'text',
|
|
260
|
+
text: 'No comments yet.'
|
|
261
|
+
}],
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
const formatComment = (comment, indent = 0) => {
|
|
265
|
+
const prefix = ' '.repeat(indent);
|
|
266
|
+
let text = `${prefix}- **${comment.user_name}** (${comment.created_at})\n${prefix} ${comment.content}\n${prefix} Votes: ${comment.vote_count || 0}`;
|
|
267
|
+
if (comment.replies && comment.replies.length > 0) {
|
|
268
|
+
text += '\n' + comment.replies.map((r) => formatComment(r, indent + 1)).join('\n');
|
|
269
|
+
}
|
|
270
|
+
return text;
|
|
271
|
+
};
|
|
272
|
+
const commentsText = comments.map((c) => formatComment(c)).join('\n\n');
|
|
273
|
+
const text = `## Toolkit Comments
|
|
274
|
+
|
|
275
|
+
${commentsText}`;
|
|
276
|
+
return { content: [{ type: 'text', text }] };
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
280
|
+
return {
|
|
281
|
+
content: [{ type: 'text', text: `Error getting comments: ${message}` }],
|
|
282
|
+
isError: true,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// ============================================
|
|
287
|
+
// Toolkit Management Tools
|
|
288
|
+
// ============================================
|
|
289
|
+
export const createAgentToolkitTool = {
|
|
290
|
+
name: 'mcp__flowdot__create_agent_toolkit',
|
|
291
|
+
description: `Create a new MCP agent toolkit.
|
|
292
|
+
|
|
293
|
+
Toolkits organize related tools and credentials for specific integrations or use cases.
|
|
294
|
+
|
|
295
|
+
## Credential Requirements
|
|
296
|
+
|
|
297
|
+
Use credential_requirements to define what credentials users need to provide. Each credential can be:
|
|
298
|
+
- **api_key**: Standard API key (most common)
|
|
299
|
+
- **oauth**: OAuth 2.0 token that can be refreshed via OAuth flow
|
|
300
|
+
- **bearer**: Bearer token
|
|
301
|
+
- **basic**: Basic auth credentials
|
|
302
|
+
- **custom**: Custom credential type
|
|
303
|
+
|
|
304
|
+
## OAuth Configuration
|
|
305
|
+
|
|
306
|
+
For OAuth credentials, set credential_type: "oauth" and provide oauth_config with:
|
|
307
|
+
|
|
308
|
+
Required OAuth fields:
|
|
309
|
+
- **authorization_url**: OAuth authorization endpoint (e.g., "https://api.schwabapi.com/v1/oauth/authorize")
|
|
310
|
+
- **token_endpoint**: Token exchange endpoint (e.g., "https://api.schwabapi.com/v1/oauth/token")
|
|
311
|
+
- **scopes**: Array of OAuth scopes (e.g., ["api"])
|
|
312
|
+
|
|
313
|
+
Client credential references (reference OTHER credentials in the same toolkit):
|
|
314
|
+
- **client_id_credential_key**: Key name of the credential that stores the client ID (e.g., "SCHWAB_APP_KEY")
|
|
315
|
+
- **client_secret_credential_key**: Key name of the credential that stores the client secret (e.g., "SCHWAB_APP_SECRET")
|
|
316
|
+
|
|
317
|
+
Optional OAuth fields:
|
|
318
|
+
- **pkce_enabled**: Enable PKCE (default: true, recommended for security)
|
|
319
|
+
- **auth_error_codes**: HTTP codes indicating auth failure (default: [401, 403])
|
|
320
|
+
- **auth_error_patterns**: Error message patterns indicating auth failure
|
|
321
|
+
- **extra_auth_params**: Additional URL params for authorization request
|
|
322
|
+
|
|
323
|
+
## Example: OAuth Toolkit Setup (e.g., Schwab API)
|
|
324
|
+
|
|
325
|
+
credential_requirements: [
|
|
326
|
+
{
|
|
327
|
+
key_name: "SCHWAB_APP_KEY",
|
|
328
|
+
label: "Schwab App Key (Client ID)",
|
|
329
|
+
credential_type: "api_key",
|
|
330
|
+
is_required: true,
|
|
331
|
+
description: "Your Schwab Developer App Key"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
key_name: "SCHWAB_APP_SECRET",
|
|
335
|
+
label: "Schwab App Secret (Client Secret)",
|
|
336
|
+
credential_type: "api_key",
|
|
337
|
+
is_required: true,
|
|
338
|
+
description: "Your Schwab Developer App Secret"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
key_name: "SCHWAB_ACCESS_TOKEN",
|
|
342
|
+
label: "Schwab Access Token",
|
|
343
|
+
credential_type: "oauth",
|
|
344
|
+
is_required: true,
|
|
345
|
+
description: "OAuth access token (auto-refreshed via Reconnect)",
|
|
346
|
+
oauth_config: {
|
|
347
|
+
authorization_url: "https://api.schwabapi.com/v1/oauth/authorize",
|
|
348
|
+
token_endpoint: "https://api.schwabapi.com/v1/oauth/token",
|
|
349
|
+
scopes: ["api"],
|
|
350
|
+
client_id_credential_key: "SCHWAB_APP_KEY",
|
|
351
|
+
client_secret_credential_key: "SCHWAB_APP_SECRET",
|
|
352
|
+
pkce_enabled: true
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
]`,
|
|
356
|
+
inputSchema: {
|
|
357
|
+
type: 'object',
|
|
358
|
+
properties: {
|
|
359
|
+
name: {
|
|
360
|
+
type: 'string',
|
|
361
|
+
description: 'Unique identifier (lowercase, hyphens only, e.g., "my-api-toolkit")',
|
|
362
|
+
},
|
|
363
|
+
title: {
|
|
364
|
+
type: 'string',
|
|
365
|
+
description: 'Display name (e.g., "My API Toolkit")',
|
|
366
|
+
},
|
|
367
|
+
description: {
|
|
368
|
+
type: 'string',
|
|
369
|
+
description: 'What this toolkit does',
|
|
370
|
+
},
|
|
371
|
+
category: {
|
|
372
|
+
type: 'string',
|
|
373
|
+
description: 'Category (e.g., "api-integration", "data-processing", "automation")',
|
|
374
|
+
},
|
|
375
|
+
version: {
|
|
376
|
+
type: 'string',
|
|
377
|
+
description: 'Version string (default: "1.0.0")',
|
|
378
|
+
},
|
|
379
|
+
icon: {
|
|
380
|
+
type: 'string',
|
|
381
|
+
description: 'Icon name or emoji',
|
|
382
|
+
},
|
|
383
|
+
visibility: {
|
|
384
|
+
type: 'string',
|
|
385
|
+
enum: ['private', 'public', 'unlisted'],
|
|
386
|
+
description: 'Visibility setting (default: "private")',
|
|
387
|
+
},
|
|
388
|
+
tags: {
|
|
389
|
+
type: 'array',
|
|
390
|
+
items: { type: 'string' },
|
|
391
|
+
description: 'Tags for discoverability (max 10)',
|
|
392
|
+
},
|
|
393
|
+
credential_requirements: {
|
|
394
|
+
type: 'array',
|
|
395
|
+
description: 'Credential requirements for the toolkit. Define what API keys, OAuth tokens, or other credentials users need.',
|
|
396
|
+
items: {
|
|
397
|
+
type: 'object',
|
|
398
|
+
properties: {
|
|
399
|
+
key_name: {
|
|
400
|
+
type: 'string',
|
|
401
|
+
description: 'Unique key identifier (e.g., "API_KEY", "SCHWAB_ACCESS_TOKEN")',
|
|
402
|
+
},
|
|
403
|
+
label: {
|
|
404
|
+
type: 'string',
|
|
405
|
+
description: 'Human-readable label (e.g., "Schwab Access Token")',
|
|
406
|
+
},
|
|
407
|
+
credential_type: {
|
|
408
|
+
type: 'string',
|
|
409
|
+
enum: ['api_key', 'oauth', 'bearer', 'basic', 'custom'],
|
|
410
|
+
description: 'Type of credential. Use "oauth" for tokens that can be refreshed via OAuth flow.',
|
|
411
|
+
},
|
|
412
|
+
description: {
|
|
413
|
+
type: 'string',
|
|
414
|
+
description: 'Help text explaining this credential',
|
|
415
|
+
},
|
|
416
|
+
is_required: {
|
|
417
|
+
type: 'boolean',
|
|
418
|
+
description: 'Whether this credential is required (default: true)',
|
|
419
|
+
},
|
|
420
|
+
placeholder: {
|
|
421
|
+
type: 'string',
|
|
422
|
+
description: 'Placeholder text for input field',
|
|
423
|
+
},
|
|
424
|
+
validation_pattern: {
|
|
425
|
+
type: 'string',
|
|
426
|
+
description: 'Regex pattern to validate credential format',
|
|
427
|
+
},
|
|
428
|
+
oauth_config: {
|
|
429
|
+
type: 'object',
|
|
430
|
+
description: 'OAuth configuration (required when credential_type is "oauth")',
|
|
431
|
+
properties: {
|
|
432
|
+
authorization_url: {
|
|
433
|
+
type: 'string',
|
|
434
|
+
description: 'OAuth authorization endpoint URL',
|
|
435
|
+
},
|
|
436
|
+
token_endpoint: {
|
|
437
|
+
type: 'string',
|
|
438
|
+
description: 'OAuth token exchange endpoint URL',
|
|
439
|
+
},
|
|
440
|
+
scopes: {
|
|
441
|
+
type: 'array',
|
|
442
|
+
items: { type: 'string' },
|
|
443
|
+
description: 'OAuth scopes to request',
|
|
444
|
+
},
|
|
445
|
+
client_id_credential_key: {
|
|
446
|
+
type: 'string',
|
|
447
|
+
description: 'Key name of another credential that contains the OAuth client ID',
|
|
448
|
+
},
|
|
449
|
+
client_secret_credential_key: {
|
|
450
|
+
type: 'string',
|
|
451
|
+
description: 'Key name of another credential that contains the OAuth client secret',
|
|
452
|
+
},
|
|
453
|
+
pkce_enabled: {
|
|
454
|
+
type: 'boolean',
|
|
455
|
+
description: 'Enable PKCE for OAuth flow (default: true)',
|
|
456
|
+
},
|
|
457
|
+
auth_error_codes: {
|
|
458
|
+
type: 'array',
|
|
459
|
+
items: { type: 'number' },
|
|
460
|
+
description: 'HTTP status codes that indicate authentication failure (default: [401, 403])',
|
|
461
|
+
},
|
|
462
|
+
auth_error_patterns: {
|
|
463
|
+
type: 'array',
|
|
464
|
+
items: { type: 'string' },
|
|
465
|
+
description: 'Error message patterns that indicate authentication failure',
|
|
466
|
+
},
|
|
467
|
+
extra_auth_params: {
|
|
468
|
+
type: 'object',
|
|
469
|
+
description: 'Additional URL parameters to include in authorization request',
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
required: ['key_name', 'label'],
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
required: ['name', 'title', 'description'],
|
|
479
|
+
},
|
|
480
|
+
};
|
|
481
|
+
export async function handleCreateAgentToolkit(api, args) {
|
|
482
|
+
try {
|
|
483
|
+
const input = {
|
|
484
|
+
name: String(args.name),
|
|
485
|
+
title: String(args.title),
|
|
486
|
+
description: String(args.description),
|
|
487
|
+
};
|
|
488
|
+
if (args.category)
|
|
489
|
+
input.category = String(args.category);
|
|
490
|
+
if (args.version)
|
|
491
|
+
input.version = String(args.version);
|
|
492
|
+
if (args.icon)
|
|
493
|
+
input.icon = String(args.icon);
|
|
494
|
+
if (args.visibility)
|
|
495
|
+
input.visibility = args.visibility;
|
|
496
|
+
if (args.tags && Array.isArray(args.tags)) {
|
|
497
|
+
input.tags = args.tags.map(t => String(t));
|
|
498
|
+
}
|
|
499
|
+
if (args.credential_requirements && Array.isArray(args.credential_requirements)) {
|
|
500
|
+
input.credential_requirements = args.credential_requirements.map((cred) => ({
|
|
501
|
+
key_name: String(cred.key_name),
|
|
502
|
+
label: String(cred.label),
|
|
503
|
+
credential_type: cred.credential_type || 'api_key',
|
|
504
|
+
description: cred.description ? String(cred.description) : undefined,
|
|
505
|
+
is_required: cred.is_required !== undefined ? Boolean(cred.is_required) : true,
|
|
506
|
+
placeholder: cred.placeholder ? String(cred.placeholder) : undefined,
|
|
507
|
+
validation_pattern: cred.validation_pattern ? String(cred.validation_pattern) : undefined,
|
|
508
|
+
oauth_config: cred.oauth_config || undefined,
|
|
509
|
+
}));
|
|
510
|
+
}
|
|
511
|
+
const result = await api.createAgentToolkit(input);
|
|
512
|
+
if (!result) {
|
|
513
|
+
return {
|
|
514
|
+
content: [{ type: 'text', text: 'Failed to create toolkit' }],
|
|
515
|
+
isError: true,
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
const toolkit = result;
|
|
519
|
+
const credsCount = input.credential_requirements?.length || 0;
|
|
520
|
+
const oauthCreds = input.credential_requirements?.filter(c => c.credential_type === 'oauth').length || 0;
|
|
521
|
+
const text = `✓ Toolkit created successfully!
|
|
522
|
+
|
|
523
|
+
**ID:** ${toolkit.id}
|
|
524
|
+
**Name:** ${toolkit.name}
|
|
525
|
+
**Title:** ${toolkit.title}
|
|
526
|
+
**Visibility:** ${toolkit.visibility}
|
|
527
|
+
${credsCount > 0 ? `**Credentials Defined:** ${credsCount} (${oauthCreds} OAuth)` : ''}
|
|
528
|
+
|
|
529
|
+
Next steps:
|
|
530
|
+
1. Add tools to your toolkit using mcp__flowdot__create_toolkit_tool
|
|
531
|
+
2. Install the toolkit using mcp__flowdot__install_toolkit
|
|
532
|
+
3. Configure credential mappings in the installation
|
|
533
|
+
${oauthCreds > 0 ? '4. Use the "Reconnect" button in the UI to authorize OAuth credentials' : ''}`;
|
|
534
|
+
return { content: [{ type: 'text', text }] };
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
538
|
+
return {
|
|
539
|
+
content: [{ type: 'text', text: `Error creating toolkit: ${message}` }],
|
|
540
|
+
isError: true,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
export const updateAgentToolkitTool = {
|
|
545
|
+
name: 'mcp__flowdot__update_agent_toolkit',
|
|
546
|
+
description: `Update an existing agent toolkit's metadata.
|
|
547
|
+
|
|
548
|
+
Modify title, description, category, tags, and other toolkit properties.
|
|
549
|
+
|
|
550
|
+
## Updating Credential Requirements
|
|
551
|
+
|
|
552
|
+
Use credential_requirements to update the toolkit's credential definitions. This REPLACES all existing credentials.
|
|
553
|
+
|
|
554
|
+
For OAuth credentials, include oauth_config with:
|
|
555
|
+
- **authorization_url**: OAuth authorization endpoint
|
|
556
|
+
- **token_endpoint**: Token exchange endpoint
|
|
557
|
+
- **scopes**: Array of OAuth scopes
|
|
558
|
+
- **client_id_credential_key**: Key name of credential containing client ID
|
|
559
|
+
- **client_secret_credential_key**: Key name of credential containing client secret
|
|
560
|
+
- **pkce_enabled**: Enable PKCE (default: true)
|
|
561
|
+
|
|
562
|
+
See mcp__flowdot__create_agent_toolkit documentation for full OAuth configuration details and examples.`,
|
|
563
|
+
inputSchema: {
|
|
564
|
+
type: 'object',
|
|
565
|
+
properties: {
|
|
566
|
+
toolkit_id: {
|
|
567
|
+
type: 'string',
|
|
568
|
+
description: 'The toolkit ID (hash)',
|
|
569
|
+
},
|
|
570
|
+
name: {
|
|
571
|
+
type: 'string',
|
|
572
|
+
description: 'New name (lowercase, hyphens only)',
|
|
573
|
+
},
|
|
574
|
+
title: {
|
|
575
|
+
type: 'string',
|
|
576
|
+
description: 'New display title',
|
|
577
|
+
},
|
|
578
|
+
description: {
|
|
579
|
+
type: 'string',
|
|
580
|
+
description: 'New description',
|
|
581
|
+
},
|
|
582
|
+
category: {
|
|
583
|
+
type: 'string',
|
|
584
|
+
description: 'New category',
|
|
585
|
+
},
|
|
586
|
+
version: {
|
|
587
|
+
type: 'string',
|
|
588
|
+
description: 'New version',
|
|
589
|
+
},
|
|
590
|
+
icon: {
|
|
591
|
+
type: 'string',
|
|
592
|
+
description: 'New icon',
|
|
593
|
+
},
|
|
594
|
+
tags: {
|
|
595
|
+
type: 'array',
|
|
596
|
+
items: { type: 'string' },
|
|
597
|
+
description: 'New tags',
|
|
598
|
+
},
|
|
599
|
+
credential_requirements: {
|
|
600
|
+
type: 'array',
|
|
601
|
+
description: 'Updated credential requirements (REPLACES all existing). See mcp__flowdot__create_agent_toolkit for schema details.',
|
|
602
|
+
items: {
|
|
603
|
+
type: 'object',
|
|
604
|
+
properties: {
|
|
605
|
+
id: {
|
|
606
|
+
type: 'number',
|
|
607
|
+
description: 'Existing credential ID (include to update, omit for new)',
|
|
608
|
+
},
|
|
609
|
+
key_name: {
|
|
610
|
+
type: 'string',
|
|
611
|
+
description: 'Unique key identifier',
|
|
612
|
+
},
|
|
613
|
+
label: {
|
|
614
|
+
type: 'string',
|
|
615
|
+
description: 'Human-readable label',
|
|
616
|
+
},
|
|
617
|
+
credential_type: {
|
|
618
|
+
type: 'string',
|
|
619
|
+
enum: ['api_key', 'oauth', 'bearer', 'basic', 'custom'],
|
|
620
|
+
description: 'Type of credential',
|
|
621
|
+
},
|
|
622
|
+
description: {
|
|
623
|
+
type: 'string',
|
|
624
|
+
description: 'Help text',
|
|
625
|
+
},
|
|
626
|
+
is_required: {
|
|
627
|
+
type: 'boolean',
|
|
628
|
+
description: 'Whether required',
|
|
629
|
+
},
|
|
630
|
+
placeholder: {
|
|
631
|
+
type: 'string',
|
|
632
|
+
description: 'Placeholder text',
|
|
633
|
+
},
|
|
634
|
+
validation_pattern: {
|
|
635
|
+
type: 'string',
|
|
636
|
+
description: 'Validation regex',
|
|
637
|
+
},
|
|
638
|
+
oauth_config: {
|
|
639
|
+
type: 'object',
|
|
640
|
+
description: 'OAuth configuration for oauth credential type',
|
|
641
|
+
properties: {
|
|
642
|
+
authorization_url: { type: 'string' },
|
|
643
|
+
token_endpoint: { type: 'string' },
|
|
644
|
+
scopes: { type: 'array', items: { type: 'string' } },
|
|
645
|
+
client_id_credential_key: { type: 'string' },
|
|
646
|
+
client_secret_credential_key: { type: 'string' },
|
|
647
|
+
pkce_enabled: { type: 'boolean' },
|
|
648
|
+
auth_error_codes: { type: 'array', items: { type: 'number' } },
|
|
649
|
+
auth_error_patterns: { type: 'array', items: { type: 'string' } },
|
|
650
|
+
extra_auth_params: { type: 'object' },
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
required: ['key_name', 'label'],
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
required: ['toolkit_id'],
|
|
659
|
+
},
|
|
660
|
+
};
|
|
661
|
+
export async function handleUpdateAgentToolkit(api, args) {
|
|
662
|
+
try {
|
|
663
|
+
const toolkitId = String(args.toolkit_id);
|
|
664
|
+
const input = {};
|
|
665
|
+
if (args.name)
|
|
666
|
+
input.name = String(args.name);
|
|
667
|
+
if (args.title)
|
|
668
|
+
input.title = String(args.title);
|
|
669
|
+
if (args.description)
|
|
670
|
+
input.description = String(args.description);
|
|
671
|
+
if (args.category)
|
|
672
|
+
input.category = String(args.category);
|
|
673
|
+
if (args.version)
|
|
674
|
+
input.version = String(args.version);
|
|
675
|
+
if (args.icon)
|
|
676
|
+
input.icon = String(args.icon);
|
|
677
|
+
if (args.tags && Array.isArray(args.tags)) {
|
|
678
|
+
input.tags = args.tags.map(t => String(t));
|
|
679
|
+
}
|
|
680
|
+
if (args.credential_requirements && Array.isArray(args.credential_requirements)) {
|
|
681
|
+
input.credential_requirements = args.credential_requirements.map((cred) => ({
|
|
682
|
+
id: cred.id ? Number(cred.id) : undefined,
|
|
683
|
+
key_name: String(cred.key_name),
|
|
684
|
+
label: String(cred.label),
|
|
685
|
+
credential_type: cred.credential_type || 'api_key',
|
|
686
|
+
description: cred.description ? String(cred.description) : undefined,
|
|
687
|
+
is_required: cred.is_required !== undefined ? Boolean(cred.is_required) : true,
|
|
688
|
+
placeholder: cred.placeholder ? String(cred.placeholder) : undefined,
|
|
689
|
+
validation_pattern: cred.validation_pattern ? String(cred.validation_pattern) : undefined,
|
|
690
|
+
oauth_config: cred.oauth_config || undefined,
|
|
691
|
+
}));
|
|
692
|
+
}
|
|
693
|
+
const result = await api.updateAgentToolkit(toolkitId, input);
|
|
694
|
+
if (!result) {
|
|
695
|
+
return {
|
|
696
|
+
content: [{ type: 'text', text: 'Failed to update toolkit' }],
|
|
697
|
+
isError: true,
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
const credsUpdated = input.credential_requirements ? ` (${input.credential_requirements.length} credentials)` : '';
|
|
701
|
+
const text = `✓ Toolkit updated successfully!${credsUpdated}
|
|
702
|
+
|
|
703
|
+
**ID:** ${result.id}
|
|
704
|
+
**Title:** ${result.title}`;
|
|
705
|
+
return { content: [{ type: 'text', text }] };
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
709
|
+
return {
|
|
710
|
+
content: [{ type: 'text', text: `Error updating toolkit: ${message}` }],
|
|
711
|
+
isError: true,
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
export const deleteAgentToolkitTool = {
|
|
716
|
+
name: 'mcp__flowdot__delete_agent_toolkit',
|
|
717
|
+
description: `Delete a toolkit permanently.
|
|
718
|
+
|
|
719
|
+
WARNING: This cannot be undone. All tools, installations, and related data will be deleted.`,
|
|
720
|
+
inputSchema: {
|
|
721
|
+
type: 'object',
|
|
722
|
+
properties: {
|
|
723
|
+
toolkit_id: {
|
|
724
|
+
type: 'string',
|
|
725
|
+
description: 'The toolkit ID (hash)',
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
required: ['toolkit_id'],
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
export async function handleDeleteAgentToolkit(api, args) {
|
|
732
|
+
try {
|
|
733
|
+
const toolkitId = String(args.toolkit_id);
|
|
734
|
+
const result = await api.deleteAgentToolkit(toolkitId);
|
|
735
|
+
const text = result.success
|
|
736
|
+
? `✓ Toolkit deleted successfully.`
|
|
737
|
+
: `Error: ${'Failed to delete toolkit'}`;
|
|
738
|
+
return {
|
|
739
|
+
content: [{ type: 'text', text }],
|
|
740
|
+
isError: !result.success,
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
745
|
+
return {
|
|
746
|
+
content: [{ type: 'text', text: `Error deleting toolkit: ${message}` }],
|
|
747
|
+
isError: true,
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
export const copyAgentToolkitTool = {
|
|
752
|
+
name: 'mcp__flowdot__copy_agent_toolkit',
|
|
753
|
+
description: `Copy/duplicate a toolkit.
|
|
754
|
+
|
|
755
|
+
Creates a private copy of a toolkit that you can customize.`,
|
|
756
|
+
inputSchema: {
|
|
757
|
+
type: 'object',
|
|
758
|
+
properties: {
|
|
759
|
+
toolkit_id: {
|
|
760
|
+
type: 'string',
|
|
761
|
+
description: 'The toolkit ID to copy',
|
|
762
|
+
},
|
|
763
|
+
name: {
|
|
764
|
+
type: 'string',
|
|
765
|
+
description: 'New name for the copy (optional, auto-generated if not provided)',
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
required: ['toolkit_id'],
|
|
769
|
+
},
|
|
770
|
+
};
|
|
771
|
+
export async function handleCopyAgentToolkit(api, args) {
|
|
772
|
+
try {
|
|
773
|
+
const toolkitId = String(args.toolkit_id);
|
|
774
|
+
const name = args.name ? String(args.name) : undefined;
|
|
775
|
+
const result = await api.copyAgentToolkit(toolkitId, name);
|
|
776
|
+
if (!result) {
|
|
777
|
+
return {
|
|
778
|
+
content: [{ type: 'text', text: 'Failed to copy toolkit' }],
|
|
779
|
+
isError: true,
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
const text = `✓ Toolkit copied successfully!
|
|
783
|
+
|
|
784
|
+
**New ID:** ${result.id}
|
|
785
|
+
**Name:** ${result.name}
|
|
786
|
+
**Title:** ${result.title}
|
|
787
|
+
|
|
788
|
+
The copy is private. You can now customize it as needed.`;
|
|
789
|
+
return { content: [{ type: 'text', text }] };
|
|
790
|
+
}
|
|
791
|
+
catch (error) {
|
|
792
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
793
|
+
return {
|
|
794
|
+
content: [{ type: 'text', text: `Error copying toolkit: ${message}` }],
|
|
795
|
+
isError: true,
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
export const toggleToolkitVisibilityTool = {
|
|
800
|
+
name: 'mcp__flowdot__toggle_toolkit_visibility',
|
|
801
|
+
description: `Change toolkit visibility (private, public, or unlisted).
|
|
802
|
+
|
|
803
|
+
Public toolkits are searchable by others. Unlisted are accessible via direct link only.`,
|
|
804
|
+
inputSchema: {
|
|
805
|
+
type: 'object',
|
|
806
|
+
properties: {
|
|
807
|
+
toolkit_id: {
|
|
808
|
+
type: 'string',
|
|
809
|
+
description: 'The toolkit ID (hash)',
|
|
810
|
+
},
|
|
811
|
+
visibility: {
|
|
812
|
+
type: 'string',
|
|
813
|
+
enum: ['private', 'public', 'unlisted'],
|
|
814
|
+
description: 'New visibility setting',
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
required: ['toolkit_id', 'visibility'],
|
|
818
|
+
},
|
|
819
|
+
};
|
|
820
|
+
export async function handleToggleToolkitVisibility(api, args) {
|
|
821
|
+
try {
|
|
822
|
+
const toolkitId = String(args.toolkit_id);
|
|
823
|
+
const visibility = args.visibility;
|
|
824
|
+
const result = await api.toggleToolkitVisibility(toolkitId, visibility);
|
|
825
|
+
const text = result.success
|
|
826
|
+
? `✓ Toolkit visibility changed to: ${visibility}`
|
|
827
|
+
: `Error: ${'Failed to change visibility'}`;
|
|
828
|
+
return {
|
|
829
|
+
content: [{ type: 'text', text }],
|
|
830
|
+
isError: !result.success,
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
catch (error) {
|
|
834
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
835
|
+
return {
|
|
836
|
+
content: [{ type: 'text', text: `Error changing visibility: ${message}` }],
|
|
837
|
+
isError: true,
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
export const voteToolkitTool = {
|
|
842
|
+
name: 'mcp__flowdot__vote_toolkit',
|
|
843
|
+
description: `Vote on a toolkit (upvote, downvote, or remove your vote).`,
|
|
844
|
+
inputSchema: {
|
|
845
|
+
type: 'object',
|
|
846
|
+
properties: {
|
|
847
|
+
toolkit_id: {
|
|
848
|
+
type: 'string',
|
|
849
|
+
description: 'The toolkit ID (hash)',
|
|
850
|
+
},
|
|
851
|
+
vote: {
|
|
852
|
+
type: 'string',
|
|
853
|
+
enum: ['up', 'down', 'remove'],
|
|
854
|
+
description: 'Vote action',
|
|
855
|
+
},
|
|
856
|
+
},
|
|
857
|
+
required: ['toolkit_id', 'vote'],
|
|
858
|
+
},
|
|
859
|
+
};
|
|
860
|
+
export async function handleVoteToolkit(api, args) {
|
|
861
|
+
try {
|
|
862
|
+
const toolkitId = String(args.toolkit_id);
|
|
863
|
+
const vote = args.vote;
|
|
864
|
+
const result = await api.voteToolkit(toolkitId, vote);
|
|
865
|
+
if (!result) {
|
|
866
|
+
return {
|
|
867
|
+
content: [{ type: 'text', text: 'Failed to vote' }],
|
|
868
|
+
isError: true,
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
const text = `✓ Vote recorded! Current votes: ${result.vote_count}`;
|
|
872
|
+
return { content: [{ type: 'text', text }] };
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
876
|
+
return {
|
|
877
|
+
content: [{ type: 'text', text: `Error voting: ${message}` }],
|
|
878
|
+
isError: true,
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
export const favoriteToolkitTool = {
|
|
883
|
+
name: 'mcp__flowdot__favorite_toolkit',
|
|
884
|
+
description: `Add or remove a toolkit from your favorites.`,
|
|
885
|
+
inputSchema: {
|
|
886
|
+
type: 'object',
|
|
887
|
+
properties: {
|
|
888
|
+
toolkit_id: {
|
|
889
|
+
type: 'string',
|
|
890
|
+
description: 'The toolkit ID (hash)',
|
|
891
|
+
},
|
|
892
|
+
favorite: {
|
|
893
|
+
type: 'boolean',
|
|
894
|
+
description: 'true to favorite, false to unfavorite',
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
required: ['toolkit_id', 'favorite'],
|
|
898
|
+
},
|
|
899
|
+
};
|
|
900
|
+
export async function handleFavoriteToolkit(api, args) {
|
|
901
|
+
try {
|
|
902
|
+
const toolkitId = String(args.toolkit_id);
|
|
903
|
+
const favorite = Boolean(args.favorite);
|
|
904
|
+
const result = await api.favoriteToolkit(toolkitId, favorite);
|
|
905
|
+
if (!result) {
|
|
906
|
+
return {
|
|
907
|
+
content: [{ type: 'text', text: 'Failed to update favorite' }],
|
|
908
|
+
isError: true,
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
const text = favorite
|
|
912
|
+
? `✓ Toolkit added to favorites!`
|
|
913
|
+
: `✓ Toolkit removed from favorites.`;
|
|
914
|
+
return { content: [{ type: 'text', text }] };
|
|
915
|
+
}
|
|
916
|
+
catch (error) {
|
|
917
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
918
|
+
return {
|
|
919
|
+
content: [{ type: 'text', text: `Error updating favorite: ${message}` }],
|
|
920
|
+
isError: true,
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
export const addToolkitCommentTool = {
|
|
925
|
+
name: 'mcp__flowdot__add_toolkit_comment',
|
|
926
|
+
description: `Add a comment to a toolkit.
|
|
927
|
+
|
|
928
|
+
Share feedback, ask questions, or discuss the toolkit with the community.`,
|
|
929
|
+
inputSchema: {
|
|
930
|
+
type: 'object',
|
|
931
|
+
properties: {
|
|
932
|
+
toolkit_id: {
|
|
933
|
+
type: 'string',
|
|
934
|
+
description: 'The toolkit ID (hash)',
|
|
935
|
+
},
|
|
936
|
+
content: {
|
|
937
|
+
type: 'string',
|
|
938
|
+
description: 'Comment content (max 2000 characters)',
|
|
939
|
+
},
|
|
940
|
+
parent_id: {
|
|
941
|
+
type: 'number',
|
|
942
|
+
description: 'Parent comment ID (for replies, optional)',
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
required: ['toolkit_id', 'content'],
|
|
946
|
+
},
|
|
947
|
+
};
|
|
948
|
+
export async function handleAddToolkitComment(api, args) {
|
|
949
|
+
try {
|
|
950
|
+
const toolkitId = String(args.toolkit_id);
|
|
951
|
+
const content = String(args.content);
|
|
952
|
+
const parentId = args.parent_id ? Number(args.parent_id) : undefined;
|
|
953
|
+
const result = await api.addToolkitComment(toolkitId, content, parentId);
|
|
954
|
+
if (!result) {
|
|
955
|
+
return {
|
|
956
|
+
content: [{ type: 'text', text: 'Failed to add comment' }],
|
|
957
|
+
isError: true,
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
const text = `✓ Comment added successfully!`;
|
|
961
|
+
return { content: [{ type: 'text', text }] };
|
|
962
|
+
}
|
|
963
|
+
catch (error) {
|
|
964
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
965
|
+
return {
|
|
966
|
+
content: [{ type: 'text', text: `Error adding comment: ${message}` }],
|
|
967
|
+
isError: true,
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
// ============================================
|
|
972
|
+
// Installation Management Tools
|
|
973
|
+
// ============================================
|
|
974
|
+
export const installToolkitTool = {
|
|
975
|
+
name: 'mcp__flowdot__install_toolkit',
|
|
976
|
+
description: `Install a toolkit to your account.
|
|
977
|
+
|
|
978
|
+
After installation, you can configure credentials and use the toolkit's tools.`,
|
|
979
|
+
inputSchema: {
|
|
980
|
+
type: 'object',
|
|
981
|
+
properties: {
|
|
982
|
+
toolkit_id: {
|
|
983
|
+
type: 'string',
|
|
984
|
+
description: 'The toolkit ID to install',
|
|
985
|
+
},
|
|
986
|
+
},
|
|
987
|
+
required: ['toolkit_id'],
|
|
988
|
+
},
|
|
989
|
+
};
|
|
990
|
+
export async function handleInstallToolkit(api, args) {
|
|
991
|
+
try {
|
|
992
|
+
const toolkitId = String(args.toolkit_id);
|
|
993
|
+
const result = await api.installToolkit(toolkitId);
|
|
994
|
+
if (!result) {
|
|
995
|
+
return {
|
|
996
|
+
content: [{ type: 'text', text: 'Failed to install toolkit' }],
|
|
997
|
+
isError: true,
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
const installation = result;
|
|
1001
|
+
const text = `✓ Toolkit installed successfully!
|
|
1002
|
+
|
|
1003
|
+
**Installation ID:** ${installation.id}
|
|
1004
|
+
**Toolkit:** ${installation.toolkit_name}
|
|
1005
|
+
**Status:** ${installation.is_active ? 'Active' : 'Inactive'}
|
|
1006
|
+
**Credentials:** ${installation.credentials_configured ? 'Configured' : 'Not configured'}
|
|
1007
|
+
|
|
1008
|
+
${!installation.credentials_configured ? `
|
|
1009
|
+
⚠️ Missing credentials: ${installation.missing_credentials.join(', ')}
|
|
1010
|
+
|
|
1011
|
+
Next steps:
|
|
1012
|
+
1. Use mcp__flowdot__check_toolkit_credentials to see required credentials
|
|
1013
|
+
2. Use mcp__flowdot__update_toolkit_installation to map credentials
|
|
1014
|
+
3. Use mcp__flowdot__toggle_toolkit_active to activate
|
|
1015
|
+
` : 'You can now use this toolkit!'}`;
|
|
1016
|
+
return { content: [{ type: 'text', text }] };
|
|
1017
|
+
}
|
|
1018
|
+
catch (error) {
|
|
1019
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1020
|
+
return {
|
|
1021
|
+
content: [{ type: 'text', text: `Error installing toolkit: ${message}` }],
|
|
1022
|
+
isError: true,
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
export const uninstallToolkitTool = {
|
|
1027
|
+
name: 'mcp__flowdot__uninstall_toolkit',
|
|
1028
|
+
description: `Uninstall a toolkit from your account.
|
|
1029
|
+
|
|
1030
|
+
Removes the installation and credential mapping (toolkit itself remains available).`,
|
|
1031
|
+
inputSchema: {
|
|
1032
|
+
type: 'object',
|
|
1033
|
+
properties: {
|
|
1034
|
+
installation_id: {
|
|
1035
|
+
type: 'string',
|
|
1036
|
+
description: 'The installation ID',
|
|
1037
|
+
},
|
|
1038
|
+
},
|
|
1039
|
+
required: ['installation_id'],
|
|
1040
|
+
},
|
|
1041
|
+
};
|
|
1042
|
+
export async function handleUninstallToolkit(api, args) {
|
|
1043
|
+
try {
|
|
1044
|
+
const installationId = String(args.installation_id);
|
|
1045
|
+
const result = await api.uninstallToolkit(installationId);
|
|
1046
|
+
const text = result.success
|
|
1047
|
+
? `✓ Toolkit uninstalled successfully.`
|
|
1048
|
+
: `Error: ${'Failed to uninstall toolkit'}`;
|
|
1049
|
+
return {
|
|
1050
|
+
content: [{ type: 'text', text }],
|
|
1051
|
+
isError: !result.success,
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
catch (error) {
|
|
1055
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1056
|
+
return {
|
|
1057
|
+
content: [{ type: 'text', text: `Error uninstalling toolkit: ${message}` }],
|
|
1058
|
+
isError: true,
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
export const listInstalledToolkitsTool = {
|
|
1063
|
+
name: 'mcp__flowdot__list_installed_toolkits',
|
|
1064
|
+
description: `List all toolkits you have installed.
|
|
1065
|
+
|
|
1066
|
+
Shows installation status and credential configuration for each toolkit.`,
|
|
1067
|
+
inputSchema: {
|
|
1068
|
+
type: 'object',
|
|
1069
|
+
properties: {},
|
|
1070
|
+
},
|
|
1071
|
+
};
|
|
1072
|
+
export async function handleListInstalledToolkits(api, args) {
|
|
1073
|
+
try {
|
|
1074
|
+
const installations = await api.listInstalledToolkits();
|
|
1075
|
+
if (!installations || installations.length === 0) {
|
|
1076
|
+
return {
|
|
1077
|
+
content: [{
|
|
1078
|
+
type: 'text',
|
|
1079
|
+
text: 'No toolkits installed. Search for toolkits using mcp__flowdot__search_agent_toolkits.'
|
|
1080
|
+
}],
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
const installationsInfo = installations.map((install) => {
|
|
1084
|
+
const status = install.is_active ? '✓ Active' : '○ Inactive';
|
|
1085
|
+
const creds = install.credentials_configured ? '✓ Configured' : '⚠️ Missing credentials';
|
|
1086
|
+
return `- **${install.toolkit_title}** ${status}
|
|
1087
|
+
Installation ID: ${install.id}
|
|
1088
|
+
Toolkit ID: ${install.toolkit_id}
|
|
1089
|
+
Credentials: ${creds}
|
|
1090
|
+
Version: ${install.toolkit_version}
|
|
1091
|
+
Last used: ${install.last_used_at || 'Never'}
|
|
1092
|
+
Usage count: ${install.usage_count}`;
|
|
1093
|
+
});
|
|
1094
|
+
const text = `## Installed Toolkits (${installations.length})
|
|
1095
|
+
|
|
1096
|
+
${installationsInfo.join('\n\n')}`;
|
|
1097
|
+
return { content: [{ type: 'text', text }] };
|
|
1098
|
+
}
|
|
1099
|
+
catch (error) {
|
|
1100
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1101
|
+
return {
|
|
1102
|
+
content: [{ type: 'text', text: `Error listing installations: ${message}` }],
|
|
1103
|
+
isError: true,
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
export const toggleToolkitActiveTool = {
|
|
1108
|
+
name: 'mcp__flowdot__toggle_toolkit_active',
|
|
1109
|
+
description: `Enable or disable a toolkit installation.
|
|
1110
|
+
|
|
1111
|
+
Inactive toolkits won't be available for use but remain installed.`,
|
|
1112
|
+
inputSchema: {
|
|
1113
|
+
type: 'object',
|
|
1114
|
+
properties: {
|
|
1115
|
+
installation_id: {
|
|
1116
|
+
type: 'string',
|
|
1117
|
+
description: 'The installation ID',
|
|
1118
|
+
},
|
|
1119
|
+
is_active: {
|
|
1120
|
+
type: 'boolean',
|
|
1121
|
+
description: 'true to activate, false to deactivate',
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
required: ['installation_id', 'is_active'],
|
|
1125
|
+
},
|
|
1126
|
+
};
|
|
1127
|
+
export async function handleToggleToolkitActive(api, args) {
|
|
1128
|
+
try {
|
|
1129
|
+
const installationId = String(args.installation_id);
|
|
1130
|
+
const isActive = Boolean(args.is_active);
|
|
1131
|
+
const result = await api.toggleToolkitActive(installationId, isActive);
|
|
1132
|
+
const text = result.success
|
|
1133
|
+
? `✓ Toolkit ${isActive ? 'activated' : 'deactivated'} successfully.`
|
|
1134
|
+
: `Error: ${'Failed to toggle toolkit'}`;
|
|
1135
|
+
return {
|
|
1136
|
+
content: [{ type: 'text', text }],
|
|
1137
|
+
isError: !result.success,
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
catch (error) {
|
|
1141
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1142
|
+
return {
|
|
1143
|
+
content: [{ type: 'text', text: `Error toggling toolkit: ${message}` }],
|
|
1144
|
+
isError: true,
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
export const checkToolkitCredentialsTool = {
|
|
1149
|
+
name: 'mcp__flowdot__check_toolkit_credentials',
|
|
1150
|
+
description: `Check credential status for a toolkit installation.
|
|
1151
|
+
|
|
1152
|
+
Shows which credentials are required and which are missing.`,
|
|
1153
|
+
inputSchema: {
|
|
1154
|
+
type: 'object',
|
|
1155
|
+
properties: {
|
|
1156
|
+
installation_id: {
|
|
1157
|
+
type: 'string',
|
|
1158
|
+
description: 'The installation ID',
|
|
1159
|
+
},
|
|
1160
|
+
},
|
|
1161
|
+
required: ['installation_id'],
|
|
1162
|
+
},
|
|
1163
|
+
};
|
|
1164
|
+
export async function handleCheckToolkitCredentials(api, args) {
|
|
1165
|
+
try {
|
|
1166
|
+
const installationId = String(args.installation_id);
|
|
1167
|
+
const result = await api.checkToolkitCredentials(installationId);
|
|
1168
|
+
if (!result) {
|
|
1169
|
+
return {
|
|
1170
|
+
content: [{ type: 'text', text: 'Failed to check credentials' }],
|
|
1171
|
+
isError: true,
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
const status = result;
|
|
1175
|
+
const requirements = status.required_credentials.map(req => {
|
|
1176
|
+
const required = req.is_required ? '[REQUIRED]' : '[optional]';
|
|
1177
|
+
const missing = status.missing_credentials.includes(req.key_name) ? '⚠️ MISSING' : '✓';
|
|
1178
|
+
return ` ${missing} ${req.label} ${required}
|
|
1179
|
+
Key: ${req.key_name}
|
|
1180
|
+
Type: ${req.credential_type}
|
|
1181
|
+
${req.description || ''}`;
|
|
1182
|
+
});
|
|
1183
|
+
const text = `## Credential Status: ${status.toolkit_name}
|
|
1184
|
+
|
|
1185
|
+
**Status:** ${status.credentials_configured ? '✓ All credentials configured' : '⚠️ Missing required credentials'}
|
|
1186
|
+
|
|
1187
|
+
**Required Credentials:**
|
|
1188
|
+
|
|
1189
|
+
${requirements.join('\n\n')}
|
|
1190
|
+
|
|
1191
|
+
${status.missing_credentials.length > 0 ? `
|
|
1192
|
+
**Missing:** ${status.missing_credentials.join(', ')}
|
|
1193
|
+
|
|
1194
|
+
Use mcp__flowdot__update_toolkit_installation to map these credentials to your API keys.
|
|
1195
|
+
` : ''}`;
|
|
1196
|
+
return { content: [{ type: 'text', text }] };
|
|
1197
|
+
}
|
|
1198
|
+
catch (error) {
|
|
1199
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1200
|
+
return {
|
|
1201
|
+
content: [{ type: 'text', text: `Error checking credentials: ${message}` }],
|
|
1202
|
+
isError: true,
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
export const updateToolkitInstallationTool = {
|
|
1207
|
+
name: 'mcp__flowdot__update_toolkit_installation',
|
|
1208
|
+
description: `Update toolkit installation (configure credential mapping).
|
|
1209
|
+
|
|
1210
|
+
Map toolkit credential requirements to your stored API keys.`,
|
|
1211
|
+
inputSchema: {
|
|
1212
|
+
type: 'object',
|
|
1213
|
+
properties: {
|
|
1214
|
+
installation_id: {
|
|
1215
|
+
type: 'string',
|
|
1216
|
+
description: 'The installation ID',
|
|
1217
|
+
},
|
|
1218
|
+
credential_mapping: {
|
|
1219
|
+
type: 'object',
|
|
1220
|
+
description: 'Map of toolkit credential keys to your API key names (e.g., {"SPOTIFY_API_KEY": "my-spotify-key"})',
|
|
1221
|
+
},
|
|
1222
|
+
},
|
|
1223
|
+
required: ['installation_id', 'credential_mapping'],
|
|
1224
|
+
},
|
|
1225
|
+
};
|
|
1226
|
+
export async function handleUpdateToolkitInstallation(api, args) {
|
|
1227
|
+
try {
|
|
1228
|
+
const installationId = String(args.installation_id);
|
|
1229
|
+
const credentialMapping = args.credential_mapping;
|
|
1230
|
+
const result = await api.updateToolkitInstallation(installationId, credentialMapping);
|
|
1231
|
+
if (!result) {
|
|
1232
|
+
return {
|
|
1233
|
+
content: [{ type: 'text', text: 'Failed to update installation' }],
|
|
1234
|
+
isError: true,
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
const text = `✓ Installation updated successfully!
|
|
1238
|
+
|
|
1239
|
+
**Credentials configured:** ${result.credentials_configured ? 'Yes' : 'No'}
|
|
1240
|
+
|
|
1241
|
+
${result.missing_credentials && result.missing_credentials.length > 0 ? `
|
|
1242
|
+
⚠️ Still missing: ${result.missing_credentials.join(', ')}
|
|
1243
|
+
` : '✓ All credentials configured! You can now use this toolkit.'}`;
|
|
1244
|
+
return { content: [{ type: 'text', text }] };
|
|
1245
|
+
}
|
|
1246
|
+
catch (error) {
|
|
1247
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1248
|
+
return {
|
|
1249
|
+
content: [{ type: 'text', text: `Error updating installation: ${message}` }],
|
|
1250
|
+
isError: true,
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
// ============================================
|
|
1255
|
+
// Execution Tools
|
|
1256
|
+
// ============================================
|
|
1257
|
+
export const invokeToolkitToolTool = {
|
|
1258
|
+
name: 'mcp__flowdot__invoke_toolkit_tool',
|
|
1259
|
+
description: `Execute a tool from an installed toolkit.
|
|
1260
|
+
|
|
1261
|
+
Runs the tool with provided inputs using your configured credentials.
|
|
1262
|
+
|
|
1263
|
+
You can optionally pass credential_overrides to provide dynamic credentials (like tokens from a previous tool call).`,
|
|
1264
|
+
inputSchema: {
|
|
1265
|
+
type: 'object',
|
|
1266
|
+
properties: {
|
|
1267
|
+
installation_id: {
|
|
1268
|
+
type: 'string',
|
|
1269
|
+
description: 'The installation ID',
|
|
1270
|
+
},
|
|
1271
|
+
tool_name: {
|
|
1272
|
+
type: 'string',
|
|
1273
|
+
description: 'The name of the tool to execute',
|
|
1274
|
+
},
|
|
1275
|
+
inputs: {
|
|
1276
|
+
type: 'object',
|
|
1277
|
+
description: 'Tool inputs (as defined by the tool\'s input schema)',
|
|
1278
|
+
},
|
|
1279
|
+
credential_overrides: {
|
|
1280
|
+
type: 'object',
|
|
1281
|
+
description: 'Optional credential overrides (e.g., {"SCHWAB_ACCESS_TOKEN": "token_value"}). Use this to pass fresh tokens from a previous token refresh call.',
|
|
1282
|
+
},
|
|
1283
|
+
},
|
|
1284
|
+
required: ['installation_id', 'tool_name'],
|
|
1285
|
+
},
|
|
1286
|
+
};
|
|
1287
|
+
export async function handleInvokeToolkitTool(api, args) {
|
|
1288
|
+
try {
|
|
1289
|
+
const input = {
|
|
1290
|
+
installation_id: String(args.installation_id),
|
|
1291
|
+
tool_name: String(args.tool_name),
|
|
1292
|
+
inputs: args.inputs || {},
|
|
1293
|
+
credential_overrides: args.credential_overrides,
|
|
1294
|
+
};
|
|
1295
|
+
const result = await api.invokeToolkitTool(input);
|
|
1296
|
+
if (!result.success) {
|
|
1297
|
+
return {
|
|
1298
|
+
content: [{ type: 'text', text: result.error || 'Tool execution failed' }],
|
|
1299
|
+
isError: true,
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
const text = `✓ Tool executed successfully!
|
|
1303
|
+
|
|
1304
|
+
**Result:**
|
|
1305
|
+
${JSON.stringify(result.data, null, 2)}
|
|
1306
|
+
|
|
1307
|
+
${result.execution_time_ms ? `Execution time: ${result.execution_time_ms}ms` : ''}`;
|
|
1308
|
+
return { content: [{ type: 'text', text }] };
|
|
1309
|
+
}
|
|
1310
|
+
catch (error) {
|
|
1311
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1312
|
+
return {
|
|
1313
|
+
content: [{ type: 'text', text: `Error invoking tool: ${message}` }],
|
|
1314
|
+
isError: true,
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
// ============================================
|
|
1319
|
+
// Tool Management Tools (Read-Only)
|
|
1320
|
+
// ============================================
|
|
1321
|
+
export const listToolkitToolsTool = {
|
|
1322
|
+
name: 'mcp__flowdot__list_toolkit_tools',
|
|
1323
|
+
description: `List all tools in a toolkit.
|
|
1324
|
+
|
|
1325
|
+
Shows tool names, descriptions, and types (HTTP or Workflow).`,
|
|
1326
|
+
inputSchema: {
|
|
1327
|
+
type: 'object',
|
|
1328
|
+
properties: {
|
|
1329
|
+
toolkit_id: {
|
|
1330
|
+
type: 'string',
|
|
1331
|
+
description: 'The toolkit ID (hash)',
|
|
1332
|
+
},
|
|
1333
|
+
},
|
|
1334
|
+
required: ['toolkit_id'],
|
|
1335
|
+
},
|
|
1336
|
+
};
|
|
1337
|
+
export async function handleListToolkitTools(api, args) {
|
|
1338
|
+
try {
|
|
1339
|
+
const toolkitId = String(args.toolkit_id);
|
|
1340
|
+
const tools = await api.listToolkitTools(toolkitId);
|
|
1341
|
+
if (!tools || tools.length === 0) {
|
|
1342
|
+
return {
|
|
1343
|
+
content: [{
|
|
1344
|
+
type: 'text',
|
|
1345
|
+
text: 'No tools in this toolkit.'
|
|
1346
|
+
}],
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
const toolsInfo = tools.map((tool) => {
|
|
1350
|
+
const enabled = tool.is_enabled ? '✓' : '○';
|
|
1351
|
+
const creds = tool.credential_keys && tool.credential_keys.length > 0
|
|
1352
|
+
? `Requires: ${tool.credential_keys.join(', ')}`
|
|
1353
|
+
: 'No credentials required';
|
|
1354
|
+
return `${enabled} **${tool.title}** (${tool.name})
|
|
1355
|
+
Type: ${tool.tool_type}
|
|
1356
|
+
Description: ${tool.description}
|
|
1357
|
+
${creds}`;
|
|
1358
|
+
});
|
|
1359
|
+
const text = `## Toolkit Tools (${tools.length})
|
|
1360
|
+
|
|
1361
|
+
${toolsInfo.join('\n\n')}`;
|
|
1362
|
+
return { content: [{ type: 'text', text }] };
|
|
1363
|
+
}
|
|
1364
|
+
catch (error) {
|
|
1365
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1366
|
+
return {
|
|
1367
|
+
content: [{ type: 'text', text: `Error listing tools: ${message}` }],
|
|
1368
|
+
isError: true,
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
export const getToolkitToolTool = {
|
|
1373
|
+
name: 'mcp__flowdot__get_toolkit_tool',
|
|
1374
|
+
description: `Get detailed information about a specific tool in a toolkit.
|
|
1375
|
+
|
|
1376
|
+
Shows input schema, configuration, and requirements.`,
|
|
1377
|
+
inputSchema: {
|
|
1378
|
+
type: 'object',
|
|
1379
|
+
properties: {
|
|
1380
|
+
toolkit_id: {
|
|
1381
|
+
type: 'string',
|
|
1382
|
+
description: 'The toolkit ID (hash)',
|
|
1383
|
+
},
|
|
1384
|
+
tool_id: {
|
|
1385
|
+
type: 'string',
|
|
1386
|
+
description: 'The tool ID',
|
|
1387
|
+
},
|
|
1388
|
+
},
|
|
1389
|
+
required: ['toolkit_id', 'tool_id'],
|
|
1390
|
+
},
|
|
1391
|
+
};
|
|
1392
|
+
export async function handleGetToolkitTool(api, args) {
|
|
1393
|
+
try {
|
|
1394
|
+
const toolkitId = String(args.toolkit_id);
|
|
1395
|
+
const toolId = String(args.tool_id);
|
|
1396
|
+
const result = await api.getToolkitTool(toolkitId, toolId);
|
|
1397
|
+
if (!result) {
|
|
1398
|
+
return {
|
|
1399
|
+
content: [{ type: 'text', text: 'Tool not found.' }],
|
|
1400
|
+
isError: true,
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
const tool = result;
|
|
1404
|
+
const text = `# ${tool.title}
|
|
1405
|
+
|
|
1406
|
+
**Name:** ${tool.name}
|
|
1407
|
+
**Type:** ${tool.tool_type}
|
|
1408
|
+
**Status:** ${tool.is_enabled ? 'Enabled' : 'Disabled'}
|
|
1409
|
+
|
|
1410
|
+
**Description:**
|
|
1411
|
+
${tool.description}
|
|
1412
|
+
|
|
1413
|
+
**Input Schema:**
|
|
1414
|
+
${JSON.stringify(tool.input_schema, null, 2)}
|
|
1415
|
+
|
|
1416
|
+
${tool.credential_keys && tool.credential_keys.length > 0 ? `
|
|
1417
|
+
**Required Credentials:**
|
|
1418
|
+
${tool.credential_keys.join(', ')}
|
|
1419
|
+
` : ''}
|
|
1420
|
+
|
|
1421
|
+
${tool.tool_type === 'http' && tool.endpoint_config ? `
|
|
1422
|
+
**HTTP Configuration:**
|
|
1423
|
+
- URL: ${tool.endpoint_config.url}
|
|
1424
|
+
- Method: ${tool.endpoint_config.method}
|
|
1425
|
+
` : ''}
|
|
1426
|
+
|
|
1427
|
+
${tool.tool_type === 'workflow' && tool.workflow_hash ? `
|
|
1428
|
+
**Workflow:** ${tool.workflow_hash}
|
|
1429
|
+
` : ''}
|
|
1430
|
+
|
|
1431
|
+
**Timeout:** ${tool.timeout_ms || 30000}ms`;
|
|
1432
|
+
return { content: [{ type: 'text', text }] };
|
|
1433
|
+
}
|
|
1434
|
+
catch (error) {
|
|
1435
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1436
|
+
return {
|
|
1437
|
+
content: [{ type: 'text', text: `Error getting tool: ${message}` }],
|
|
1438
|
+
isError: true,
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
export const createToolkitToolTool = {
|
|
1443
|
+
name: 'mcp__flowdot__create_toolkit_tool',
|
|
1444
|
+
description: `Create a new tool in a toolkit.
|
|
1445
|
+
|
|
1446
|
+
Add HTTP or Workflow-based tools to your agent toolkit with custom input/output schemas and credentials.`,
|
|
1447
|
+
inputSchema: {
|
|
1448
|
+
type: 'object',
|
|
1449
|
+
properties: {
|
|
1450
|
+
toolkit_id: {
|
|
1451
|
+
type: 'string',
|
|
1452
|
+
description: 'The toolkit ID (hash)',
|
|
1453
|
+
},
|
|
1454
|
+
name: {
|
|
1455
|
+
type: 'string',
|
|
1456
|
+
description: 'Unique tool name (lowercase, hyphens, e.g., "get-weather")',
|
|
1457
|
+
},
|
|
1458
|
+
title: {
|
|
1459
|
+
type: 'string',
|
|
1460
|
+
description: 'Display title (e.g., "Get Weather Data")',
|
|
1461
|
+
},
|
|
1462
|
+
description: {
|
|
1463
|
+
type: 'string',
|
|
1464
|
+
description: 'What this tool does',
|
|
1465
|
+
},
|
|
1466
|
+
tool_type: {
|
|
1467
|
+
type: 'string',
|
|
1468
|
+
enum: ['http', 'workflow'],
|
|
1469
|
+
description: 'Tool type: "http" for REST API calls, "workflow" for FlowDot workflows',
|
|
1470
|
+
},
|
|
1471
|
+
input_schema: {
|
|
1472
|
+
type: 'object',
|
|
1473
|
+
description: 'JSON Schema defining tool inputs',
|
|
1474
|
+
},
|
|
1475
|
+
output_schema: {
|
|
1476
|
+
type: 'object',
|
|
1477
|
+
description: 'Optional JSON Schema defining tool outputs',
|
|
1478
|
+
},
|
|
1479
|
+
endpoint_config: {
|
|
1480
|
+
type: 'object',
|
|
1481
|
+
description: 'HTTP configuration (required if tool_type is "http")',
|
|
1482
|
+
properties: {
|
|
1483
|
+
url: { type: 'string', description: 'API endpoint URL' },
|
|
1484
|
+
method: { type: 'string', enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] },
|
|
1485
|
+
},
|
|
1486
|
+
},
|
|
1487
|
+
workflow_hash: {
|
|
1488
|
+
type: 'string',
|
|
1489
|
+
description: 'FlowDot workflow hash (required if tool_type is "workflow")',
|
|
1490
|
+
},
|
|
1491
|
+
credential_keys: {
|
|
1492
|
+
type: 'array',
|
|
1493
|
+
items: { type: 'string' },
|
|
1494
|
+
description: 'List of credential keys this tool requires (e.g., ["API_KEY", "API_SECRET"])',
|
|
1495
|
+
},
|
|
1496
|
+
timeout_ms: {
|
|
1497
|
+
type: 'number',
|
|
1498
|
+
description: 'Execution timeout in milliseconds (1000-300000, default: 30000)',
|
|
1499
|
+
},
|
|
1500
|
+
is_enabled: {
|
|
1501
|
+
type: 'boolean',
|
|
1502
|
+
description: 'Whether the tool is enabled (default: true)',
|
|
1503
|
+
},
|
|
1504
|
+
},
|
|
1505
|
+
required: ['toolkit_id', 'name', 'title', 'description', 'tool_type', 'input_schema'],
|
|
1506
|
+
},
|
|
1507
|
+
};
|
|
1508
|
+
export async function handleCreateToolkitTool(api, args) {
|
|
1509
|
+
try {
|
|
1510
|
+
const toolkitId = String(args.toolkit_id);
|
|
1511
|
+
const input = {
|
|
1512
|
+
name: String(args.name),
|
|
1513
|
+
title: String(args.title),
|
|
1514
|
+
description: String(args.description),
|
|
1515
|
+
tool_type: args.tool_type,
|
|
1516
|
+
input_schema: args.input_schema,
|
|
1517
|
+
};
|
|
1518
|
+
if (args.output_schema)
|
|
1519
|
+
input.output_schema = args.output_schema;
|
|
1520
|
+
if (args.endpoint_config)
|
|
1521
|
+
input.endpoint_config = args.endpoint_config;
|
|
1522
|
+
if (args.workflow_hash)
|
|
1523
|
+
input.workflow_hash = String(args.workflow_hash);
|
|
1524
|
+
if (args.credential_keys && Array.isArray(args.credential_keys)) {
|
|
1525
|
+
input.credential_keys = args.credential_keys.map(k => String(k));
|
|
1526
|
+
}
|
|
1527
|
+
if (args.timeout_ms)
|
|
1528
|
+
input.timeout_ms = Number(args.timeout_ms);
|
|
1529
|
+
if (args.is_enabled !== undefined)
|
|
1530
|
+
input.is_enabled = Boolean(args.is_enabled);
|
|
1531
|
+
const result = await api.createToolkitTool(toolkitId, input);
|
|
1532
|
+
if (!result) {
|
|
1533
|
+
return {
|
|
1534
|
+
content: [{ type: 'text', text: 'Failed to create tool' }],
|
|
1535
|
+
isError: true,
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
const text = `✓ Tool created successfully!
|
|
1539
|
+
|
|
1540
|
+
**Name:** ${result.name}
|
|
1541
|
+
**Title:** ${result.title}
|
|
1542
|
+
**Type:** ${result.tool_type}
|
|
1543
|
+
**ID:** ${result.id}
|
|
1544
|
+
|
|
1545
|
+
Your tool is now available in the toolkit.`;
|
|
1546
|
+
return { content: [{ type: 'text', text }] };
|
|
1547
|
+
}
|
|
1548
|
+
catch (error) {
|
|
1549
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1550
|
+
return {
|
|
1551
|
+
content: [{ type: 'text', text: `Error creating tool: ${message}` }],
|
|
1552
|
+
isError: true,
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
export const updateToolkitToolTool = {
|
|
1557
|
+
name: 'mcp__flowdot__update_toolkit_tool',
|
|
1558
|
+
description: `Update an existing tool in a toolkit.
|
|
1559
|
+
|
|
1560
|
+
Modify tool configuration, schemas, endpoints, or credentials.`,
|
|
1561
|
+
inputSchema: {
|
|
1562
|
+
type: 'object',
|
|
1563
|
+
properties: {
|
|
1564
|
+
toolkit_id: {
|
|
1565
|
+
type: 'string',
|
|
1566
|
+
description: 'The toolkit ID (hash)',
|
|
1567
|
+
},
|
|
1568
|
+
tool_id: {
|
|
1569
|
+
type: 'string',
|
|
1570
|
+
description: 'The tool ID to update',
|
|
1571
|
+
},
|
|
1572
|
+
name: {
|
|
1573
|
+
type: 'string',
|
|
1574
|
+
description: 'New tool name',
|
|
1575
|
+
},
|
|
1576
|
+
title: {
|
|
1577
|
+
type: 'string',
|
|
1578
|
+
description: 'New title',
|
|
1579
|
+
},
|
|
1580
|
+
description: {
|
|
1581
|
+
type: 'string',
|
|
1582
|
+
description: 'New description',
|
|
1583
|
+
},
|
|
1584
|
+
tool_type: {
|
|
1585
|
+
type: 'string',
|
|
1586
|
+
enum: ['http', 'workflow'],
|
|
1587
|
+
description: 'New tool type',
|
|
1588
|
+
},
|
|
1589
|
+
input_schema: {
|
|
1590
|
+
type: 'object',
|
|
1591
|
+
description: 'New input schema',
|
|
1592
|
+
},
|
|
1593
|
+
output_schema: {
|
|
1594
|
+
type: 'object',
|
|
1595
|
+
description: 'New output schema',
|
|
1596
|
+
},
|
|
1597
|
+
endpoint_config: {
|
|
1598
|
+
type: 'object',
|
|
1599
|
+
description: 'New HTTP configuration',
|
|
1600
|
+
},
|
|
1601
|
+
workflow_hash: {
|
|
1602
|
+
type: 'string',
|
|
1603
|
+
description: 'New workflow hash',
|
|
1604
|
+
},
|
|
1605
|
+
credential_keys: {
|
|
1606
|
+
type: 'array',
|
|
1607
|
+
items: { type: 'string' },
|
|
1608
|
+
description: 'New credential keys list',
|
|
1609
|
+
},
|
|
1610
|
+
timeout_ms: {
|
|
1611
|
+
type: 'number',
|
|
1612
|
+
description: 'New timeout in milliseconds',
|
|
1613
|
+
},
|
|
1614
|
+
is_enabled: {
|
|
1615
|
+
type: 'boolean',
|
|
1616
|
+
description: 'Enable or disable the tool',
|
|
1617
|
+
},
|
|
1618
|
+
},
|
|
1619
|
+
required: ['toolkit_id', 'tool_id'],
|
|
1620
|
+
},
|
|
1621
|
+
};
|
|
1622
|
+
export async function handleUpdateToolkitTool(api, args) {
|
|
1623
|
+
try {
|
|
1624
|
+
const toolkitId = String(args.toolkit_id);
|
|
1625
|
+
const toolId = String(args.tool_id);
|
|
1626
|
+
const input = {};
|
|
1627
|
+
if (args.name)
|
|
1628
|
+
input.name = String(args.name);
|
|
1629
|
+
if (args.title)
|
|
1630
|
+
input.title = String(args.title);
|
|
1631
|
+
if (args.description)
|
|
1632
|
+
input.description = String(args.description);
|
|
1633
|
+
if (args.tool_type)
|
|
1634
|
+
input.tool_type = args.tool_type;
|
|
1635
|
+
if (args.input_schema)
|
|
1636
|
+
input.input_schema = args.input_schema;
|
|
1637
|
+
if (args.output_schema)
|
|
1638
|
+
input.output_schema = args.output_schema;
|
|
1639
|
+
if (args.endpoint_config)
|
|
1640
|
+
input.endpoint_config = args.endpoint_config;
|
|
1641
|
+
if (args.workflow_hash)
|
|
1642
|
+
input.workflow_hash = String(args.workflow_hash);
|
|
1643
|
+
if (args.credential_keys && Array.isArray(args.credential_keys)) {
|
|
1644
|
+
input.credential_keys = args.credential_keys.map(k => String(k));
|
|
1645
|
+
}
|
|
1646
|
+
if (args.timeout_ms)
|
|
1647
|
+
input.timeout_ms = Number(args.timeout_ms);
|
|
1648
|
+
if (args.is_enabled !== undefined)
|
|
1649
|
+
input.is_enabled = Boolean(args.is_enabled);
|
|
1650
|
+
const result = await api.updateToolkitTool(toolkitId, toolId, input);
|
|
1651
|
+
if (!result) {
|
|
1652
|
+
return {
|
|
1653
|
+
content: [{ type: 'text', text: 'Failed to update tool' }],
|
|
1654
|
+
isError: true,
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
const text = `✓ Tool updated successfully!
|
|
1658
|
+
|
|
1659
|
+
**Name:** ${result.name}
|
|
1660
|
+
**Title:** ${result.title}`;
|
|
1661
|
+
return { content: [{ type: 'text', text }] };
|
|
1662
|
+
}
|
|
1663
|
+
catch (error) {
|
|
1664
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1665
|
+
return {
|
|
1666
|
+
content: [{ type: 'text', text: `Error updating tool: ${message}` }],
|
|
1667
|
+
isError: true,
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
export const deleteToolkitToolTool = {
|
|
1672
|
+
name: 'mcp__flowdot__delete_toolkit_tool',
|
|
1673
|
+
description: `Delete a tool from a toolkit.
|
|
1674
|
+
|
|
1675
|
+
WARNING: This cannot be undone. The tool will be permanently removed.`,
|
|
1676
|
+
inputSchema: {
|
|
1677
|
+
type: 'object',
|
|
1678
|
+
properties: {
|
|
1679
|
+
toolkit_id: {
|
|
1680
|
+
type: 'string',
|
|
1681
|
+
description: 'The toolkit ID (hash)',
|
|
1682
|
+
},
|
|
1683
|
+
tool_id: {
|
|
1684
|
+
type: 'string',
|
|
1685
|
+
description: 'The tool ID to delete',
|
|
1686
|
+
},
|
|
1687
|
+
},
|
|
1688
|
+
required: ['toolkit_id', 'tool_id'],
|
|
1689
|
+
},
|
|
1690
|
+
};
|
|
1691
|
+
export async function handleDeleteToolkitTool(api, args) {
|
|
1692
|
+
try {
|
|
1693
|
+
const toolkitId = String(args.toolkit_id);
|
|
1694
|
+
const toolId = String(args.tool_id);
|
|
1695
|
+
const result = await api.deleteToolkitTool(toolkitId, toolId);
|
|
1696
|
+
const text = result.success
|
|
1697
|
+
? `✓ Tool deleted successfully.`
|
|
1698
|
+
: `Error: ${'Failed to delete tool'}`;
|
|
1699
|
+
return {
|
|
1700
|
+
content: [{ type: 'text', text }],
|
|
1701
|
+
isError: !result.success,
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
catch (error) {
|
|
1705
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1706
|
+
return {
|
|
1707
|
+
content: [{ type: 'text', text: `Error deleting tool: ${message}` }],
|
|
1708
|
+
isError: true,
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
//# sourceMappingURL=agent-toolkits.js.map
|