@webhooks-cc/mcp 1.16.0 → 1.18.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/README.md +14 -2
- package/dist/bin/mcp.js +240 -6
- package/dist/{chunk-4LEPLCW5.mjs → chunk-GTEE7L2Y.mjs} +233 -2
- package/dist/index.js +240 -6
- package/dist/index.mjs +13 -5
- package/dist/tools.d.mts +22 -2
- package/dist/tools.d.ts +22 -2
- package/dist/tools.js +238 -4
- package/dist/tools.mjs +9 -3
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -182,6 +182,15 @@ function omitHeaders(holder) {
|
|
|
182
182
|
holder.headers = {};
|
|
183
183
|
holder.headersOmitted = `${count} headers left out to fit the output`;
|
|
184
184
|
}
|
|
185
|
+
function trimAuth(holder) {
|
|
186
|
+
const auth = holder.auth;
|
|
187
|
+
if (auth && typeof auth === "object" && !Array.isArray(auth)) {
|
|
188
|
+
const verdicts = { ...auth };
|
|
189
|
+
delete verdicts.setup;
|
|
190
|
+
delete verdicts.authenticationResults;
|
|
191
|
+
holder.auth = verdicts;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
185
194
|
function trimSpam(holder) {
|
|
186
195
|
const spam = holder.spam;
|
|
187
196
|
if (spam && typeof spam === "object" && !Array.isArray(spam)) {
|
|
@@ -329,6 +338,7 @@ function compactRequest(request) {
|
|
|
329
338
|
shrinkToFit(root, budget, [
|
|
330
339
|
() => trimParsed(compact),
|
|
331
340
|
() => omitHeaders(compact),
|
|
341
|
+
() => trimAuth(email),
|
|
332
342
|
() => trimSpam(email),
|
|
333
343
|
() => capLists(email),
|
|
334
344
|
() => cutStringToFit(root, email, "text", "textTruncated", budget, TEXT_FLOOR),
|
|
@@ -469,6 +479,10 @@ function registerResources(server, client) {
|
|
|
469
479
|
var import_zod3 = require("zod");
|
|
470
480
|
var import_sdk2 = require("@webhooks-cc/sdk");
|
|
471
481
|
|
|
482
|
+
// src/version.ts
|
|
483
|
+
var VERSION = true ? "1.18.0" : "0.0.0-dev";
|
|
484
|
+
var MCP_USER_AGENT = `webhooks-cc-mcp/${VERSION}`;
|
|
485
|
+
|
|
472
486
|
// src/tools.ts
|
|
473
487
|
var import_zod2 = require("zod");
|
|
474
488
|
var import_sdk = require("@webhooks-cc/sdk");
|
|
@@ -1020,7 +1034,7 @@ function emailDetail(client, email, view, includeHtml) {
|
|
|
1020
1034
|
]);
|
|
1021
1035
|
return detail;
|
|
1022
1036
|
}
|
|
1023
|
-
var LOCAL_ONLY_TOOLS = /* @__PURE__ */ new Set(["send_to", "replay_request"]);
|
|
1037
|
+
var LOCAL_ONLY_TOOLS = /* @__PURE__ */ new Set(["send_to", "replay_request", "share_port"]);
|
|
1024
1038
|
var TARGET_URL_TOOLS = /* @__PURE__ */ new Set(["render_email", "test_webhook_flow"]);
|
|
1025
1039
|
var REMOTE_MAX_WAIT_MS = 5e4;
|
|
1026
1040
|
var REMOTE_MIN_POLL_MS = 1e3;
|
|
@@ -1078,9 +1092,78 @@ function toolTarget(target, remote, handles) {
|
|
|
1078
1092
|
}
|
|
1079
1093
|
};
|
|
1080
1094
|
}
|
|
1095
|
+
function shareSummary(live) {
|
|
1096
|
+
const notes = [];
|
|
1097
|
+
if (live.notice) {
|
|
1098
|
+
notes.push(
|
|
1099
|
+
"The first time each browser opens the link, it sees a short notice from webhooks.cc and clicks Open the preview (Free, and paid accounts in their first 7 days)."
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
if (live.password) notes.push("Visitors need the password.");
|
|
1103
|
+
if (live.expiresAt) {
|
|
1104
|
+
notes.push(
|
|
1105
|
+
`The plan stops this share at ${live.expiresAt}; reconnecting does not extend it, and starting it again gives a new link.`
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
notes.push("It runs until stop_share or the end of this MCP server.");
|
|
1109
|
+
return {
|
|
1110
|
+
url: live.url,
|
|
1111
|
+
name: live.name,
|
|
1112
|
+
port: live.port,
|
|
1113
|
+
expiresAt: live.expiresAt,
|
|
1114
|
+
notice: live.notice,
|
|
1115
|
+
password: live.password,
|
|
1116
|
+
notes: notes.join(" ")
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
var REMOTE_SHARE = "`whk share <port>` on the person's computer (or the local MCP server, npx -y @webhooks-cc/mcp, which has share_port)";
|
|
1120
|
+
function shareHints(list, remote = false) {
|
|
1121
|
+
const start = remote ? REMOTE_SHARE : "share_port";
|
|
1122
|
+
const hints = [];
|
|
1123
|
+
const limits = list.limits;
|
|
1124
|
+
const usage = list.usage;
|
|
1125
|
+
const previews = list.shares.filter((s) => s.kind !== "live" && !s.endedAt && s.mine !== false);
|
|
1126
|
+
if (usage?.over) {
|
|
1127
|
+
hints.push(
|
|
1128
|
+
`This month's shared data is used up, so previews are paused until ${usage.resetsAt}. A larger plan (Pro 25 GB, Business 150 GB) raises it; the person upgrades on webhooks.cc.`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
if (limits && previews.length >= limits.shares) {
|
|
1132
|
+
hints.push(
|
|
1133
|
+
`All ${limits.shares} of the plan's preview slots are in use: stop one with stop_share (its id is in shares) before ${start}.`
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
if (limits && limits.sessionMinutes) {
|
|
1137
|
+
hints.push(
|
|
1138
|
+
`Previews on this plan stop after ${limits.sessionMinutes} minutes; ${start} again gives a new link.`
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
if (limits && !limits.passwords) {
|
|
1142
|
+
hints.push("Passwords and reserved names come with Pro and Business.");
|
|
1143
|
+
}
|
|
1144
|
+
return hints;
|
|
1145
|
+
}
|
|
1146
|
+
function toolWords(hint, remote = false) {
|
|
1147
|
+
const words = hint.replace(/whk shares stop(?: <[^>]*>)?/g, "stop_share").replace(/whk shares (?:ls|list)/g, "list_shares").replace(/whk shares log(?: <[^>]*>)?/g, "share_requests").replace(/whk names reserve(?: <[^>]*>)?(?: --team <[^>]*>)?/g, "reserve_name").replace(/whk names release(?: <[^>]*>)?/g, "release_name").replace(/whk names password(?: <[^>]*>)? --clear/g, "clear_name_password").replace(/whk names password(?: <[^>]*>)?/g, "set_name_password").replace(/whk names ls/g, "list_names");
|
|
1148
|
+
if (remote) return words;
|
|
1149
|
+
return words.replace(/whk share <port> --password/g, "share_port with a password").replace(/whk share <port>/g, "share_port");
|
|
1150
|
+
}
|
|
1151
|
+
function withShareHints(list, remote = false) {
|
|
1152
|
+
const server = (list.hints ?? []).map((h) => toolWords(h, remote));
|
|
1153
|
+
const ours = shareHints(list, remote);
|
|
1154
|
+
if (list.suspended && !server.some((h) => /suspended/i.test(h))) {
|
|
1155
|
+
ours.unshift(
|
|
1156
|
+
`Sharing is suspended on this account: ${remote ? "new previews are" : "share_port is"} refused. The person can write to support@webhooks.cc.`
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
const hints = [.../* @__PURE__ */ new Set([...server, ...ours])];
|
|
1160
|
+
return hints.length > 0 ? { ...list, hints } : { ...list };
|
|
1161
|
+
}
|
|
1081
1162
|
function registerTools(target, client, options = {}) {
|
|
1082
1163
|
const handles = [];
|
|
1083
|
-
const
|
|
1164
|
+
const remote = options.remote === true;
|
|
1165
|
+
const server = toolTarget(target, remote, handles);
|
|
1166
|
+
const shareWith = remote ? REMOTE_SHARE : "share_port";
|
|
1084
1167
|
server.tool(
|
|
1085
1168
|
"create_endpoint",
|
|
1086
1169
|
"Create a webhook endpoint. Returns the endpoint slug, URL, and metadata.",
|
|
@@ -1201,6 +1284,18 @@ function registerTools(target, client, options = {}) {
|
|
|
1201
1284
|
return jsonContent(endpoint);
|
|
1202
1285
|
})
|
|
1203
1286
|
);
|
|
1287
|
+
server.tool(
|
|
1288
|
+
"favorite_endpoint",
|
|
1289
|
+
"Mark an endpoint as one of your favourites, or unmark it with favorite: false. A favourite is your own choice, so endpoints shared with you through teams can be marked too; list_endpoints and get_endpoint show it as favorite. Idempotent.",
|
|
1290
|
+
{
|
|
1291
|
+
slug: import_zod2.z.string().describe("The endpoint slug"),
|
|
1292
|
+
favorite: import_zod2.z.boolean().optional().describe("true marks it as a favourite (the default), false unmarks it")
|
|
1293
|
+
},
|
|
1294
|
+
withErrorHandling(async ({ slug, favorite }) => {
|
|
1295
|
+
const result = favorite === false ? await client.endpoints.unfavorite(slug) : await client.endpoints.favorite(slug);
|
|
1296
|
+
return jsonContent({ slug, favorite: result.favorite });
|
|
1297
|
+
})
|
|
1298
|
+
);
|
|
1204
1299
|
server.tool(
|
|
1205
1300
|
"update_endpoint",
|
|
1206
1301
|
"Update an endpoint name, mock response, conditional response rules, signing configuration, whether codes and links are picked out of its emails, or the named fields picked out of them.",
|
|
@@ -2129,6 +2224,143 @@ function registerTools(target, client, options = {}) {
|
|
|
2129
2224
|
);
|
|
2130
2225
|
})
|
|
2131
2226
|
);
|
|
2227
|
+
const started = /* @__PURE__ */ new Map();
|
|
2228
|
+
server.tool(
|
|
2229
|
+
"share_port",
|
|
2230
|
+
"Share a port on this computer at a public link (https://<name>.sharehooks.cc) by running the webhooks.cc CLI (whk share), so a person can open the site you are building. Returns the link. It keeps running until stop_share, the plan's session limit, or the end of this MCP server. Asking again for the same port without a name or password returns the running link; with a name or password, the running share on that port stops and a new one starts. Free accounts get a random name ending in -free, a 2-hour limit and a notice page before the site; Pro and Business can use a reserved name and a password. Needs whk installed on this computer. For a webhook provider that must get your local app's real answer, use `whk tunnel <port> --live` instead.",
|
|
2231
|
+
{
|
|
2232
|
+
port: import_zod2.z.number().int().min(1).max(65535).describe("The local port the site runs on"),
|
|
2233
|
+
name: import_zod2.z.string().optional().describe("A name you reserved (Pro and Business); leave out for a random one"),
|
|
2234
|
+
password: import_zod2.z.string().min(8).max(200).optional().describe("What visitors must type (Pro and Business), 8 to 200 characters")
|
|
2235
|
+
},
|
|
2236
|
+
withErrorHandling(async ({ port, name, password }) => {
|
|
2237
|
+
const running = started.get(port);
|
|
2238
|
+
if (running && !name && !password) {
|
|
2239
|
+
return jsonContent({ ...shareSummary(running), alreadyRunning: true });
|
|
2240
|
+
}
|
|
2241
|
+
if (running) {
|
|
2242
|
+
started.delete(port);
|
|
2243
|
+
await running.stop();
|
|
2244
|
+
}
|
|
2245
|
+
let live;
|
|
2246
|
+
try {
|
|
2247
|
+
live = await client.shares.start({
|
|
2248
|
+
port,
|
|
2249
|
+
...name ? { name } : {},
|
|
2250
|
+
...password ? { password } : {},
|
|
2251
|
+
...process.env.WHK_PATH ? { whkPath: process.env.WHK_PATH } : {}
|
|
2252
|
+
});
|
|
2253
|
+
} catch (error) {
|
|
2254
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2255
|
+
throw new Error(
|
|
2256
|
+
`${message} With these tools: list_shares shows what runs and the plan's limits, stop_share frees a slot, list_names shows the names you can use.`
|
|
2257
|
+
);
|
|
2258
|
+
}
|
|
2259
|
+
started.set(port, live);
|
|
2260
|
+
void live.closed.then(() => {
|
|
2261
|
+
if (started.get(port) === live) started.delete(port);
|
|
2262
|
+
});
|
|
2263
|
+
const summary = shareSummary(live);
|
|
2264
|
+
try {
|
|
2265
|
+
const list = await client.shares.list({ state: "live" });
|
|
2266
|
+
summary.limits = list.limits;
|
|
2267
|
+
summary.usage = list.usage;
|
|
2268
|
+
const hints = shareHints(list);
|
|
2269
|
+
if (hints.length > 0) summary.hints = hints;
|
|
2270
|
+
} catch {
|
|
2271
|
+
}
|
|
2272
|
+
return jsonContent(summary);
|
|
2273
|
+
})
|
|
2274
|
+
);
|
|
2275
|
+
server.tool(
|
|
2276
|
+
"list_shares",
|
|
2277
|
+
`List your public previews of local ports (whk share${remote ? "" : ", share_port"}) and live tunnels (whk tunnel --live): live ones first, then the latest that ended, with this month's shared data and your plan's sharing limits. Not the same as share_endpoint, which shares an endpoint with a team.`,
|
|
2278
|
+
{
|
|
2279
|
+
state: import_zod2.z.enum(["live", "ended"]).optional().describe("Only the running ones, or only the ended ones")
|
|
2280
|
+
},
|
|
2281
|
+
withErrorHandling(async ({ state }) => {
|
|
2282
|
+
return jsonContent(withShareHints(await client.shares.list(state ? { state } : {}), remote));
|
|
2283
|
+
})
|
|
2284
|
+
);
|
|
2285
|
+
server.tool(
|
|
2286
|
+
"stop_share",
|
|
2287
|
+
"Stop a public preview or live tunnel by its id (from list_shares). The CLI running it is told why and exits.",
|
|
2288
|
+
{
|
|
2289
|
+
id: import_zod2.z.string().describe("The share's id, from list_shares")
|
|
2290
|
+
},
|
|
2291
|
+
withErrorHandling(async ({ id }) => {
|
|
2292
|
+
const result = await client.shares.stop(id);
|
|
2293
|
+
return jsonContent({
|
|
2294
|
+
id,
|
|
2295
|
+
stopped: result.stopped,
|
|
2296
|
+
edgeReached: result.edgeReached,
|
|
2297
|
+
note: result.stopped ? result.edgeReached ? "Stopped; its CLI was told and exits." : "Stopped; the edge could not be told at once, so it ends within half a minute." : "It had already ended."
|
|
2298
|
+
});
|
|
2299
|
+
})
|
|
2300
|
+
);
|
|
2301
|
+
server.tool(
|
|
2302
|
+
"share_requests",
|
|
2303
|
+
"The last requests visitors made to a running preview (from list_shares), newest first: method, path, status, time, size, country, device and a number per visitor, never an address. Use it to see whether the person opened the link and what failed for them. `available` is false when the log could not be read just now.",
|
|
2304
|
+
{
|
|
2305
|
+
id: import_zod2.z.string().describe("The share's id, from list_shares")
|
|
2306
|
+
},
|
|
2307
|
+
withErrorHandling(async ({ id }) => {
|
|
2308
|
+
return jsonContent(await client.shares.requests(id));
|
|
2309
|
+
})
|
|
2310
|
+
);
|
|
2311
|
+
server.tool(
|
|
2312
|
+
"list_names",
|
|
2313
|
+
`List the reserved preview names you can share under (Pro and Business): your own and your teams', each with its link, whether it has a password, whether a preview runs under it now, and whether your plan still covers it (usable). Includes how many your plan allows and how many you hold. Share under one with ${remote ? "`whk share <port> --name <name>` on the person's computer (or the local MCP server's share_port)" : "share_port and its name"}.`,
|
|
2314
|
+
{},
|
|
2315
|
+
withErrorHandling(async () => {
|
|
2316
|
+
return jsonContent(await client.names.list());
|
|
2317
|
+
})
|
|
2318
|
+
);
|
|
2319
|
+
server.tool(
|
|
2320
|
+
"reserve_name",
|
|
2321
|
+
`Reserve a preview name, so ${shareWith} can use the link https://<name>.sharehooks.cc (Pro and Business). Lowercase letters, digits and dashes; names that look like random ones or end in -free are refused. With team, the name belongs to that team and every member may share under it.`,
|
|
2322
|
+
{
|
|
2323
|
+
name: import_zod2.z.string().min(1).max(63).describe("The name: lowercase letters, digits and dashes"),
|
|
2324
|
+
team: import_zod2.z.string().optional().describe("A team's id or name (from list_teams), to keep the name inside that team")
|
|
2325
|
+
},
|
|
2326
|
+
withErrorHandling(async ({ name, team }) => {
|
|
2327
|
+
return jsonContent(await client.names.reserve(name, team ? { team } : {}));
|
|
2328
|
+
})
|
|
2329
|
+
);
|
|
2330
|
+
server.tool(
|
|
2331
|
+
"release_name",
|
|
2332
|
+
"Release a reserved preview name you kept (or, for a team name, as the team's owner). A preview running under it stops, and the link stops working.",
|
|
2333
|
+
{
|
|
2334
|
+
name: import_zod2.z.string().min(1).max(63).describe("The name, from list_names")
|
|
2335
|
+
},
|
|
2336
|
+
withErrorHandling(async ({ name }) => {
|
|
2337
|
+
await client.names.release(name);
|
|
2338
|
+
return jsonContent({ released: name });
|
|
2339
|
+
})
|
|
2340
|
+
);
|
|
2341
|
+
server.tool(
|
|
2342
|
+
"set_name_password",
|
|
2343
|
+
"Put a password on every preview under a reserved name (Pro and Business): visitors must type it before the page opens. The password is not shown back; give it to the person yourself.",
|
|
2344
|
+
{
|
|
2345
|
+
name: import_zod2.z.string().min(1).max(63).describe("The name, from list_names"),
|
|
2346
|
+
password: import_zod2.z.string().min(8).max(200).describe("What visitors must type, 8 to 200 characters")
|
|
2347
|
+
},
|
|
2348
|
+
withErrorHandling(async ({ name, password }) => {
|
|
2349
|
+
await client.names.setPassword(name, password);
|
|
2350
|
+
return jsonContent({ name, password: true });
|
|
2351
|
+
})
|
|
2352
|
+
);
|
|
2353
|
+
server.tool(
|
|
2354
|
+
"clear_name_password",
|
|
2355
|
+
"Take the password off a reserved name, so its previews open without one.",
|
|
2356
|
+
{
|
|
2357
|
+
name: import_zod2.z.string().min(1).max(63).describe("The name, from list_names")
|
|
2358
|
+
},
|
|
2359
|
+
withErrorHandling(async ({ name }) => {
|
|
2360
|
+
await client.names.clearPassword(name);
|
|
2361
|
+
return jsonContent({ name, password: false });
|
|
2362
|
+
})
|
|
2363
|
+
);
|
|
2132
2364
|
server.tool(
|
|
2133
2365
|
"describe",
|
|
2134
2366
|
"Describe all available SDK operations, parameters, and types.",
|
|
@@ -2173,7 +2405,8 @@ var AgentSession = class {
|
|
|
2173
2405
|
baseUrl: this.baseUrl,
|
|
2174
2406
|
webhookUrl: this.webhookUrl,
|
|
2175
2407
|
clientName: this.clientName,
|
|
2176
|
-
credentialsFile: this.credentialsFile
|
|
2408
|
+
credentialsFile: this.credentialsFile,
|
|
2409
|
+
userAgent: MCP_USER_AGENT
|
|
2177
2410
|
};
|
|
2178
2411
|
}
|
|
2179
2412
|
/**
|
|
@@ -2266,6 +2499,7 @@ function registerSandboxTools(server, options = {}) {
|
|
|
2266
2499
|
baseUrl,
|
|
2267
2500
|
webhookUrl,
|
|
2268
2501
|
credentialsFile: options.credentialsFile,
|
|
2502
|
+
userAgent: MCP_USER_AGENT,
|
|
2269
2503
|
// The human disconnected the agent: back to the sandbox, unless a
|
|
2270
2504
|
// newer connection is already on display.
|
|
2271
2505
|
onRevoked: () => queueMicrotask(() => {
|
|
@@ -2427,7 +2661,8 @@ function sandboxToolSet(server, session, showAccount) {
|
|
|
2427
2661
|
webhookUrl: session.webhookUrl,
|
|
2428
2662
|
email: normalized,
|
|
2429
2663
|
clientName: session.clientName,
|
|
2430
|
-
credentialsFile: session.credentialsFile
|
|
2664
|
+
credentialsFile: session.credentialsFile,
|
|
2665
|
+
userAgent: MCP_USER_AGENT
|
|
2431
2666
|
}));
|
|
2432
2667
|
session.connect = { via: "connect", pending, email: normalized };
|
|
2433
2668
|
attempt = pending;
|
|
@@ -2536,7 +2771,6 @@ function registerAgentRegistrationTools(server) {
|
|
|
2536
2771
|
}
|
|
2537
2772
|
|
|
2538
2773
|
// src/index.ts
|
|
2539
|
-
var VERSION = true ? "1.16.0" : "0.0.0-dev";
|
|
2540
2774
|
function createServer(options = {}) {
|
|
2541
2775
|
const apiKey = options.apiKey ?? process.env.WHK_API_KEY;
|
|
2542
2776
|
const webhookUrl = options.webhookUrl ?? process.env.WHK_WEBHOOK_URL;
|
|
@@ -2551,7 +2785,7 @@ function createServer(options = {}) {
|
|
|
2551
2785
|
registerPrompts(server);
|
|
2552
2786
|
return server;
|
|
2553
2787
|
}
|
|
2554
|
-
const client = new import_sdk3.WebhooksCC({ apiKey, webhookUrl, baseUrl });
|
|
2788
|
+
const client = new import_sdk3.WebhooksCC({ apiKey, webhookUrl, baseUrl, userAgent: MCP_USER_AGENT });
|
|
2555
2789
|
registerTools(server, client);
|
|
2556
2790
|
registerPrompts(server);
|
|
2557
2791
|
registerResources(server, client);
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
registerTools,
|
|
14
14
|
waitForRequestShape,
|
|
15
15
|
withErrorHandling
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GTEE7L2Y.mjs";
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -260,6 +260,12 @@ import {
|
|
|
260
260
|
SandboxClient,
|
|
261
261
|
WebhooksCC
|
|
262
262
|
} from "@webhooks-cc/sdk";
|
|
263
|
+
|
|
264
|
+
// src/version.ts
|
|
265
|
+
var VERSION = true ? "1.18.0" : "0.0.0-dev";
|
|
266
|
+
var MCP_USER_AGENT = `webhooks-cc-mcp/${VERSION}`;
|
|
267
|
+
|
|
268
|
+
// src/sandbox-tools.ts
|
|
263
269
|
var SANDBOX = {
|
|
264
270
|
maxEndpoints: 3,
|
|
265
271
|
requestsPerEndpoint: 25,
|
|
@@ -291,7 +297,8 @@ var AgentSession = class {
|
|
|
291
297
|
baseUrl: this.baseUrl,
|
|
292
298
|
webhookUrl: this.webhookUrl,
|
|
293
299
|
clientName: this.clientName,
|
|
294
|
-
credentialsFile: this.credentialsFile
|
|
300
|
+
credentialsFile: this.credentialsFile,
|
|
301
|
+
userAgent: MCP_USER_AGENT
|
|
295
302
|
};
|
|
296
303
|
}
|
|
297
304
|
/**
|
|
@@ -384,6 +391,7 @@ function registerSandboxTools(server, options = {}) {
|
|
|
384
391
|
baseUrl,
|
|
385
392
|
webhookUrl,
|
|
386
393
|
credentialsFile: options.credentialsFile,
|
|
394
|
+
userAgent: MCP_USER_AGENT,
|
|
387
395
|
// The human disconnected the agent: back to the sandbox, unless a
|
|
388
396
|
// newer connection is already on display.
|
|
389
397
|
onRevoked: () => queueMicrotask(() => {
|
|
@@ -545,7 +553,8 @@ function sandboxToolSet(server, session, showAccount) {
|
|
|
545
553
|
webhookUrl: session.webhookUrl,
|
|
546
554
|
email: normalized,
|
|
547
555
|
clientName: session.clientName,
|
|
548
|
-
credentialsFile: session.credentialsFile
|
|
556
|
+
credentialsFile: session.credentialsFile,
|
|
557
|
+
userAgent: MCP_USER_AGENT
|
|
549
558
|
}));
|
|
550
559
|
session.connect = { via: "connect", pending, email: normalized };
|
|
551
560
|
attempt = pending;
|
|
@@ -654,7 +663,6 @@ function registerAgentRegistrationTools(server) {
|
|
|
654
663
|
}
|
|
655
664
|
|
|
656
665
|
// src/index.ts
|
|
657
|
-
var VERSION = true ? "1.16.0" : "0.0.0-dev";
|
|
658
666
|
function createServer(options = {}) {
|
|
659
667
|
const apiKey = options.apiKey ?? process.env.WHK_API_KEY;
|
|
660
668
|
const webhookUrl = options.webhookUrl ?? process.env.WHK_WEBHOOK_URL;
|
|
@@ -669,7 +677,7 @@ function createServer(options = {}) {
|
|
|
669
677
|
registerPrompts(server);
|
|
670
678
|
return server;
|
|
671
679
|
}
|
|
672
|
-
const client = new WebhooksCC2({ apiKey, webhookUrl, baseUrl });
|
|
680
|
+
const client = new WebhooksCC2({ apiKey, webhookUrl, baseUrl, userAgent: MCP_USER_AGENT });
|
|
673
681
|
registerTools(server, client);
|
|
674
682
|
registerPrompts(server);
|
|
675
683
|
registerResources(server, client);
|
package/dist/tools.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { WebhooksCC, Request, PayloadSchemaFormat } from '@webhooks-cc/sdk';
|
|
2
|
+
import { WebhooksCC, Request, PayloadSchemaFormat, TunnelShareList } from '@webhooks-cc/sdk';
|
|
3
3
|
|
|
4
4
|
declare const createEndpointShape: {
|
|
5
5
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -166,11 +166,31 @@ interface RegisterToolsOptions {
|
|
|
166
166
|
declare const REMOTE_MAX_WAIT_MS = 50000;
|
|
167
167
|
/** Shortest poll interval on the hosted server: each poll is an API request. */
|
|
168
168
|
declare const REMOTE_MIN_POLL_MS = 1000;
|
|
169
|
+
/**
|
|
170
|
+
* What an agent can do about the account's sharing limits, from a share
|
|
171
|
+
* list: the next step when slots or data run out, so it never has to send
|
|
172
|
+
* the person to the dashboard. `remote` for the hosted server, which has no
|
|
173
|
+
* share_port.
|
|
174
|
+
*/
|
|
175
|
+
declare function shareHints(list: TunnelShareList, remote?: boolean): string[];
|
|
176
|
+
/**
|
|
177
|
+
* A server hint in this server's words: the whk commands it names become
|
|
178
|
+
* the tools that do the same, so an agent does not reach for a CLI. On the
|
|
179
|
+
* hosted server (`remote`) `whk share` stays a command for the person's
|
|
180
|
+
* computer, since that server has no share_port.
|
|
181
|
+
*/
|
|
182
|
+
declare function toolWords(hint: string, remote?: boolean): string;
|
|
183
|
+
/**
|
|
184
|
+
* A share list with hints for an agent, for list_shares and share_port: the
|
|
185
|
+
* server's own (in tool words) and this server's, without repeats, so
|
|
186
|
+
* nothing the server says (a suspension, a pause) is lost.
|
|
187
|
+
*/
|
|
188
|
+
declare function withShareHints(list: TunnelShareList, remote?: boolean): Record<string, unknown>;
|
|
169
189
|
/**
|
|
170
190
|
* Registers the webhooks.cc tools for an account client. Returns their
|
|
171
191
|
* handles, so a caller can swap the tool set later.
|
|
172
192
|
*/
|
|
173
193
|
declare function registerTools(target: ToolServer, client: WebhooksCC, options?: RegisterToolsOptions): RegisteredToolHandle[];
|
|
174
194
|
|
|
175
|
-
export { REMOTE_MAX_WAIT_MS, REMOTE_MIN_POLL_MS, createEndpointShape, deleteEndpointShape, getEndpointShape, getRequestShape, jsonContent, listEndpointsShape, listRequestsShape, payloadSchemaResult, payloadSchemaShape, registerTools, textContent, waitForRequestShape, withErrorHandling };
|
|
195
|
+
export { REMOTE_MAX_WAIT_MS, REMOTE_MIN_POLL_MS, createEndpointShape, deleteEndpointShape, getEndpointShape, getRequestShape, jsonContent, listEndpointsShape, listRequestsShape, payloadSchemaResult, payloadSchemaShape, registerTools, shareHints, textContent, toolWords, waitForRequestShape, withErrorHandling, withShareHints };
|
|
176
196
|
export type { RegisterToolsOptions, RegisteredToolHandle, ToolResult, ToolServer };
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { WebhooksCC, Request, PayloadSchemaFormat } from '@webhooks-cc/sdk';
|
|
2
|
+
import { WebhooksCC, Request, PayloadSchemaFormat, TunnelShareList } from '@webhooks-cc/sdk';
|
|
3
3
|
|
|
4
4
|
declare const createEndpointShape: {
|
|
5
5
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -166,11 +166,31 @@ interface RegisterToolsOptions {
|
|
|
166
166
|
declare const REMOTE_MAX_WAIT_MS = 50000;
|
|
167
167
|
/** Shortest poll interval on the hosted server: each poll is an API request. */
|
|
168
168
|
declare const REMOTE_MIN_POLL_MS = 1000;
|
|
169
|
+
/**
|
|
170
|
+
* What an agent can do about the account's sharing limits, from a share
|
|
171
|
+
* list: the next step when slots or data run out, so it never has to send
|
|
172
|
+
* the person to the dashboard. `remote` for the hosted server, which has no
|
|
173
|
+
* share_port.
|
|
174
|
+
*/
|
|
175
|
+
declare function shareHints(list: TunnelShareList, remote?: boolean): string[];
|
|
176
|
+
/**
|
|
177
|
+
* A server hint in this server's words: the whk commands it names become
|
|
178
|
+
* the tools that do the same, so an agent does not reach for a CLI. On the
|
|
179
|
+
* hosted server (`remote`) `whk share` stays a command for the person's
|
|
180
|
+
* computer, since that server has no share_port.
|
|
181
|
+
*/
|
|
182
|
+
declare function toolWords(hint: string, remote?: boolean): string;
|
|
183
|
+
/**
|
|
184
|
+
* A share list with hints for an agent, for list_shares and share_port: the
|
|
185
|
+
* server's own (in tool words) and this server's, without repeats, so
|
|
186
|
+
* nothing the server says (a suspension, a pause) is lost.
|
|
187
|
+
*/
|
|
188
|
+
declare function withShareHints(list: TunnelShareList, remote?: boolean): Record<string, unknown>;
|
|
169
189
|
/**
|
|
170
190
|
* Registers the webhooks.cc tools for an account client. Returns their
|
|
171
191
|
* handles, so a caller can swap the tool set later.
|
|
172
192
|
*/
|
|
173
193
|
declare function registerTools(target: ToolServer, client: WebhooksCC, options?: RegisterToolsOptions): RegisteredToolHandle[];
|
|
174
194
|
|
|
175
|
-
export { REMOTE_MAX_WAIT_MS, REMOTE_MIN_POLL_MS, createEndpointShape, deleteEndpointShape, getEndpointShape, getRequestShape, jsonContent, listEndpointsShape, listRequestsShape, payloadSchemaResult, payloadSchemaShape, registerTools, textContent, waitForRequestShape, withErrorHandling };
|
|
195
|
+
export { REMOTE_MAX_WAIT_MS, REMOTE_MIN_POLL_MS, createEndpointShape, deleteEndpointShape, getEndpointShape, getRequestShape, jsonContent, listEndpointsShape, listRequestsShape, payloadSchemaResult, payloadSchemaShape, registerTools, shareHints, textContent, toolWords, waitForRequestShape, withErrorHandling, withShareHints };
|
|
176
196
|
export type { RegisterToolsOptions, RegisteredToolHandle, ToolResult, ToolServer };
|