@kadoa/mcp 0.3.1-rc.0 → 0.3.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/README.md +7 -0
- package/dist/index.js +70 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,12 @@ Use [Kadoa](https://kadoa.com) from ChatGPT, Claude.ai, Claude Code, Cursor, and
|
|
|
6
6
|
|
|
7
7
|
A hosted MCP server is available at `https://mcp.kadoa.com/mcp`. Connect from any MCP client — no local install, no API key config. You sign in with your Kadoa account via OAuth.
|
|
8
8
|
|
|
9
|
+
### Claude Code
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
claude mcp add kadoa --transport http https://mcp.kadoa.com/mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
9
15
|
### ChatGPT
|
|
10
16
|
|
|
11
17
|
1. Go to **Settings → Connectors → Add MCP server**
|
|
@@ -144,6 +150,7 @@ Get your API key from [kadoa.com/settings](https://kadoa.com/settings).
|
|
|
144
150
|
| `delete_workflow` | Delete a workflow |
|
|
145
151
|
| `approve_workflow` | Approve and activate a workflow |
|
|
146
152
|
| `update_workflow` | Update workflow configuration and schema |
|
|
153
|
+
| `whoami` | Show current user details, auth method, and team memberships |
|
|
147
154
|
| `team_list` | List all teams you belong to and see which is active |
|
|
148
155
|
| `team_switch` | Switch the active team by name or ID |
|
|
149
156
|
|
package/dist/index.js
CHANGED
|
@@ -49273,26 +49273,87 @@ function registerTools(server, ctx) {
|
|
|
49273
49273
|
"FOUR_WEEKS",
|
|
49274
49274
|
"MONTHLY",
|
|
49275
49275
|
"REAL_TIME"
|
|
49276
|
-
]).optional().describe("How often the workflow runs. Defaults to ONLY_ONCE. Use REAL_TIME for continuous monitoring.")
|
|
49276
|
+
]).optional().describe("How often the workflow runs. Defaults to ONLY_ONCE. Use REAL_TIME for continuous monitoring."),
|
|
49277
|
+
notifications: exports_external.object({
|
|
49278
|
+
email: exports_external.boolean().optional().describe("Send email notifications to the account email when data changes"),
|
|
49279
|
+
webhook: exports_external.object({
|
|
49280
|
+
url: exports_external.string().url().describe("Webhook endpoint URL"),
|
|
49281
|
+
httpMethod: exports_external.enum(["POST", "GET", "PUT", "PATCH"]).optional().describe("HTTP method (defaults to POST)")
|
|
49282
|
+
}).optional().describe("Send notifications via HTTP webhook"),
|
|
49283
|
+
slack: exports_external.object({
|
|
49284
|
+
webhookUrl: exports_external.string().url().describe("Slack incoming webhook URL")
|
|
49285
|
+
}).optional().describe("Send notifications to a Slack channel"),
|
|
49286
|
+
websocket: exports_external.boolean().optional().describe("Enable WebSocket notifications for programmatic real-time consumption")
|
|
49287
|
+
}).optional().describe("Notification channels to alert when data changes. At least one channel is required for REAL_TIME workflows.")
|
|
49277
49288
|
},
|
|
49278
49289
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
49279
49290
|
}, withErrorHandling("create_workflow", async (args) => {
|
|
49280
|
-
const
|
|
49281
|
-
|
|
49291
|
+
const n = args.notifications;
|
|
49292
|
+
const hasNotifications = n && (n.email || n.webhook || n.slack || n.websocket);
|
|
49293
|
+
if (args.interval === "REAL_TIME" && !hasNotifications) {
|
|
49294
|
+
return errorResult("Real-time workflows require at least one notification channel so you get alerted when data changes. " + "Add a notifications object with one or more channels: email, webhook, slack, or websocket.");
|
|
49295
|
+
}
|
|
49296
|
+
const extraction = args.schema ? (builder2) => {
|
|
49297
|
+
const entity = builder2.entity(args.entity || "Data");
|
|
49282
49298
|
for (const field of args.schema) {
|
|
49283
49299
|
entity.field(field.name, field.description || field.name, field.dataType || "STRING", { example: field.example });
|
|
49284
49300
|
}
|
|
49285
49301
|
return entity;
|
|
49286
49302
|
} : undefined;
|
|
49287
|
-
|
|
49303
|
+
let builder = ctx.client.extract({
|
|
49288
49304
|
urls: args.urls,
|
|
49289
49305
|
name: args.name || "Untitled Workflow",
|
|
49290
49306
|
navigationMode: "agentic-navigation",
|
|
49291
49307
|
userPrompt: args.prompt,
|
|
49292
49308
|
extraction,
|
|
49293
49309
|
interval: args.interval
|
|
49294
|
-
})
|
|
49295
|
-
|
|
49310
|
+
});
|
|
49311
|
+
if (hasNotifications) {
|
|
49312
|
+
const channels = {};
|
|
49313
|
+
if (n.email)
|
|
49314
|
+
channels.EMAIL = true;
|
|
49315
|
+
if (n.websocket)
|
|
49316
|
+
channels.WEBSOCKET = true;
|
|
49317
|
+
if (n.webhook) {
|
|
49318
|
+
channels.WEBHOOK = {
|
|
49319
|
+
name: "mcp-webhook",
|
|
49320
|
+
webhookUrl: n.webhook.url,
|
|
49321
|
+
httpMethod: n.webhook.httpMethod || "POST"
|
|
49322
|
+
};
|
|
49323
|
+
}
|
|
49324
|
+
if (n.slack) {
|
|
49325
|
+
channels.SLACK = {
|
|
49326
|
+
name: "mcp-slack",
|
|
49327
|
+
webhookUrl: n.slack.webhookUrl
|
|
49328
|
+
};
|
|
49329
|
+
}
|
|
49330
|
+
builder = builder.withNotifications({
|
|
49331
|
+
events: ["workflow_data_change"],
|
|
49332
|
+
channels
|
|
49333
|
+
});
|
|
49334
|
+
}
|
|
49335
|
+
const workflow = await builder.create();
|
|
49336
|
+
const enabledChannels = [];
|
|
49337
|
+
if (n?.email) {
|
|
49338
|
+
const user = await ctx.client.user.getCurrentUser();
|
|
49339
|
+
enabledChannels.push(`email (${user.email})`);
|
|
49340
|
+
}
|
|
49341
|
+
if (n?.slack)
|
|
49342
|
+
enabledChannels.push(`slack (${n.slack.webhookUrl})`);
|
|
49343
|
+
if (n?.webhook)
|
|
49344
|
+
enabledChannels.push(`webhook (${n.webhook.url})`);
|
|
49345
|
+
if (n?.websocket)
|
|
49346
|
+
enabledChannels.push("websocket");
|
|
49347
|
+
let message = "Workflow created successfully.";
|
|
49348
|
+
if (args.interval === "REAL_TIME") {
|
|
49349
|
+
message += " This real-time workflow monitors continuously — no manual runs needed.";
|
|
49350
|
+
} else {
|
|
49351
|
+
message += " The AI agent will start extracting data automatically.";
|
|
49352
|
+
}
|
|
49353
|
+
if (enabledChannels.length > 0) {
|
|
49354
|
+
message += ` Notifications on data changes via: ${enabledChannels.join(", ")}.`;
|
|
49355
|
+
}
|
|
49356
|
+
message += " Use fetch_data to retrieve the latest extracted results.";
|
|
49296
49357
|
return jsonResult({
|
|
49297
49358
|
success: true,
|
|
49298
49359
|
workflowId: workflow.workflowId,
|
|
@@ -53959,7 +54020,7 @@ function renderTeamSelectionPage(teams, selectionToken) {
|
|
|
53959
54020
|
function escapeHtml(str) {
|
|
53960
54021
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
53961
54022
|
}
|
|
53962
|
-
var clients, pendingAuths, pendingTeamSelections, authCodes, accessTokens, refreshTokens, TEAM_SELECTION_TTL, ACCESS_TOKEN_TTL
|
|
54023
|
+
var clients, pendingAuths, pendingTeamSelections, authCodes, accessTokens, refreshTokens, TEAM_SELECTION_TTL, ACCESS_TOKEN_TTL, kadoaClientsStore;
|
|
53963
54024
|
var init_auth2 = __esm(() => {
|
|
53964
54025
|
clients = new Map;
|
|
53965
54026
|
pendingAuths = new Map;
|
|
@@ -53968,6 +54029,7 @@ var init_auth2 = __esm(() => {
|
|
|
53968
54029
|
accessTokens = new Map;
|
|
53969
54030
|
refreshTokens = new Map;
|
|
53970
54031
|
TEAM_SELECTION_TTL = 10 * 60 * 1000;
|
|
54032
|
+
ACCESS_TOKEN_TTL = 7 * 24 * 3600;
|
|
53971
54033
|
kadoaClientsStore = {
|
|
53972
54034
|
getClient(clientId) {
|
|
53973
54035
|
return clients.get(clientId);
|
|
@@ -54184,7 +54246,7 @@ function createServer(auth) {
|
|
|
54184
54246
|
client: createKadoaClient(auth)
|
|
54185
54247
|
};
|
|
54186
54248
|
}
|
|
54187
|
-
const server = new McpServer({ name: "kadoa", version: "0.2
|
|
54249
|
+
const server = new McpServer({ name: "kadoa", version: "0.3.2" });
|
|
54188
54250
|
registerTools(server, ctx);
|
|
54189
54251
|
server.server.onerror = (error48) => console.error("[MCP Error]", error48);
|
|
54190
54252
|
return server;
|