feat(server): signed webhook management tools — create/list/get/delete (62 → 66) - #70
feat(server): signed webhook management tools — create/list/get/delete (62 → 66)#70johnxie wants to merge 4 commits into
Conversation
…n annotation overrides
…e (62 → 66)
Refresh taskade-public.v2.json from the live spec (45 → 47 paths; adds the
signed-webhook CRUD from upstream v6.213.0) and expose it as four new v2
tools: createWebhook, listWebhooks, getWebhook, deleteWebhook.
These REST-shaped ops omit operationId and their path-derived names would
all collide as 'webhooks' (deriveToolName drops {param} segments and
ignores the method), so the codegen/parser gains an explicit nameOverrides
map keyed by '<lowercase-method> <path>'; the v2 gen script supplies the
four overrides and its prune matcher now mirrors the codegen's
override -> operationId -> derived resolution order.
createWebhook's description surfaces the HMAC reality: the signing secret
is returned exactly once and must be stored securely.
🦋 Changeset detectedLatest commit: 1b25f60 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Code reviewFound 2 issues:
mcp/packages/server/src/tools.v2.generated.ts Lines 407 to 409 in eb0ae29
mcp/packages/server/server.json Lines 3 to 5 in eb0ae29 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
… auto-encodes); registry-safe server.json description
|
Both code-review findings fixed in b64aa52. 1. Double-encoding trap (getWebhook/deleteWebhook descriptions). The upstream spec text ("…by id (its URL-encoded target URL)") told the model to pre-encode the id, but the generated runtime already applies
(and the 2. MCP Registry description limit. Gates re-run on the branch: |
Upstream context
Taskade shipped signed-webhook CRUD in API v2 on Jul 20–21 2026 (changelog v6.213.0 — "MCP Connections Do More & Signed Webhooks"). Refreshing
taskade-public.v2.jsonfrom the live spec (yarn fetch:openapi:v2) brings the path count from 45 → 47:POST /webhooks— register a signed webhook (body:targetUrl,events[], optionalspaceIds[])GET /webhooks— list registered webhooksGET /webhooks/{id}— get one (id = the URL-encoded target URL)DELETE /webhooks/{id}— delete oneThis PR exposes them as four new v2 tools — 62 → 66 tools:
createWebhook,listWebhooks,getWebhook,deleteWebhook.Other live-spec drift picked up by the refresh (kept as-is — it is the live spec): expanded agent-persona enums on
/createAgent,includeTranscripton/getConversation,launcherIcon/coloron the public-agent ops, expandedConvomodel list,Fieldschema additions, and deprecation notes on thesubscribeWebhook/unsubscribeWebhooksummaries ([Deprecated: use POST /webhooks]/[Deprecated: use DELETE /webhooks/:id]) — those flow into the generated descriptions of the two legacy tools.The naming-collision problem →
nameOverridesThese four ops have no
operationId, and they are the first REST-shaped (non-flat-RPC) routes in v2. The codegen's fallbackderiveToolNamedrops{param}segments and ignores the HTTP method, so all four would collide as a single name,webhooks.Design: the codegen/parser now accepts an optional
nameOverridesmap keyed by"<lowercase-method> <path>":operationId→ derived. An override is explicit intent, so it beatsoperationIdtoo.deriveToolNameinstead of a drift-prone local copy./webhooks*ops →webhooks) so the hazard stays documented by a failing-if-changed test.Hard constraint held: the 5 existing v2 names (
promptAgent,listConversations,getConversation,subscribeWebhook,unsubscribeWebhook) and all 57 v1 names are byte-identical (see A1 below).HMAC secret shown once
The
POST /webhooksresponse includes the HMAC signing secret with spec description "shown once. Store it now." — and it is not retrievable afterwards (not even viagetWebhook).createWebhook's tool description (via the per-action description mechanism,TASKADE_V2_ACTION_DESCRIPTIONS) tells the model explicitly:The README's v2 section carries the same warning, and marks
subscribeWebhook/unsubscribeWebhookas legacy/unsigned per upstream deprecation.Stacked PR
Based on
feat/derived-idempotent-openworld-hints(derived idempotent/openWorld hints); retargets tomainautomatically once that merges. The generated diff here includes the correct derived annotations for the new tools (list/get read-only + idempotent, delete destructive + idempotent).Manual live-QA checklist (requires a real
TASKADE_API_KEY; not run in CI)createWebhookwith a testtargetUrl+events: ['task.due']→ response containssecret(returned once); note it downlistWebhooks→ shows the new endpoint (no secret in the payload)getWebhookwith the webhook's raw target URL asid(do NOT pre-URL-encode — the runtime encodes path params automatically) → returns the endpointdeleteWebhookwith the sameid→ cleans up;listWebhooksno longer shows itcreateWebhookagain → a fresh, different secret (confirms shown-once semantics)Assertions (scripted, outputs verbatim)
A1 — tool-name set diff vs baseline
24f491b:A2 — regenerated schemas:
createWebhookinput hastargetUrl(uri),events(enum array, min 1),spaceIds(string array, max 100 — present in spec);getWebhook/deleteWebhookboth takez.object({ id: z.string().min(1) })withpathParamKeys: ['id'].A3 — count consistency:
git grep -n '66' README.md packages/server/server.json→ README lines 16/29/172/302/329 + server.json line 4;git grep -nE '\b62 tools\b'→ no matches.Gates:
yarn buildgreen; working tree clean after post-commit rebuild;yarn lintgreen;yarn testgreen (4 files, 23 tests — includes the new parser tests).Related
Relates to #11 — the webhook layer is now first-class (signed create/list/get/delete via API v2); MCP resource subscriptions themselves remain blocked upstream.
Changesets
@taskade/mcp-openapi-codegen: minor —nameOverridesoption + parser exported from package root@taskade/mcp-server: minor — 4 new signed-webhook tools (62 → 66)