@agentled/mcp-server 0.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Agentled
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # @agentled/mcp-server
2
+
3
+ MCP server for [Agentled](https://www.agentled.app) — create, manage, and run automation workflows from Claude Code.
4
+
5
+ ## Quick Setup
6
+
7
+ ```bash
8
+ claude mcp add agentled \
9
+ -e AGENTLED_API_KEY=wsk_... \
10
+ -e AGENTLED_URL=https://www.agentled.app \
11
+ -- agentled-mcp-server
12
+ ```
13
+
14
+ ### Getting your API key
15
+
16
+ 1. Go to your [Agentled workspace](https://www.agentled.app)
17
+ 2. Open **Workspace Settings > Developer**
18
+ 3. Generate a new API key (starts with `wsk_`)
19
+
20
+ ### Environment variables
21
+
22
+ | Variable | Required | Description |
23
+ |----------|----------|-------------|
24
+ | `AGENTLED_API_KEY` | Yes | Workspace API key (`wsk_...`) |
25
+ | `AGENTLED_URL` | No | API base URL (default: `https://www.agentled.app`) |
26
+
27
+ ## Available Tools
28
+
29
+ ### Workflows
30
+
31
+ | Tool | Description |
32
+ |------|-------------|
33
+ | `list_workflows` | List all workflows in the workspace |
34
+ | `get_workflow` | Get full workflow definition by ID |
35
+ | `create_workflow` | Create a new workflow from pipeline JSON |
36
+ | `update_workflow` | Update an existing workflow |
37
+ | `delete_workflow` | Permanently delete a workflow |
38
+ | `validate_workflow` | Validate pipeline structure, returns errors per step |
39
+ | `publish_workflow` | Change workflow status (draft, live, paused, archived) |
40
+ | `export_workflow` | Export a workflow as portable JSON |
41
+ | `import_workflow` | Import a workflow from exported JSON |
42
+
43
+ ### Drafts & Snapshots
44
+
45
+ | Tool | Description |
46
+ |------|-------------|
47
+ | `get_draft` | Get the current draft version of a workflow |
48
+ | `promote_draft` | Promote a draft to the live version |
49
+ | `discard_draft` | Discard the current draft |
50
+ | `list_snapshots` | List version snapshots for a workflow |
51
+ | `restore_snapshot` | Restore a workflow to a previous snapshot |
52
+
53
+ ### Executions
54
+
55
+ | Tool | Description |
56
+ |------|-------------|
57
+ | `start_workflow` | Start a workflow execution with input |
58
+ | `list_executions` | List executions for a workflow |
59
+ | `get_execution` | Get execution details with step results |
60
+ | `stop_execution` | Stop a running execution |
61
+ | `retry_execution` | Retry a failed execution |
62
+
63
+ ### Apps & Testing
64
+
65
+ | Tool | Description |
66
+ |------|-------------|
67
+ | `list_apps` | List available apps and integrations |
68
+ | `get_app_actions` | Get action schemas for an app |
69
+ | `test_app_action` | Test an app action without creating a workflow |
70
+ | `test_ai_action` | Test an AI prompt without creating a workflow |
71
+
72
+ ### Knowledge & Data
73
+
74
+ | Tool | Description |
75
+ |------|-------------|
76
+ | `get_workspace` | Get workspace info and settings |
77
+ | `list_knowledge_lists` | List knowledge lists in the workspace |
78
+ | `get_knowledge_rows` | Get rows from a knowledge list |
79
+ | `get_knowledge_text` | Get text content from a knowledge entry |
80
+ | `query_kg_edges` | Query knowledge graph edges |
81
+ | `get_scoring_history` | Get scoring history for an entity |
82
+
83
+ ### n8n Migration
84
+
85
+ | Tool | Description |
86
+ |------|-------------|
87
+ | `preview_n8n_import` | Preview an n8n workflow import (dry run) |
88
+ | `import_n8n_workflow` | Import an n8n workflow into Agentled |
89
+
90
+ ## Example Usage
91
+
92
+ Once connected, you can ask Claude Code to:
93
+
94
+ - "List my workflows"
95
+ - "Create a workflow that scrapes a URL and summarizes the content"
96
+ - "Show me the last 5 executions of my lead scoring workflow"
97
+ - "Test the LinkedIn company enrichment action with this URL"
98
+
99
+ ## Building from Source
100
+
101
+ ```bash
102
+ git clone https://github.com/agentled/mcp-server.git
103
+ cd mcp-server
104
+ npm install
105
+ npm run build
106
+ ```
107
+
108
+ ## License
109
+
110
+ MIT
@@ -0,0 +1,67 @@
1
+ /**
2
+ * AgentledClient — HTTP client wrapping the /api/external/* routes.
3
+ *
4
+ * Reads AGENTLED_API_KEY and AGENTLED_URL from environment variables.
5
+ */
6
+ export declare class AgentledClient {
7
+ private baseUrl;
8
+ private apiKey;
9
+ constructor();
10
+ private request;
11
+ listWorkflows(params?: {
12
+ status?: string;
13
+ limit?: number;
14
+ }): Promise<any>;
15
+ getWorkflow(id: string): Promise<any>;
16
+ createWorkflow(pipeline: Record<string, any>, locale?: string): Promise<any>;
17
+ updateWorkflow(id: string, updates: Record<string, any>, locale?: string): Promise<any>;
18
+ deleteWorkflow(id: string): Promise<any>;
19
+ validateWorkflow(id: string, pipeline?: Record<string, any>): Promise<any>;
20
+ publishWorkflow(id: string, status: string): Promise<any>;
21
+ listSnapshots(workflowId: string): Promise<any>;
22
+ restoreSnapshot(workflowId: string, snapshotId: string): Promise<any>;
23
+ getDraft(workflowId: string): Promise<any>;
24
+ promoteDraft(workflowId: string): Promise<any>;
25
+ discardDraft(workflowId: string): Promise<any>;
26
+ startWorkflow(id: string, input?: Record<string, any>, metadata?: Record<string, any>): Promise<any>;
27
+ listExecutions(workflowId: string, params?: {
28
+ status?: string;
29
+ limit?: number;
30
+ nextToken?: string;
31
+ direction?: 'asc' | 'desc';
32
+ }): Promise<any>;
33
+ getExecution(workflowId: string, executionId: string): Promise<any>;
34
+ stopExecution(workflowId: string, executionId: string): Promise<any>;
35
+ retryExecution(workflowId: string, executionId: string, options?: {
36
+ timelineId?: string;
37
+ forceWithoutCache?: boolean;
38
+ rerunMode?: string;
39
+ }): Promise<any>;
40
+ listApps(): Promise<any>;
41
+ getAppActions(appId: string): Promise<any>;
42
+ testAppAction(appId: string, actionId: string, input?: Record<string, any>, bypassCache?: boolean): Promise<any>;
43
+ testAiAction(template: string, variables?: Record<string, any>, responseStructure?: Record<string, any>, options?: {
44
+ responseType?: string;
45
+ systemPrompt?: string;
46
+ }): Promise<any>;
47
+ exportWorkflow(id: string): Promise<any>;
48
+ importWorkflow(exportData: Record<string, any>, locale?: string): Promise<any>;
49
+ getWorkspace(): Promise<any>;
50
+ listKnowledgeLists(): Promise<any>;
51
+ getKnowledgeRows(listKey: string, limit?: number): Promise<any>;
52
+ getKnowledgeText(key: string): Promise<any>;
53
+ queryKgEdges(entityName?: string, relationshipType?: string, limit?: number): Promise<any>;
54
+ getScoringHistory(entityName?: string, limit?: number): Promise<any>;
55
+ previewN8nImport(n8nJson: string | Record<string, any>, options?: Record<string, any>, workflow?: {
56
+ name?: string;
57
+ goal?: string;
58
+ description?: string;
59
+ pathname?: string;
60
+ }): Promise<any>;
61
+ importN8nWorkflow(n8nJson: string | Record<string, any>, workflow?: {
62
+ name?: string;
63
+ goal?: string;
64
+ description?: string;
65
+ pathname?: string;
66
+ }, options?: Record<string, any>, locale?: string): Promise<any>;
67
+ }
package/dist/client.js ADDED
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ /**
3
+ * AgentledClient — HTTP client wrapping the /api/external/* routes.
4
+ *
5
+ * Reads AGENTLED_API_KEY and AGENTLED_URL from environment variables.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.AgentledClient = void 0;
9
+ class AgentledClient {
10
+ baseUrl;
11
+ apiKey;
12
+ constructor() {
13
+ this.apiKey = process.env.AGENTLED_API_KEY || '';
14
+ this.baseUrl = (process.env.AGENTLED_URL || 'http://localhost:3000').replace(/\/$/, '');
15
+ if (!this.apiKey) {
16
+ throw new Error('AGENTLED_API_KEY is not set. Generate one in Workspace Settings > Developer.');
17
+ }
18
+ }
19
+ async request(path, options = {}) {
20
+ const url = `${this.baseUrl}/api/external${path}`;
21
+ const response = await fetch(url, {
22
+ ...options,
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'x-api-key': this.apiKey,
26
+ ...options.headers,
27
+ },
28
+ });
29
+ const data = await response.json();
30
+ if (!response.ok) {
31
+ throw new Error(data.error || `HTTP ${response.status}: ${response.statusText}`);
32
+ }
33
+ return data;
34
+ }
35
+ // --- Workflows ---
36
+ async listWorkflows(params) {
37
+ const query = new URLSearchParams();
38
+ if (params?.status)
39
+ query.set('status', params.status);
40
+ if (params?.limit)
41
+ query.set('limit', String(params.limit));
42
+ const qs = query.toString();
43
+ return this.request(`/workflows${qs ? `?${qs}` : ''}`);
44
+ }
45
+ async getWorkflow(id) {
46
+ return this.request(`/workflows/${id}`);
47
+ }
48
+ async createWorkflow(pipeline, locale) {
49
+ return this.request('/workflows', {
50
+ method: 'POST',
51
+ body: JSON.stringify({ pipeline, locale }),
52
+ });
53
+ }
54
+ async updateWorkflow(id, updates, locale) {
55
+ return this.request(`/workflows/${id}`, {
56
+ method: 'PATCH',
57
+ body: JSON.stringify({ updates, locale }),
58
+ });
59
+ }
60
+ async deleteWorkflow(id) {
61
+ return this.request(`/workflows/${id}`, { method: 'DELETE' });
62
+ }
63
+ async validateWorkflow(id, pipeline) {
64
+ return this.request(`/workflows/${id}/validate`, {
65
+ method: 'POST',
66
+ body: JSON.stringify({ pipeline }),
67
+ });
68
+ }
69
+ async publishWorkflow(id, status) {
70
+ return this.request(`/workflows/${id}/status`, {
71
+ method: 'PATCH',
72
+ body: JSON.stringify({ status }),
73
+ });
74
+ }
75
+ async listSnapshots(workflowId) {
76
+ return this.request(`/workflows/${workflowId}/snapshots`);
77
+ }
78
+ async restoreSnapshot(workflowId, snapshotId) {
79
+ return this.request(`/workflows/${workflowId}/snapshots`, {
80
+ method: 'POST',
81
+ body: JSON.stringify({ snapshotId }),
82
+ });
83
+ }
84
+ // --- Draft Lifecycle ---
85
+ async getDraft(workflowId) {
86
+ return this.request(`/workflows/${workflowId}/draft`);
87
+ }
88
+ async promoteDraft(workflowId) {
89
+ return this.request(`/workflows/${workflowId}/draft`, {
90
+ method: 'POST',
91
+ });
92
+ }
93
+ async discardDraft(workflowId) {
94
+ return this.request(`/workflows/${workflowId}/draft`, {
95
+ method: 'DELETE',
96
+ });
97
+ }
98
+ // --- Executions ---
99
+ async startWorkflow(id, input, metadata) {
100
+ return this.request(`/workflows/${id}/start`, {
101
+ method: 'POST',
102
+ body: JSON.stringify({ input, metadata }),
103
+ });
104
+ }
105
+ async listExecutions(workflowId, params) {
106
+ const query = new URLSearchParams();
107
+ if (params?.status)
108
+ query.set('status', params.status);
109
+ if (params?.limit)
110
+ query.set('limit', String(params.limit));
111
+ if (params?.nextToken)
112
+ query.set('nextToken', params.nextToken);
113
+ if (params?.direction)
114
+ query.set('direction', params.direction);
115
+ const qs = query.toString();
116
+ return this.request(`/workflows/${workflowId}/executions${qs ? `?${qs}` : ''}`);
117
+ }
118
+ async getExecution(workflowId, executionId) {
119
+ return this.request(`/workflows/${workflowId}/executions/${executionId}`);
120
+ }
121
+ async stopExecution(workflowId, executionId) {
122
+ return this.request(`/workflows/${workflowId}/executions/${executionId}/stop`, {
123
+ method: 'POST',
124
+ });
125
+ }
126
+ async retryExecution(workflowId, executionId, options) {
127
+ return this.request(`/workflows/${workflowId}/executions/${executionId}/retry`, {
128
+ method: 'POST',
129
+ body: JSON.stringify({
130
+ timelineId: options?.timelineId,
131
+ forceWithoutCache: options?.forceWithoutCache,
132
+ rerunMode: options?.rerunMode,
133
+ }),
134
+ });
135
+ }
136
+ // --- Apps ---
137
+ async listApps() {
138
+ return this.request('/apps');
139
+ }
140
+ async getAppActions(appId) {
141
+ return this.request(`/apps/${appId}/actions`);
142
+ }
143
+ // --- Step Testing ---
144
+ async testAppAction(appId, actionId, input, bypassCache) {
145
+ return this.request('/step/test', {
146
+ method: 'POST',
147
+ body: JSON.stringify({ appId, actionId, input, bypassCache }),
148
+ });
149
+ }
150
+ async testAiAction(template, variables, responseStructure, options) {
151
+ return this.request('/step/test-ai', {
152
+ method: 'POST',
153
+ body: JSON.stringify({
154
+ template,
155
+ variables,
156
+ responseStructure,
157
+ responseType: options?.responseType,
158
+ systemPrompt: options?.systemPrompt,
159
+ }),
160
+ });
161
+ }
162
+ // --- Workflow Export/Import ---
163
+ async exportWorkflow(id) {
164
+ return this.request(`/workflows/${id}/export`);
165
+ }
166
+ async importWorkflow(exportData, locale) {
167
+ return this.request('/workflows/import', {
168
+ method: 'POST',
169
+ body: JSON.stringify({ export: exportData, locale }),
170
+ });
171
+ }
172
+ // --- Workspace ---
173
+ async getWorkspace() {
174
+ return this.request('/workspace');
175
+ }
176
+ // --- Knowledge ---
177
+ async listKnowledgeLists() {
178
+ return this.request('/knowledge/lists');
179
+ }
180
+ async getKnowledgeRows(listKey, limit) {
181
+ const query = new URLSearchParams({ listKey });
182
+ if (limit)
183
+ query.set('limit', String(limit));
184
+ return this.request(`/knowledge/rows?${query}`);
185
+ }
186
+ async getKnowledgeText(key) {
187
+ const query = new URLSearchParams({ key });
188
+ return this.request(`/knowledge/text?${query}`);
189
+ }
190
+ // --- Knowledge Graph ---
191
+ async queryKgEdges(entityName, relationshipType, limit) {
192
+ const query = new URLSearchParams();
193
+ if (entityName)
194
+ query.set('entityName', entityName);
195
+ if (relationshipType)
196
+ query.set('relationshipType', relationshipType);
197
+ if (limit)
198
+ query.set('limit', String(limit));
199
+ const qs = query.toString();
200
+ return this.request(`/knowledge/graph/edges${qs ? `?${qs}` : ''}`);
201
+ }
202
+ async getScoringHistory(entityName, limit) {
203
+ const query = new URLSearchParams();
204
+ if (entityName)
205
+ query.set('entityName', entityName);
206
+ if (limit)
207
+ query.set('limit', String(limit));
208
+ const qs = query.toString();
209
+ return this.request(`/knowledge/graph/scoring${qs ? `?${qs}` : ''}`);
210
+ }
211
+ // --- n8n Import ---
212
+ async previewN8nImport(n8nJson, options, workflow) {
213
+ return this.request('/workflows/import/n8n/preview', {
214
+ method: 'POST',
215
+ body: JSON.stringify({ n8nJson, options, workflow }),
216
+ });
217
+ }
218
+ async importN8nWorkflow(n8nJson, workflow, options, locale) {
219
+ return this.request('/workflows/import/n8n/create', {
220
+ method: 'POST',
221
+ body: JSON.stringify({ n8nJson, workflow, options, locale }),
222
+ });
223
+ }
224
+ }
225
+ exports.AgentledClient = AgentledClient;
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agentled MCP Server — Entry point
4
+ *
5
+ * Connects via stdio transport for use with Claude Code.
6
+ *
7
+ * Environment variables:
8
+ * AGENTLED_API_KEY — Workspace API key (wsk_*)
9
+ * AGENTLED_URL — Base URL (default: http://localhost:3000)
10
+ */
11
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Agentled MCP Server — Entry point
5
+ *
6
+ * Connects via stdio transport for use with Claude Code.
7
+ *
8
+ * Environment variables:
9
+ * AGENTLED_API_KEY — Workspace API key (wsk_*)
10
+ * AGENTLED_URL — Base URL (default: http://localhost:3000)
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
14
+ const server_js_1 = require("./server.js");
15
+ async function main() {
16
+ const server = (0, server_js_1.createServer)();
17
+ const transport = new stdio_js_1.StdioServerTransport();
18
+ await server.connect(transport);
19
+ }
20
+ main().catch((error) => {
21
+ console.error('Failed to start Agentled MCP server:', error);
22
+ process.exit(1);
23
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Resource — App Catalog
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerAppResources(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Resource — App Catalog
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerAppResources = registerAppResources;
7
+ function registerAppResources(server, client) {
8
+ server.resource('app-catalog', 'agentled://apps', {
9
+ description: 'Browse all available Agentled apps and their actions. Use this to discover integrations for building workflows.',
10
+ mimeType: 'application/json',
11
+ }, async () => {
12
+ const result = await client.listApps();
13
+ return {
14
+ contents: [{
15
+ uri: 'agentled://apps',
16
+ mimeType: 'application/json',
17
+ text: JSON.stringify(result, null, 2),
18
+ }],
19
+ };
20
+ });
21
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Resource — Workspace Workflows
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerWorkflowResources(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Resource — Workspace Workflows
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerWorkflowResources = registerWorkflowResources;
7
+ function registerWorkflowResources(server, client) {
8
+ server.resource('workflow-catalog', 'agentled://workflows', {
9
+ description: 'Browse all workflows in the current workspace. Shows id, name, status, and goal for each workflow.',
10
+ mimeType: 'application/json',
11
+ }, async () => {
12
+ const result = await client.listWorkflows({ limit: 100 });
13
+ return {
14
+ contents: [{
15
+ uri: 'agentled://workflows',
16
+ mimeType: 'application/json',
17
+ text: JSON.stringify(result, null, 2),
18
+ }],
19
+ };
20
+ });
21
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Agentled MCP Server setup.
3
+ *
4
+ * Registers all tools and resources.
5
+ */
6
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
+ export declare function createServer(): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * Agentled MCP Server setup.
4
+ *
5
+ * Registers all tools and resources.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.createServer = createServer;
9
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
10
+ const client_js_1 = require("./client.js");
11
+ const workflows_js_1 = require("./tools/workflows.js");
12
+ const executions_js_1 = require("./tools/executions.js");
13
+ const apps_js_1 = require("./tools/apps.js");
14
+ const testing_js_1 = require("./tools/testing.js");
15
+ const knowledge_js_1 = require("./tools/knowledge.js");
16
+ const apps_js_2 = require("./resources/apps.js");
17
+ const workflows_js_2 = require("./resources/workflows.js");
18
+ function createServer() {
19
+ const server = new mcp_js_1.McpServer({
20
+ name: 'agentled',
21
+ version: '0.1.0',
22
+ });
23
+ const client = new client_js_1.AgentledClient();
24
+ // Register tools
25
+ (0, workflows_js_1.registerWorkflowTools)(server, client);
26
+ (0, executions_js_1.registerExecutionTools)(server, client);
27
+ (0, apps_js_1.registerAppTools)(server, client);
28
+ (0, testing_js_1.registerTestingTools)(server, client);
29
+ (0, knowledge_js_1.registerKnowledgeTools)(server, client);
30
+ // Register resources
31
+ (0, apps_js_2.registerAppResources)(server, client);
32
+ (0, workflows_js_2.registerWorkflowResources)(server, client);
33
+ return server;
34
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Tools — App Discovery
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerAppTools(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Tools — App Discovery
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerAppTools = registerAppTools;
7
+ const zod_1 = require("zod");
8
+ function registerAppTools(server, client) {
9
+ server.tool('list_apps', `List all available apps/integrations in Agentled. Returns app names, descriptions, and action summaries.
10
+ Use this to discover what integrations are available before building a workflow.
11
+ Common apps: agentled (LinkedIn enrichment, email finder), hunter (email), web-scraping, affinity-crm, specter, http-request.`, {}, async () => {
12
+ const result = await client.listApps();
13
+ return {
14
+ content: [{
15
+ type: 'text',
16
+ text: JSON.stringify(result, null, 2),
17
+ }],
18
+ };
19
+ });
20
+ server.tool('get_app_actions', `Get detailed action schemas for a specific app. Returns input parameters, output fields, and credit costs.
21
+ Use this to understand exactly what inputs an action needs when building workflow steps.`, {
22
+ appId: zod_1.z.string().describe('The app ID (e.g., "agentled", "hunter", "web-scraping", "affinity-crm")'),
23
+ }, async ({ appId }) => {
24
+ const result = await client.getAppActions(appId);
25
+ return {
26
+ content: [{
27
+ type: 'text',
28
+ text: JSON.stringify(result, null, 2),
29
+ }],
30
+ };
31
+ });
32
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Tools — Workflow Executions
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerExecutionTools(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Tools — Workflow Executions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerExecutionTools = registerExecutionTools;
7
+ const zod_1 = require("zod");
8
+ function registerExecutionTools(server, client) {
9
+ server.tool('start_workflow', `Start a workflow execution. Optionally provide input data that maps to the workflow's input page fields.
10
+ For example, if the workflow expects "company_url", pass: { input: { company_url: "https://..." } }`, {
11
+ workflowId: zod_1.z.string().describe('The workflow ID to start'),
12
+ input: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Input payload matching the workflow input page fields'),
13
+ metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Optional execution metadata'),
14
+ }, async ({ workflowId, input, metadata }) => {
15
+ const result = await client.startWorkflow(workflowId, input, metadata);
16
+ return {
17
+ content: [{
18
+ type: 'text',
19
+ text: JSON.stringify(result, null, 2),
20
+ }],
21
+ };
22
+ });
23
+ server.tool('list_executions', 'List recent executions for a workflow. Returns execution id, status, timestamps.', {
24
+ workflowId: zod_1.z.string().describe('The workflow ID'),
25
+ status: zod_1.z.string().optional().describe('Filter: running, completed, failed'),
26
+ limit: zod_1.z.number().optional().describe('Max results (default 50, max 500)'),
27
+ direction: zod_1.z.enum(['asc', 'desc']).optional().describe('Sort order (default: desc)'),
28
+ }, async ({ workflowId, status, limit, direction }) => {
29
+ const result = await client.listExecutions(workflowId, { status, limit, direction });
30
+ return {
31
+ content: [{
32
+ type: 'text',
33
+ text: JSON.stringify(result, null, 2),
34
+ }],
35
+ };
36
+ });
37
+ server.tool('get_execution', `Get full execution details including results from each completed step.
38
+ The executionContent field maps stepId -> step output data.
39
+ Use this to inspect what a workflow produced, debug failures, or check intermediate results.`, {
40
+ workflowId: zod_1.z.string().describe('The workflow ID'),
41
+ executionId: zod_1.z.string().describe('The execution ID'),
42
+ }, async ({ workflowId, executionId }) => {
43
+ const result = await client.getExecution(workflowId, executionId);
44
+ return {
45
+ content: [{
46
+ type: 'text',
47
+ text: JSON.stringify(result, null, 2),
48
+ }],
49
+ };
50
+ });
51
+ server.tool('stop_execution', 'Stop a running or pending workflow execution. Only works on executions with status "running" or "pending".', {
52
+ workflowId: zod_1.z.string().describe('The workflow ID'),
53
+ executionId: zod_1.z.string().describe('The execution ID to stop'),
54
+ }, async ({ workflowId, executionId }) => {
55
+ const result = await client.stopExecution(workflowId, executionId);
56
+ return {
57
+ content: [{
58
+ type: 'text',
59
+ text: JSON.stringify(result, null, 2),
60
+ }],
61
+ };
62
+ });
63
+ server.tool('retry_execution', `Retry a failed step in a workflow execution. If no timelineId is provided, the most recent failed timeline is automatically detected and retried. This re-runs the failed step and continues the workflow from that point.`, {
64
+ workflowId: zod_1.z.string().describe('The workflow ID'),
65
+ executionId: zod_1.z.string().describe('The execution ID containing the failed step'),
66
+ timelineId: zod_1.z.string().optional().describe('Specific timeline ID to retry. If omitted, the most recent failed timeline is auto-detected.'),
67
+ forceWithoutCache: zod_1.z.boolean().optional().describe('Bypass cache when retrying the step'),
68
+ rerunMode: zod_1.z.enum(['single-step', 'from-step', 'selected-steps']).optional().describe('Rerun mode: single-step (retry only this step), from-step (retry from this step onward), selected-steps'),
69
+ }, async ({ workflowId, executionId, timelineId, forceWithoutCache, rerunMode }) => {
70
+ const result = await client.retryExecution(workflowId, executionId, {
71
+ timelineId,
72
+ forceWithoutCache,
73
+ rerunMode,
74
+ });
75
+ return {
76
+ content: [{
77
+ type: 'text',
78
+ text: JSON.stringify(result, null, 2),
79
+ }],
80
+ };
81
+ });
82
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Tools — Knowledge, Workspace & Knowledge Graph
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerKnowledgeTools(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Tools — Knowledge, Workspace & Knowledge Graph
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerKnowledgeTools = registerKnowledgeTools;
7
+ const zod_1 = require("zod");
8
+ function registerKnowledgeTools(server, client) {
9
+ // --- Workspace Context ---
10
+ server.tool('get_workspace', `Get workspace company info, offerings, and knowledge schema overview.
11
+ Returns company details (name, industry, size, offerings) and a summary of all knowledge lists with their field definitions and row counts.
12
+ Use this as a first call to understand what data the workspace has.`, {}, async () => {
13
+ const result = await client.getWorkspace();
14
+ return {
15
+ content: [{
16
+ type: 'text',
17
+ text: JSON.stringify(result, null, 2),
18
+ }],
19
+ };
20
+ });
21
+ // --- Knowledge Data ---
22
+ server.tool('list_knowledge_lists', `List all knowledge list schemas with field definitions, row counts, and metadata.
23
+ Returns detailed information about each list including fields, source type, category, entity config, and KG sync status.
24
+ Use this to discover what lists exist and understand their structure before querying rows.`, {}, async () => {
25
+ const result = await client.listKnowledgeLists();
26
+ return {
27
+ content: [{
28
+ type: 'text',
29
+ text: JSON.stringify(result, null, 2),
30
+ }],
31
+ };
32
+ });
33
+ server.tool('get_knowledge_rows', `Fetch sample rows from a knowledge list. Use this to inspect actual data — see example payloads from investor/deal lists.
34
+ Returns rows with their full rowData, plus count and totalCount for the list.`, {
35
+ listKey: zod_1.z.string().describe('The list key to fetch rows from (e.g., "investors", "deals")'),
36
+ limit: zod_1.z.number().min(1).max(50).optional().describe('Number of rows to return (default 5, max 50)'),
37
+ }, async ({ listKey, limit }) => {
38
+ const result = await client.getKnowledgeRows(listKey, limit);
39
+ return {
40
+ content: [{
41
+ type: 'text',
42
+ text: JSON.stringify(result, null, 2),
43
+ }],
44
+ };
45
+ });
46
+ server.tool('get_knowledge_text', `Fetch a text-type knowledge entry by key. Use this to access text-based knowledge like feedback files, notes, or configuration text stored in the workspace.`, {
47
+ key: zod_1.z.string().describe('The key of the text entry to fetch'),
48
+ }, async ({ key }) => {
49
+ const result = await client.getKnowledgeText(key);
50
+ return {
51
+ content: [{
52
+ type: 'text',
53
+ text: JSON.stringify(result, null, 2),
54
+ }],
55
+ };
56
+ });
57
+ // --- Knowledge Graph ---
58
+ server.tool('query_kg_edges', `Traverse Knowledge Graph edges by entity name and/or relationship type.
59
+ Returns edges with source/target node IDs, relations, scores, and metadata.
60
+ Use this to explore deal relationships, investor-startup connections, and scoring edges.
61
+ Gracefully returns empty results if the Knowledge Graph is not configured.`, {
62
+ entityName: zod_1.z.string().optional().describe('Filter edges by entity name'),
63
+ relationshipType: zod_1.z.string().optional().describe('Filter edges by relationship type (e.g., "INVESTED_IN", "SCORED")'),
64
+ limit: zod_1.z.number().min(1).max(500).optional().describe('Max edges to return (default 100, max 500)'),
65
+ }, async ({ entityName, relationshipType, limit }) => {
66
+ const result = await client.queryKgEdges(entityName, relationshipType, limit);
67
+ return {
68
+ content: [{
69
+ type: 'text',
70
+ text: JSON.stringify(result, null, 2),
71
+ }],
72
+ };
73
+ });
74
+ server.tool('get_scoring_history', `Fetch scoring history for entities from the Knowledge Graph.
75
+ Returns past scoring decisions (PROCEED_TO_IC, HOLD_FOR_REVIEW, REPOSITION, SCORED) with DMF scores and dates.
76
+ Use this to see how entities were previously scored and calibrate future scoring runs.
77
+ Returns both structured records and a compact text format for prompt injection.`, {
78
+ entityName: zod_1.z.string().optional().describe('Filter scoring history by entity name'),
79
+ limit: zod_1.z.number().min(1).max(500).optional().describe('Max records to return (default 100, max 500)'),
80
+ }, async ({ entityName, limit }) => {
81
+ const result = await client.getScoringHistory(entityName, limit);
82
+ return {
83
+ content: [{
84
+ type: 'text',
85
+ text: JSON.stringify(result, null, 2),
86
+ }],
87
+ };
88
+ });
89
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Tools — Step Testing
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerTestingTools(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Tools — Step Testing
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerTestingTools = registerTestingTools;
7
+ const zod_1 = require("zod");
8
+ function registerTestingTools(server, client) {
9
+ server.tool('test_app_action', `Test an app action in isolation without creating a workflow or execution.
10
+ Pass the appId and actionId (from list_apps / get_app_actions) plus input data to run the action directly and see results immediately.
11
+ Useful for verifying inputs before wiring a step into a workflow.
12
+ Example: test_app_action("web-scraping", "scrape", { url: "https://example.com" })`, {
13
+ appId: zod_1.z.string().describe('App ID (e.g., "agentled", "web-scraping", "hunter")'),
14
+ actionId: zod_1.z.string().describe('Action ID (e.g., "scrape", "get-linkedin-company-from-url", "find-email-person-domain")'),
15
+ input: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Input data for the action (e.g., { url: "https://example.com" })'),
16
+ bypassCache: zod_1.z.boolean().optional().describe('Skip cache and run against the live API (default: false)'),
17
+ }, async ({ appId, actionId, input, bypassCache }) => {
18
+ const result = await client.testAppAction(appId, actionId, input, bypassCache);
19
+ return {
20
+ content: [{
21
+ type: 'text',
22
+ text: JSON.stringify(result, null, 2),
23
+ }],
24
+ };
25
+ });
26
+ server.tool('test_ai_action', `Test an AI prompt in isolation without creating a workflow or execution.
27
+ Pass a prompt template with {{variable}} syntax and variable values to run the AI and see the response.
28
+ Useful for tuning prompts and response structures before adding an AI step to a workflow.
29
+ Example: test_ai_action("Analyze this company: {{company}}", { company: "Stripe" }, { score: "number 0-100", summary: "string" })`, {
30
+ template: zod_1.z.string().describe('Prompt template with {{variable}} placeholders'),
31
+ variables: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Variable values to substitute in the template'),
32
+ responseStructure: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Expected JSON output shape (e.g., { score: "number 0-100", summary: "string" })'),
33
+ responseType: zod_1.z.enum(['json', 'text']).optional().describe('Response format: "json" (default) or "text"'),
34
+ systemPrompt: zod_1.z.string().optional().describe('Optional system instructions for the AI'),
35
+ }, async ({ template, variables, responseStructure, responseType, systemPrompt }) => {
36
+ const result = await client.testAiAction(template, variables, responseStructure, {
37
+ responseType,
38
+ systemPrompt,
39
+ });
40
+ return {
41
+ content: [{
42
+ type: 'text',
43
+ text: JSON.stringify(result, null, 2),
44
+ }],
45
+ };
46
+ });
47
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP Tools — Workflow CRUD + Validation + Lifecycle
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { AgentledClient } from '../client.js';
6
+ export declare function registerWorkflowTools(server: McpServer, client: AgentledClient): void;
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Tools — Workflow CRUD + Validation + Lifecycle
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerWorkflowTools = registerWorkflowTools;
7
+ const zod_1 = require("zod");
8
+ function registerWorkflowTools(server, client) {
9
+ server.tool('list_workflows', 'List all workflows in the workspace. Returns id, name, status, goal for each.', {
10
+ status: zod_1.z.string().optional().describe('Filter by status: draft, active, paused'),
11
+ limit: zod_1.z.number().optional().describe('Max results (default 50, max 200)'),
12
+ }, async ({ status, limit }) => {
13
+ const result = await client.listWorkflows({ status, limit });
14
+ return {
15
+ content: [{
16
+ type: 'text',
17
+ text: JSON.stringify(result, null, 2),
18
+ }],
19
+ };
20
+ });
21
+ server.tool('get_workflow', `Get full details of a workflow including all steps, context, metadata, and configuration.
22
+ Also returns hasDraftSnapshot (boolean) and draftSnapshot summary if a draft exists for a live workflow.`, {
23
+ workflowId: zod_1.z.string().describe('The workflow ID'),
24
+ }, async ({ workflowId }) => {
25
+ const result = await client.getWorkflow(workflowId);
26
+ return {
27
+ content: [{
28
+ type: 'text',
29
+ text: JSON.stringify(result, null, 2),
30
+ }],
31
+ };
32
+ });
33
+ server.tool('create_workflow', `Create a new workflow from a pipeline definition. The pipeline object should include:
34
+ - name (required): Workflow name
35
+ - goal: What the workflow does
36
+ - description: Longer description
37
+ - steps: Array of pipeline steps (trigger, aiAction, appAction, milestone, etc.)
38
+ - context: Execution input config and input/output pages
39
+ - metadata: Template info, notifications, ROI
40
+ - style: UI styling (colors, icon)`, {
41
+ pipeline: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).describe('The pipeline definition object'),
42
+ locale: zod_1.z.string().optional().describe('Locale (default: en)'),
43
+ }, async ({ pipeline, locale }) => {
44
+ const result = await client.createWorkflow(pipeline, locale);
45
+ return {
46
+ content: [{
47
+ type: 'text',
48
+ text: JSON.stringify(result, null, 2),
49
+ }],
50
+ };
51
+ });
52
+ server.tool('update_workflow', `Update an existing workflow. Provide only the fields you want to change.
53
+
54
+ IMPORTANT: If the workflow is live, config edits (steps, context, name, etc.) are automatically
55
+ routed to a draft snapshot instead of modifying the live pipeline. The response will include
56
+ editingDraft: true. Use get_draft to view the draft, promote_draft to make it live, or
57
+ discard_draft to throw away the changes. Non-live workflows are updated directly with an
58
+ automatic pre-edit snapshot for rollback.`, {
59
+ workflowId: zod_1.z.string().describe('The workflow ID to update'),
60
+ updates: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).describe('Partial pipeline updates (name, steps, context, etc.)'),
61
+ locale: zod_1.z.string().optional().describe('Locale (default: en)'),
62
+ }, async ({ workflowId, updates, locale }) => {
63
+ const result = await client.updateWorkflow(workflowId, updates, locale);
64
+ return {
65
+ content: [{
66
+ type: 'text',
67
+ text: JSON.stringify(result, null, 2),
68
+ }],
69
+ };
70
+ });
71
+ server.tool('delete_workflow', 'Permanently delete a workflow by ID. This cannot be undone.', {
72
+ workflowId: zod_1.z.string().describe('The workflow ID to delete'),
73
+ }, async ({ workflowId }) => {
74
+ const result = await client.deleteWorkflow(workflowId);
75
+ return {
76
+ content: [{
77
+ type: 'text',
78
+ text: JSON.stringify(result, null, 2),
79
+ }],
80
+ };
81
+ });
82
+ server.tool('validate_workflow', `Validate a workflow's pipeline definition. Returns structured errors per step.
83
+ Use this after creating or updating a workflow to check for:
84
+ - Missing step connections (broken next.stepId references)
85
+ - Missing required fields (app action without inputs, AI step without prompt)
86
+ - Unreachable steps (not connected to the trigger chain)
87
+ - Invalid app/action IDs (not in the app registry)
88
+ - Missing trigger or milestone steps
89
+ - List field misconfigurations (missing itemFields, defaultValue format mismatches)
90
+ - Config page field validation (missing name/type on input page fields)
91
+
92
+ Each error/warning may include a "suggestedFix" with a concrete remediation.
93
+
94
+ You can also pass a pipeline object to validate a draft before saving.
95
+ Returns: { valid: boolean, errors: [...], warnings: [...], stepCount: number }`, {
96
+ workflowId: zod_1.z.string().describe('The workflow ID to validate'),
97
+ pipeline: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Optional draft pipeline to validate before saving (merged with stored pipeline)'),
98
+ }, async ({ workflowId, pipeline }) => {
99
+ const result = await client.validateWorkflow(workflowId, pipeline);
100
+ return {
101
+ content: [{
102
+ type: 'text',
103
+ text: JSON.stringify(result, null, 2),
104
+ }],
105
+ };
106
+ });
107
+ server.tool('list_snapshots', `List available config snapshots for a workflow. Snapshots are automatically captured
108
+ before every external API update, allowing you to restore a previous configuration.
109
+ Returns snapshot ID, timestamp, and which fields were changed.`, {
110
+ workflowId: zod_1.z.string().describe('The workflow ID'),
111
+ }, async ({ workflowId }) => {
112
+ const result = await client.listSnapshots(workflowId);
113
+ return {
114
+ content: [{
115
+ type: 'text',
116
+ text: JSON.stringify(result, null, 2),
117
+ }],
118
+ };
119
+ });
120
+ server.tool('restore_snapshot', `Restore a workflow to a previous config snapshot. Use list_snapshots first to find the
121
+ snapshot ID. This will revert the workflow's steps, context, name, description, goal, and
122
+ style to the state captured in the snapshot.`, {
123
+ workflowId: zod_1.z.string().describe('The workflow ID'),
124
+ snapshotId: zod_1.z.string().describe('The snapshot ID to restore (from list_snapshots)'),
125
+ }, async ({ workflowId, snapshotId }) => {
126
+ const result = await client.restoreSnapshot(workflowId, snapshotId);
127
+ return {
128
+ content: [{
129
+ type: 'text',
130
+ text: JSON.stringify(result, null, 2),
131
+ }],
132
+ };
133
+ });
134
+ server.tool('get_draft', `Get the draft snapshot for a live workflow. When you update a live workflow, changes
135
+ go to a draft instead of modifying the live pipeline. Use this to inspect the current draft
136
+ state. Returns hasDraft: true/false and the draft config if it exists.`, {
137
+ workflowId: zod_1.z.string().describe('The workflow ID'),
138
+ }, async ({ workflowId }) => {
139
+ const result = await client.getDraft(workflowId);
140
+ return {
141
+ content: [{
142
+ type: 'text',
143
+ text: JSON.stringify(result, null, 2),
144
+ }],
145
+ };
146
+ });
147
+ server.tool('promote_draft', `Promote the draft snapshot to live. This overwrites the live pipeline config with
148
+ the draft contents, then deletes the draft snapshot. A pre-promote snapshot is saved
149
+ automatically so the previous live config can be restored if needed.`, {
150
+ workflowId: zod_1.z.string().describe('The workflow ID'),
151
+ }, async ({ workflowId }) => {
152
+ const result = await client.promoteDraft(workflowId);
153
+ return {
154
+ content: [{
155
+ type: 'text',
156
+ text: JSON.stringify(result, null, 2),
157
+ }],
158
+ };
159
+ });
160
+ server.tool('discard_draft', `Discard the draft snapshot for a live workflow. The live pipeline config stays
161
+ unchanged. Use this to abandon draft changes and go back to the current live version.`, {
162
+ workflowId: zod_1.z.string().describe('The workflow ID'),
163
+ }, async ({ workflowId }) => {
164
+ const result = await client.discardDraft(workflowId);
165
+ return {
166
+ content: [{
167
+ type: 'text',
168
+ text: JSON.stringify(result, null, 2),
169
+ }],
170
+ };
171
+ });
172
+ server.tool('publish_workflow', `Change the status of a workflow (publish, pause, or archive).
173
+ Valid transitions: created/draft -> live, live -> paused, paused -> live, any -> archived.
174
+ Use "live" to publish a draft workflow so it can be executed.`, {
175
+ workflowId: zod_1.z.string().describe('The workflow ID'),
176
+ status: zod_1.z.enum(['live', 'paused', 'archived']).describe('Target status'),
177
+ }, async ({ workflowId, status }) => {
178
+ const result = await client.publishWorkflow(workflowId, status);
179
+ return {
180
+ content: [{
181
+ type: 'text',
182
+ text: JSON.stringify(result, null, 2),
183
+ }],
184
+ };
185
+ });
186
+ server.tool('export_workflow', `Export a workflow as portable JSON for cross-environment transfer.
187
+ Returns a self-contained WorkflowExport object with all steps, context, metadata, and pages.
188
+ Workspace-specific identifiers (workspaceId, agentIds) are stripped so the export can be imported into any workspace.
189
+
190
+ Use this together with import_workflow to move workflows between environments (e.g. sandbox → prod).`, {
191
+ workflowId: zod_1.z.string().describe('The workflow ID to export'),
192
+ }, async ({ workflowId }) => {
193
+ const result = await client.exportWorkflow(workflowId);
194
+ return {
195
+ content: [{
196
+ type: 'text',
197
+ text: JSON.stringify(result, null, 2),
198
+ }],
199
+ };
200
+ });
201
+ server.tool('import_workflow', `Import a workflow from an export JSON into this workspace.
202
+ Accepts the full WorkflowExport object (from export_workflow) and creates a new workflow with fresh IDs.
203
+ Associated pages are recreated. Import provenance is recorded in the workflow metadata.
204
+
205
+ Use this together with export_workflow to move workflows between environments.
206
+ Tip: register separate MCP servers for sandbox and prod, export from one, import into the other.`, {
207
+ exportJson: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).describe('The WorkflowExport object (output from export_workflow)'),
208
+ locale: zod_1.z.string().optional().describe('Locale for the imported workflow (default: en)'),
209
+ }, async ({ exportJson, locale }) => {
210
+ const result = await client.importWorkflow(exportJson, locale);
211
+ return {
212
+ content: [{
213
+ type: 'text',
214
+ text: JSON.stringify(result, null, 2),
215
+ }],
216
+ };
217
+ });
218
+ server.tool('preview_n8n_import', `Preview a deterministic n8n import from JSON. Returns:
219
+ - normalized import hash and IR
220
+ - mapped step graph
221
+ - unsupported nodes + remediation
222
+ - warnings/risks
223
+ - draft workflow build contract and compiler readiness summary
224
+
225
+ This is a read-only preview and does not create any workflow.`, {
226
+ n8nJson: zod_1.z.any().describe('n8n workflow JSON object or string export'),
227
+ options: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Optional import options (e.g. maxNodes, allowPartial)'),
228
+ workflow: zod_1.z.object({
229
+ name: zod_1.z.string().optional(),
230
+ goal: zod_1.z.string().optional(),
231
+ description: zod_1.z.string().optional(),
232
+ pathname: zod_1.z.string().optional(),
233
+ }).optional().describe('Optional workflow metadata overrides for preview contract'),
234
+ }, async ({ n8nJson, options, workflow }) => {
235
+ const result = await client.previewN8nImport(n8nJson, options, workflow);
236
+ return {
237
+ content: [{
238
+ type: 'text',
239
+ text: JSON.stringify(result, null, 2),
240
+ }],
241
+ };
242
+ });
243
+ server.tool('import_n8n_workflow', `Create a new Agentled workflow from an n8n JSON import.
244
+
245
+ Behavior:
246
+ - runs deterministic import preview
247
+ - creates workflow in preflight draft mode
248
+ - stores imported contract for review/approval
249
+ - does NOT auto-apply scaffold`, {
250
+ n8nJson: zod_1.z.any().describe('n8n workflow JSON object or string export'),
251
+ workflow: zod_1.z.object({
252
+ name: zod_1.z.string().optional(),
253
+ goal: zod_1.z.string().optional(),
254
+ description: zod_1.z.string().optional(),
255
+ pathname: zod_1.z.string().optional(),
256
+ }).optional().describe('Optional metadata overrides for the created workflow'),
257
+ options: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe('Optional import options'),
258
+ locale: zod_1.z.string().optional().describe('Locale for workflow creation (default en)'),
259
+ }, async ({ n8nJson, workflow, options, locale }) => {
260
+ const result = await client.importN8nWorkflow(n8nJson, workflow, options, locale);
261
+ return {
262
+ content: [{
263
+ type: 'text',
264
+ text: JSON.stringify(result, null, 2),
265
+ }],
266
+ };
267
+ });
268
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@agentled/mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Agentled — create, manage, and run workflows from Claude Code",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "agentled-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "start": "node dist/index.js",
19
+ "prepublishOnly": "tsc"
20
+ },
21
+ "dependencies": {
22
+ "@modelcontextprotocol/sdk": "^1.12.0",
23
+ "zod": "^3.25.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.0.0",
27
+ "typescript": "^5.5.0"
28
+ },
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "keywords": [
33
+ "mcp",
34
+ "agentled",
35
+ "workflows",
36
+ "claude-code",
37
+ "automation",
38
+ "ai-agents"
39
+ ],
40
+ "author": "Agentled",
41
+ "homepage": "https://www.agentled.app",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/agentled/mcp-server"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/agentled/mcp-server/issues"
48
+ },
49
+ "license": "MIT"
50
+ }