@webhooks-cc/mcp 1.5.0 → 1.6.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/dist/bin/mcp.js +109 -6
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +111 -6
- package/dist/index.mjs +113 -8
- package/package.json +2 -2
package/dist/bin/mcp.js
CHANGED
|
@@ -1103,24 +1103,127 @@ function registerTools(server, client) {
|
|
|
1103
1103
|
return jsonContent(description);
|
|
1104
1104
|
})
|
|
1105
1105
|
);
|
|
1106
|
+
registerAgentRegistrationTools(server);
|
|
1107
|
+
}
|
|
1108
|
+
function resolveBaseUrl() {
|
|
1109
|
+
return process.env.WHK_BASE_URL ?? "https://webhooks.cc";
|
|
1110
|
+
}
|
|
1111
|
+
function registerAgentRegistrationTools(server) {
|
|
1112
|
+
const baseUrl = resolveBaseUrl();
|
|
1113
|
+
server.tool(
|
|
1114
|
+
"how_to_register",
|
|
1115
|
+
"Explain how an agent self-registers for a webhooks.cc API credential (auth.md). Call this FIRST when you have no API key. Returns the three registration flows and the auth.md documentation URL. No authentication required.",
|
|
1116
|
+
{},
|
|
1117
|
+
withErrorHandling(async () => {
|
|
1118
|
+
return jsonContent({
|
|
1119
|
+
...import_sdk.WebhooksCC.describeRegistration(baseUrl),
|
|
1120
|
+
next_steps: [
|
|
1121
|
+
"Easiest: call register_agent (anonymous) to get a key immediately, then have a human run claim_agent with the returned userCode while logged in to webhooks.cc.",
|
|
1122
|
+
"Or set WHK_API_KEY to an existing whcc_ key and use the authenticated tools."
|
|
1123
|
+
]
|
|
1124
|
+
});
|
|
1125
|
+
})
|
|
1126
|
+
);
|
|
1127
|
+
server.tool(
|
|
1128
|
+
"register_agent",
|
|
1129
|
+
"Self-register for a webhooks.cc API credential via the anonymous auth.md flow. Returns a whcc_ API key that works immediately in a bounded sandbox, plus a short userCode and claimUrl a human uses to bind the key to their account. No authentication required. After registering, set WHK_API_KEY to the returned credential.",
|
|
1130
|
+
{
|
|
1131
|
+
clientName: import_zod2.z.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1132
|
+
},
|
|
1133
|
+
withErrorHandling(async ({ clientName }) => {
|
|
1134
|
+
const reg = await import_sdk.WebhooksCC.register.anonymous({ baseUrl, clientName });
|
|
1135
|
+
return jsonContent({
|
|
1136
|
+
credential: reg.credential,
|
|
1137
|
+
scopes: reg.scopes,
|
|
1138
|
+
claim: {
|
|
1139
|
+
userCode: reg.userCode,
|
|
1140
|
+
claimUrl: reg.claimUrl,
|
|
1141
|
+
claimToken: reg.claimToken,
|
|
1142
|
+
expiresAt: reg.claimTokenExpires,
|
|
1143
|
+
instructions: `Ask a human to open ${reg.claimUrl} while logged in to webhooks.cc and either enter the code ${reg.userCode} or open ${reg.claimUrl}?token=${reg.claimToken}. Then call check_claim with the claimToken.`
|
|
1144
|
+
},
|
|
1145
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools. Before it is claimed the key can create ephemeral endpoints and read its own captured requests in the sandbox."
|
|
1146
|
+
});
|
|
1147
|
+
})
|
|
1148
|
+
);
|
|
1149
|
+
server.tool(
|
|
1150
|
+
"check_claim",
|
|
1151
|
+
"Check whether an anonymous registration's API key has been claimed by a human yet. Poll this after register_agent until status is 'claimed'. No authentication required.",
|
|
1152
|
+
{
|
|
1153
|
+
claimToken: import_zod2.z.string().describe("The claimToken returned by register_agent")
|
|
1154
|
+
},
|
|
1155
|
+
withErrorHandling(async ({ claimToken }) => {
|
|
1156
|
+
const poll = await import_sdk.WebhooksCC.register.pollClaim(claimToken, { baseUrl });
|
|
1157
|
+
return jsonContent(poll);
|
|
1158
|
+
})
|
|
1159
|
+
);
|
|
1160
|
+
server.tool(
|
|
1161
|
+
"register_agent_with_email",
|
|
1162
|
+
"Self-register via the verified_email auth.md flow: webhooks.cc emails a one-time code to the address. The credential is WITHHELD until the code is confirmed with verify_agent_otp. Returns a claimToken to pass to verify_agent_otp. No authentication required.",
|
|
1163
|
+
{
|
|
1164
|
+
email: import_zod2.z.string().email({ message: "Invalid email address" }).describe("The email address to verify and bind the credential to"),
|
|
1165
|
+
clientName: import_zod2.z.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1166
|
+
},
|
|
1167
|
+
withErrorHandling(async ({ email, clientName }) => {
|
|
1168
|
+
const challenge = await import_sdk.WebhooksCC.register.withEmail(email, { baseUrl, clientName });
|
|
1169
|
+
return jsonContent({
|
|
1170
|
+
claimToken: challenge.claimToken,
|
|
1171
|
+
expiresAt: challenge.claimTokenExpires,
|
|
1172
|
+
postClaimScopes: challenge.postClaimScopes,
|
|
1173
|
+
next_step: `A one-time code was emailed to ${email}. Ask the human for it, then call verify_agent_otp with this claimToken and the code.`
|
|
1174
|
+
});
|
|
1175
|
+
})
|
|
1176
|
+
);
|
|
1177
|
+
server.tool(
|
|
1178
|
+
"verify_agent_otp",
|
|
1179
|
+
"Complete the verified_email flow: submit the emailed OTP with the claimToken from register_agent_with_email. On success returns the whcc_ API key (bound to the verified email). Set WHK_API_KEY to it. No authentication required.",
|
|
1180
|
+
{
|
|
1181
|
+
claimToken: import_zod2.z.string().describe("The claimToken returned by register_agent_with_email"),
|
|
1182
|
+
otp: import_zod2.z.string().describe("The one-time code the human received by email")
|
|
1183
|
+
},
|
|
1184
|
+
withErrorHandling(async ({ claimToken, otp }) => {
|
|
1185
|
+
const issued = await import_sdk.WebhooksCC.register.confirmEmailOtp({ claimToken, otp }, { baseUrl });
|
|
1186
|
+
return jsonContent({
|
|
1187
|
+
credential: issued.credential,
|
|
1188
|
+
scopes: issued.scopes,
|
|
1189
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1190
|
+
});
|
|
1191
|
+
})
|
|
1192
|
+
);
|
|
1193
|
+
server.tool(
|
|
1194
|
+
"register_agent_with_idjag",
|
|
1195
|
+
"Self-register via the identity_assertion (ID-JAG) auth.md flow: present a verified identity-assertion JWT (urn:ietf:params:oauth:token-type:id-jag) from a trusted provider. The credential is returned synchronously \u2014 no human claim step. No webhooks.cc authentication required, but only works if webhooks.cc trusts your provider.",
|
|
1196
|
+
{
|
|
1197
|
+
assertion: import_zod2.z.string().describe("The ID-JAG assertion JWT (typ oauth-id-jag+jwt) from a trusted provider")
|
|
1198
|
+
},
|
|
1199
|
+
withErrorHandling(async ({ assertion }) => {
|
|
1200
|
+
const issued = await import_sdk.WebhooksCC.register.withIdJag(assertion, { baseUrl });
|
|
1201
|
+
return jsonContent({
|
|
1202
|
+
credential: issued.credential,
|
|
1203
|
+
scopes: issued.scopes,
|
|
1204
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1205
|
+
});
|
|
1206
|
+
})
|
|
1207
|
+
);
|
|
1106
1208
|
}
|
|
1107
1209
|
|
|
1108
1210
|
// src/index.ts
|
|
1109
|
-
var VERSION = true ? "1.
|
|
1211
|
+
var VERSION = true ? "1.6.0" : "0.0.0-dev";
|
|
1110
1212
|
function createServer(options = {}) {
|
|
1111
1213
|
const apiKey = options.apiKey ?? process.env.WHK_API_KEY;
|
|
1214
|
+
const server = new import_mcp2.McpServer({
|
|
1215
|
+
name: "webhooks-cc",
|
|
1216
|
+
version: VERSION
|
|
1217
|
+
});
|
|
1112
1218
|
if (!apiKey) {
|
|
1113
|
-
|
|
1219
|
+
registerAgentRegistrationTools(server);
|
|
1220
|
+
return server;
|
|
1114
1221
|
}
|
|
1115
1222
|
const client = new import_sdk2.WebhooksCC({
|
|
1116
1223
|
apiKey,
|
|
1117
1224
|
webhookUrl: options.webhookUrl ?? process.env.WHK_WEBHOOK_URL,
|
|
1118
1225
|
baseUrl: options.baseUrl ?? process.env.WHK_BASE_URL
|
|
1119
1226
|
});
|
|
1120
|
-
const server = new import_mcp2.McpServer({
|
|
1121
|
-
name: "webhooks-cc",
|
|
1122
|
-
version: VERSION
|
|
1123
|
-
});
|
|
1124
1227
|
registerTools(server, client);
|
|
1125
1228
|
registerPrompts(server);
|
|
1126
1229
|
registerResources(server, client);
|
package/dist/index.d.mts
CHANGED
|
@@ -3,6 +3,14 @@ import { WebhooksCC } from '@webhooks-cc/sdk';
|
|
|
3
3
|
|
|
4
4
|
/** Register all webhook tools on an MCP server instance. */
|
|
5
5
|
declare function registerTools(server: McpServer, client: WebhooksCC): void;
|
|
6
|
+
/**
|
|
7
|
+
* Agent self-registration tools (auth.md). These are UNAUTHENTICATED — they let
|
|
8
|
+
* an agent that does NOT yet have a webhooks.cc credential obtain one, then
|
|
9
|
+
* configure the MCP server with the returned key (WHK_API_KEY). Registered on
|
|
10
|
+
* every server so a probing agent can always discover the on-ramp via
|
|
11
|
+
* `describe` / `how_to_register`.
|
|
12
|
+
*/
|
|
13
|
+
declare function registerAgentRegistrationTools(server: McpServer): void;
|
|
6
14
|
|
|
7
15
|
declare function registerPrompts(server: McpServer): void;
|
|
8
16
|
|
|
@@ -30,4 +38,4 @@ interface CreateServerOptions {
|
|
|
30
38
|
*/
|
|
31
39
|
declare function createServer(options?: CreateServerOptions): McpServer;
|
|
32
40
|
|
|
33
|
-
export { type CreateServerOptions, createServer, registerPrompts, registerResources, registerTools };
|
|
41
|
+
export { type CreateServerOptions, createServer, registerAgentRegistrationTools, registerPrompts, registerResources, registerTools };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ import { WebhooksCC } from '@webhooks-cc/sdk';
|
|
|
3
3
|
|
|
4
4
|
/** Register all webhook tools on an MCP server instance. */
|
|
5
5
|
declare function registerTools(server: McpServer, client: WebhooksCC): void;
|
|
6
|
+
/**
|
|
7
|
+
* Agent self-registration tools (auth.md). These are UNAUTHENTICATED — they let
|
|
8
|
+
* an agent that does NOT yet have a webhooks.cc credential obtain one, then
|
|
9
|
+
* configure the MCP server with the returned key (WHK_API_KEY). Registered on
|
|
10
|
+
* every server so a probing agent can always discover the on-ramp via
|
|
11
|
+
* `describe` / `how_to_register`.
|
|
12
|
+
*/
|
|
13
|
+
declare function registerAgentRegistrationTools(server: McpServer): void;
|
|
6
14
|
|
|
7
15
|
declare function registerPrompts(server: McpServer): void;
|
|
8
16
|
|
|
@@ -30,4 +38,4 @@ interface CreateServerOptions {
|
|
|
30
38
|
*/
|
|
31
39
|
declare function createServer(options?: CreateServerOptions): McpServer;
|
|
32
40
|
|
|
33
|
-
export { type CreateServerOptions, createServer, registerPrompts, registerResources, registerTools };
|
|
41
|
+
export { type CreateServerOptions, createServer, registerAgentRegistrationTools, registerPrompts, registerResources, registerTools };
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
createServer: () => createServer,
|
|
24
|
+
registerAgentRegistrationTools: () => registerAgentRegistrationTools,
|
|
24
25
|
registerPrompts: () => registerPrompts,
|
|
25
26
|
registerResources: () => registerResources,
|
|
26
27
|
registerTools: () => registerTools
|
|
@@ -1124,24 +1125,127 @@ function registerTools(server, client) {
|
|
|
1124
1125
|
return jsonContent(description);
|
|
1125
1126
|
})
|
|
1126
1127
|
);
|
|
1128
|
+
registerAgentRegistrationTools(server);
|
|
1129
|
+
}
|
|
1130
|
+
function resolveBaseUrl() {
|
|
1131
|
+
return process.env.WHK_BASE_URL ?? "https://webhooks.cc";
|
|
1132
|
+
}
|
|
1133
|
+
function registerAgentRegistrationTools(server) {
|
|
1134
|
+
const baseUrl = resolveBaseUrl();
|
|
1135
|
+
server.tool(
|
|
1136
|
+
"how_to_register",
|
|
1137
|
+
"Explain how an agent self-registers for a webhooks.cc API credential (auth.md). Call this FIRST when you have no API key. Returns the three registration flows and the auth.md documentation URL. No authentication required.",
|
|
1138
|
+
{},
|
|
1139
|
+
withErrorHandling(async () => {
|
|
1140
|
+
return jsonContent({
|
|
1141
|
+
...import_sdk.WebhooksCC.describeRegistration(baseUrl),
|
|
1142
|
+
next_steps: [
|
|
1143
|
+
"Easiest: call register_agent (anonymous) to get a key immediately, then have a human run claim_agent with the returned userCode while logged in to webhooks.cc.",
|
|
1144
|
+
"Or set WHK_API_KEY to an existing whcc_ key and use the authenticated tools."
|
|
1145
|
+
]
|
|
1146
|
+
});
|
|
1147
|
+
})
|
|
1148
|
+
);
|
|
1149
|
+
server.tool(
|
|
1150
|
+
"register_agent",
|
|
1151
|
+
"Self-register for a webhooks.cc API credential via the anonymous auth.md flow. Returns a whcc_ API key that works immediately in a bounded sandbox, plus a short userCode and claimUrl a human uses to bind the key to their account. No authentication required. After registering, set WHK_API_KEY to the returned credential.",
|
|
1152
|
+
{
|
|
1153
|
+
clientName: import_zod2.z.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1154
|
+
},
|
|
1155
|
+
withErrorHandling(async ({ clientName }) => {
|
|
1156
|
+
const reg = await import_sdk.WebhooksCC.register.anonymous({ baseUrl, clientName });
|
|
1157
|
+
return jsonContent({
|
|
1158
|
+
credential: reg.credential,
|
|
1159
|
+
scopes: reg.scopes,
|
|
1160
|
+
claim: {
|
|
1161
|
+
userCode: reg.userCode,
|
|
1162
|
+
claimUrl: reg.claimUrl,
|
|
1163
|
+
claimToken: reg.claimToken,
|
|
1164
|
+
expiresAt: reg.claimTokenExpires,
|
|
1165
|
+
instructions: `Ask a human to open ${reg.claimUrl} while logged in to webhooks.cc and either enter the code ${reg.userCode} or open ${reg.claimUrl}?token=${reg.claimToken}. Then call check_claim with the claimToken.`
|
|
1166
|
+
},
|
|
1167
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools. Before it is claimed the key can create ephemeral endpoints and read its own captured requests in the sandbox."
|
|
1168
|
+
});
|
|
1169
|
+
})
|
|
1170
|
+
);
|
|
1171
|
+
server.tool(
|
|
1172
|
+
"check_claim",
|
|
1173
|
+
"Check whether an anonymous registration's API key has been claimed by a human yet. Poll this after register_agent until status is 'claimed'. No authentication required.",
|
|
1174
|
+
{
|
|
1175
|
+
claimToken: import_zod2.z.string().describe("The claimToken returned by register_agent")
|
|
1176
|
+
},
|
|
1177
|
+
withErrorHandling(async ({ claimToken }) => {
|
|
1178
|
+
const poll = await import_sdk.WebhooksCC.register.pollClaim(claimToken, { baseUrl });
|
|
1179
|
+
return jsonContent(poll);
|
|
1180
|
+
})
|
|
1181
|
+
);
|
|
1182
|
+
server.tool(
|
|
1183
|
+
"register_agent_with_email",
|
|
1184
|
+
"Self-register via the verified_email auth.md flow: webhooks.cc emails a one-time code to the address. The credential is WITHHELD until the code is confirmed with verify_agent_otp. Returns a claimToken to pass to verify_agent_otp. No authentication required.",
|
|
1185
|
+
{
|
|
1186
|
+
email: import_zod2.z.string().email({ message: "Invalid email address" }).describe("The email address to verify and bind the credential to"),
|
|
1187
|
+
clientName: import_zod2.z.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1188
|
+
},
|
|
1189
|
+
withErrorHandling(async ({ email, clientName }) => {
|
|
1190
|
+
const challenge = await import_sdk.WebhooksCC.register.withEmail(email, { baseUrl, clientName });
|
|
1191
|
+
return jsonContent({
|
|
1192
|
+
claimToken: challenge.claimToken,
|
|
1193
|
+
expiresAt: challenge.claimTokenExpires,
|
|
1194
|
+
postClaimScopes: challenge.postClaimScopes,
|
|
1195
|
+
next_step: `A one-time code was emailed to ${email}. Ask the human for it, then call verify_agent_otp with this claimToken and the code.`
|
|
1196
|
+
});
|
|
1197
|
+
})
|
|
1198
|
+
);
|
|
1199
|
+
server.tool(
|
|
1200
|
+
"verify_agent_otp",
|
|
1201
|
+
"Complete the verified_email flow: submit the emailed OTP with the claimToken from register_agent_with_email. On success returns the whcc_ API key (bound to the verified email). Set WHK_API_KEY to it. No authentication required.",
|
|
1202
|
+
{
|
|
1203
|
+
claimToken: import_zod2.z.string().describe("The claimToken returned by register_agent_with_email"),
|
|
1204
|
+
otp: import_zod2.z.string().describe("The one-time code the human received by email")
|
|
1205
|
+
},
|
|
1206
|
+
withErrorHandling(async ({ claimToken, otp }) => {
|
|
1207
|
+
const issued = await import_sdk.WebhooksCC.register.confirmEmailOtp({ claimToken, otp }, { baseUrl });
|
|
1208
|
+
return jsonContent({
|
|
1209
|
+
credential: issued.credential,
|
|
1210
|
+
scopes: issued.scopes,
|
|
1211
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1212
|
+
});
|
|
1213
|
+
})
|
|
1214
|
+
);
|
|
1215
|
+
server.tool(
|
|
1216
|
+
"register_agent_with_idjag",
|
|
1217
|
+
"Self-register via the identity_assertion (ID-JAG) auth.md flow: present a verified identity-assertion JWT (urn:ietf:params:oauth:token-type:id-jag) from a trusted provider. The credential is returned synchronously \u2014 no human claim step. No webhooks.cc authentication required, but only works if webhooks.cc trusts your provider.",
|
|
1218
|
+
{
|
|
1219
|
+
assertion: import_zod2.z.string().describe("The ID-JAG assertion JWT (typ oauth-id-jag+jwt) from a trusted provider")
|
|
1220
|
+
},
|
|
1221
|
+
withErrorHandling(async ({ assertion }) => {
|
|
1222
|
+
const issued = await import_sdk.WebhooksCC.register.withIdJag(assertion, { baseUrl });
|
|
1223
|
+
return jsonContent({
|
|
1224
|
+
credential: issued.credential,
|
|
1225
|
+
scopes: issued.scopes,
|
|
1226
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1227
|
+
});
|
|
1228
|
+
})
|
|
1229
|
+
);
|
|
1127
1230
|
}
|
|
1128
1231
|
|
|
1129
1232
|
// src/index.ts
|
|
1130
|
-
var VERSION = true ? "1.
|
|
1233
|
+
var VERSION = true ? "1.6.0" : "0.0.0-dev";
|
|
1131
1234
|
function createServer(options = {}) {
|
|
1132
1235
|
const apiKey = options.apiKey ?? process.env.WHK_API_KEY;
|
|
1236
|
+
const server = new import_mcp2.McpServer({
|
|
1237
|
+
name: "webhooks-cc",
|
|
1238
|
+
version: VERSION
|
|
1239
|
+
});
|
|
1133
1240
|
if (!apiKey) {
|
|
1134
|
-
|
|
1241
|
+
registerAgentRegistrationTools(server);
|
|
1242
|
+
return server;
|
|
1135
1243
|
}
|
|
1136
1244
|
const client = new import_sdk2.WebhooksCC({
|
|
1137
1245
|
apiKey,
|
|
1138
1246
|
webhookUrl: options.webhookUrl ?? process.env.WHK_WEBHOOK_URL,
|
|
1139
1247
|
baseUrl: options.baseUrl ?? process.env.WHK_BASE_URL
|
|
1140
1248
|
});
|
|
1141
|
-
const server = new import_mcp2.McpServer({
|
|
1142
|
-
name: "webhooks-cc",
|
|
1143
|
-
version: VERSION
|
|
1144
|
-
});
|
|
1145
1249
|
registerTools(server, client);
|
|
1146
1250
|
registerPrompts(server);
|
|
1147
1251
|
registerResources(server, client);
|
|
@@ -1150,6 +1254,7 @@ function createServer(options = {}) {
|
|
|
1150
1254
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1151
1255
|
0 && (module.exports = {
|
|
1152
1256
|
createServer,
|
|
1257
|
+
registerAgentRegistrationTools,
|
|
1153
1258
|
registerPrompts,
|
|
1154
1259
|
registerResources,
|
|
1155
1260
|
registerTools
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
-
import { WebhooksCC } from "@webhooks-cc/sdk";
|
|
3
|
+
import { WebhooksCC as WebhooksCC2 } from "@webhooks-cc/sdk";
|
|
4
4
|
|
|
5
5
|
// src/prompts.ts
|
|
6
6
|
import { z } from "zod";
|
|
@@ -255,6 +255,7 @@ import {
|
|
|
255
255
|
UnauthorizedError,
|
|
256
256
|
VERIFY_PROVIDERS,
|
|
257
257
|
verifySignature,
|
|
258
|
+
WebhooksCC,
|
|
258
259
|
WebhooksCCError
|
|
259
260
|
} from "@webhooks-cc/sdk";
|
|
260
261
|
var MAX_BODY_SIZE = 32768;
|
|
@@ -1117,24 +1118,127 @@ function registerTools(server, client) {
|
|
|
1117
1118
|
return jsonContent(description);
|
|
1118
1119
|
})
|
|
1119
1120
|
);
|
|
1121
|
+
registerAgentRegistrationTools(server);
|
|
1122
|
+
}
|
|
1123
|
+
function resolveBaseUrl() {
|
|
1124
|
+
return process.env.WHK_BASE_URL ?? "https://webhooks.cc";
|
|
1125
|
+
}
|
|
1126
|
+
function registerAgentRegistrationTools(server) {
|
|
1127
|
+
const baseUrl = resolveBaseUrl();
|
|
1128
|
+
server.tool(
|
|
1129
|
+
"how_to_register",
|
|
1130
|
+
"Explain how an agent self-registers for a webhooks.cc API credential (auth.md). Call this FIRST when you have no API key. Returns the three registration flows and the auth.md documentation URL. No authentication required.",
|
|
1131
|
+
{},
|
|
1132
|
+
withErrorHandling(async () => {
|
|
1133
|
+
return jsonContent({
|
|
1134
|
+
...WebhooksCC.describeRegistration(baseUrl),
|
|
1135
|
+
next_steps: [
|
|
1136
|
+
"Easiest: call register_agent (anonymous) to get a key immediately, then have a human run claim_agent with the returned userCode while logged in to webhooks.cc.",
|
|
1137
|
+
"Or set WHK_API_KEY to an existing whcc_ key and use the authenticated tools."
|
|
1138
|
+
]
|
|
1139
|
+
});
|
|
1140
|
+
})
|
|
1141
|
+
);
|
|
1142
|
+
server.tool(
|
|
1143
|
+
"register_agent",
|
|
1144
|
+
"Self-register for a webhooks.cc API credential via the anonymous auth.md flow. Returns a whcc_ API key that works immediately in a bounded sandbox, plus a short userCode and claimUrl a human uses to bind the key to their account. No authentication required. After registering, set WHK_API_KEY to the returned credential.",
|
|
1145
|
+
{
|
|
1146
|
+
clientName: z2.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1147
|
+
},
|
|
1148
|
+
withErrorHandling(async ({ clientName }) => {
|
|
1149
|
+
const reg = await WebhooksCC.register.anonymous({ baseUrl, clientName });
|
|
1150
|
+
return jsonContent({
|
|
1151
|
+
credential: reg.credential,
|
|
1152
|
+
scopes: reg.scopes,
|
|
1153
|
+
claim: {
|
|
1154
|
+
userCode: reg.userCode,
|
|
1155
|
+
claimUrl: reg.claimUrl,
|
|
1156
|
+
claimToken: reg.claimToken,
|
|
1157
|
+
expiresAt: reg.claimTokenExpires,
|
|
1158
|
+
instructions: `Ask a human to open ${reg.claimUrl} while logged in to webhooks.cc and either enter the code ${reg.userCode} or open ${reg.claimUrl}?token=${reg.claimToken}. Then call check_claim with the claimToken.`
|
|
1159
|
+
},
|
|
1160
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools. Before it is claimed the key can create ephemeral endpoints and read its own captured requests in the sandbox."
|
|
1161
|
+
});
|
|
1162
|
+
})
|
|
1163
|
+
);
|
|
1164
|
+
server.tool(
|
|
1165
|
+
"check_claim",
|
|
1166
|
+
"Check whether an anonymous registration's API key has been claimed by a human yet. Poll this after register_agent until status is 'claimed'. No authentication required.",
|
|
1167
|
+
{
|
|
1168
|
+
claimToken: z2.string().describe("The claimToken returned by register_agent")
|
|
1169
|
+
},
|
|
1170
|
+
withErrorHandling(async ({ claimToken }) => {
|
|
1171
|
+
const poll = await WebhooksCC.register.pollClaim(claimToken, { baseUrl });
|
|
1172
|
+
return jsonContent(poll);
|
|
1173
|
+
})
|
|
1174
|
+
);
|
|
1175
|
+
server.tool(
|
|
1176
|
+
"register_agent_with_email",
|
|
1177
|
+
"Self-register via the verified_email auth.md flow: webhooks.cc emails a one-time code to the address. The credential is WITHHELD until the code is confirmed with verify_agent_otp. Returns a claimToken to pass to verify_agent_otp. No authentication required.",
|
|
1178
|
+
{
|
|
1179
|
+
email: z2.string().email({ message: "Invalid email address" }).describe("The email address to verify and bind the credential to"),
|
|
1180
|
+
clientName: z2.string().optional().describe("A human-readable name for this agent, recorded on the issued key")
|
|
1181
|
+
},
|
|
1182
|
+
withErrorHandling(async ({ email, clientName }) => {
|
|
1183
|
+
const challenge = await WebhooksCC.register.withEmail(email, { baseUrl, clientName });
|
|
1184
|
+
return jsonContent({
|
|
1185
|
+
claimToken: challenge.claimToken,
|
|
1186
|
+
expiresAt: challenge.claimTokenExpires,
|
|
1187
|
+
postClaimScopes: challenge.postClaimScopes,
|
|
1188
|
+
next_step: `A one-time code was emailed to ${email}. Ask the human for it, then call verify_agent_otp with this claimToken and the code.`
|
|
1189
|
+
});
|
|
1190
|
+
})
|
|
1191
|
+
);
|
|
1192
|
+
server.tool(
|
|
1193
|
+
"verify_agent_otp",
|
|
1194
|
+
"Complete the verified_email flow: submit the emailed OTP with the claimToken from register_agent_with_email. On success returns the whcc_ API key (bound to the verified email). Set WHK_API_KEY to it. No authentication required.",
|
|
1195
|
+
{
|
|
1196
|
+
claimToken: z2.string().describe("The claimToken returned by register_agent_with_email"),
|
|
1197
|
+
otp: z2.string().describe("The one-time code the human received by email")
|
|
1198
|
+
},
|
|
1199
|
+
withErrorHandling(async ({ claimToken, otp }) => {
|
|
1200
|
+
const issued = await WebhooksCC.register.confirmEmailOtp({ claimToken, otp }, { baseUrl });
|
|
1201
|
+
return jsonContent({
|
|
1202
|
+
credential: issued.credential,
|
|
1203
|
+
scopes: issued.scopes,
|
|
1204
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1205
|
+
});
|
|
1206
|
+
})
|
|
1207
|
+
);
|
|
1208
|
+
server.tool(
|
|
1209
|
+
"register_agent_with_idjag",
|
|
1210
|
+
"Self-register via the identity_assertion (ID-JAG) auth.md flow: present a verified identity-assertion JWT (urn:ietf:params:oauth:token-type:id-jag) from a trusted provider. The credential is returned synchronously \u2014 no human claim step. No webhooks.cc authentication required, but only works if webhooks.cc trusts your provider.",
|
|
1211
|
+
{
|
|
1212
|
+
assertion: z2.string().describe("The ID-JAG assertion JWT (typ oauth-id-jag+jwt) from a trusted provider")
|
|
1213
|
+
},
|
|
1214
|
+
withErrorHandling(async ({ assertion }) => {
|
|
1215
|
+
const issued = await WebhooksCC.register.withIdJag(assertion, { baseUrl });
|
|
1216
|
+
return jsonContent({
|
|
1217
|
+
credential: issued.credential,
|
|
1218
|
+
scopes: issued.scopes,
|
|
1219
|
+
usage: "Set WHK_API_KEY to `credential` to use the authenticated tools."
|
|
1220
|
+
});
|
|
1221
|
+
})
|
|
1222
|
+
);
|
|
1120
1223
|
}
|
|
1121
1224
|
|
|
1122
1225
|
// src/index.ts
|
|
1123
|
-
var VERSION = true ? "1.
|
|
1226
|
+
var VERSION = true ? "1.6.0" : "0.0.0-dev";
|
|
1124
1227
|
function createServer(options = {}) {
|
|
1125
1228
|
const apiKey = options.apiKey ?? process.env.WHK_API_KEY;
|
|
1229
|
+
const server = new McpServer2({
|
|
1230
|
+
name: "webhooks-cc",
|
|
1231
|
+
version: VERSION
|
|
1232
|
+
});
|
|
1126
1233
|
if (!apiKey) {
|
|
1127
|
-
|
|
1234
|
+
registerAgentRegistrationTools(server);
|
|
1235
|
+
return server;
|
|
1128
1236
|
}
|
|
1129
|
-
const client = new
|
|
1237
|
+
const client = new WebhooksCC2({
|
|
1130
1238
|
apiKey,
|
|
1131
1239
|
webhookUrl: options.webhookUrl ?? process.env.WHK_WEBHOOK_URL,
|
|
1132
1240
|
baseUrl: options.baseUrl ?? process.env.WHK_BASE_URL
|
|
1133
1241
|
});
|
|
1134
|
-
const server = new McpServer2({
|
|
1135
|
-
name: "webhooks-cc",
|
|
1136
|
-
version: VERSION
|
|
1137
|
-
});
|
|
1138
1242
|
registerTools(server, client);
|
|
1139
1243
|
registerPrompts(server);
|
|
1140
1244
|
registerResources(server, client);
|
|
@@ -1142,6 +1246,7 @@ function createServer(options = {}) {
|
|
|
1142
1246
|
}
|
|
1143
1247
|
export {
|
|
1144
1248
|
createServer,
|
|
1249
|
+
registerAgentRegistrationTools,
|
|
1145
1250
|
registerPrompts,
|
|
1146
1251
|
registerResources,
|
|
1147
1252
|
registerTools
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webhooks-cc/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "MCP server for webhooks.cc — AI agent integration for webhook testing",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
40
40
|
"zod": "^4.4.3",
|
|
41
|
-
"@webhooks-cc/sdk": "1.
|
|
41
|
+
"@webhooks-cc/sdk": "1.8.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^25.9.1",
|