Svix App Portal MCP and SDK v2: debugging Sume webhook deliveries

Svix now ships an App Portal MCP server for coding agents. For Sume webhooks, debug with the signature check, a test delivery and redeliver endpoints.

4 min readSume
All posts

If you use Svix to receive or forward webhooks and let a coding agent debug them through the new App Portal MCP server, keep Sume's own checks next to it: verify the HMAC signature, send a test delivery, and redeliver a missed event. Svix's September 2026 changelog lists SDK v2 (where update becomes upsert), a CLI wizard and the App Portal MCP server. Sume's webhook behaviour is documented separately.

What Svix announced

Svix September 2026 items (read 2026-10-02)
ItemDetail
SDK v2Update becomes upsert
CLI wizardNew
App Portal MCP serverLets coding agents debug webhooks

Sume's side of the debugging loop

Start with the signature. Sume signs <timestamp>.<raw_body> with HMAC-SHA256 and sends x-sume-webhook-timestamp, x-sume-webhook-signature as sume-v1=<hex>, and x-sume-webhook-secret-fingerprint. The default replay window is 300 seconds. The fingerprint tells you which secret signed the delivery, useful during the 24 hour rotation window when the signature header carries several entries.

import hashlib
import hmac
import os
import time


def verify(raw: bytes, ts: str, sig_header: str, secret: str) -> bool:
    if not secret:
        raise ValueError("signing secret is empty")
    if abs(time.time() - int(ts)) > 300:
        return False
    mac = hmac.new(secret.encode(), ts.encode() + b"." + raw, hashlib.sha256)
    want = "sume-v1=" + mac.hexdigest()
    return any(hmac.compare_digest(p.strip(), want) for p in sig_header.split(","))


if __name__ == "__main__":
    secret = os.environ.get("SUME_COM_WEBHOOK_SIGNING_SECRET", "")
    body = b'{"ok":true}'
    ts = str(int(time.time()))
    sig = "sume-v1=" + hmac.new(secret.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
    print(verify(body, ts, sig, secret))

Test and replay

Use POST /v1/webhooks/test-deliveries to send a test event, then POST /v1/jobs/{id}/webhook/redeliver (needs jobs:write) or POST /v1/format-runs/{id}/webhook/redeliver (needs formats:write) to replay a real one. Dedupe on job_id for jobs, run_id or request_id for runs, since Sume retries up to 10 times with a 10 second timeout per attempt.

  • The URL must be public HTTPS; redirects are not followed.
  • A receipt over 1 MiB arrives as payload: null with payload_too_large; fetch result_url.
  • Canceled and skipped runs send no webhook.

Keep secrets away from the agent

An agent debugging through MCP should see delivery metadata, not the signing secret. Read the secret with GET /v1/webhooks/signing-secret (account:read) only in the service that verifies. Rotating is POST /v1/webhooks/signing-secret/rotate; do not let an automated debug session do it. Polling remains the backup if deliveries are lost.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume