Skip to main content
Triggers are in draft. Breaking change may happen without notice.
Triggers let your app react to events from the services you’ve connected through Smithery. With Triggers, you can listen to events that happen on various services, such as when a Notion page is updated, or when a commit is pushed to GitHub. Each connection exposes a catalog of trigger types declared by the service; your app activates the ones it needs and receives events as signed HTTP webhooks. Triggers are to events what tools are to actions:
ToolsTriggers
Synchronous action you invokeEvent that fires when something happens upstream
Request/responseSigned HTTP POST to your URL
tools/list, tools/callevents/list, events/subscribe
Both are declared by the MCP server and live under the same connection.

Getting started

This walkthrough wires up a single Notion connection to deliver page.updated events to your app. You’ll need:
  • A Smithery namespace (e.g. my-app) — created on the dashboard or via Connect.
  • A SMITHERY_API_KEY from your namespace settings.

1. Create a connection

Create a connection to Notion with the id notion — this id becomes the stable URL segment for the rest of this walkthrough. mcpUrl is the MCP server URL from the Notion server page on Smithery.
curl -X PUT "https://smithery.run/my-app/notion" \
  -H "Authorization: Bearer $SMITHERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mcpUrl": "https://server.smithery.ai/notion" }'

2. Register a subscription URL

A subscription tells Smithery where to deliver events. Scope it to the notion connection so only Notion events land here.
curl -X POST "https://smithery.run/my-app/notion/.subscriptions" \
  -H "Authorization: Bearer $SMITHERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://my-app.example.com/events" }'
{
  "id": "sub_01HW...",
  "url": "https://my-app.example.com/events",
  "secret": "whsec_..." // shown only once — store securely
}

3. Create a trigger

curl -X POST "https://smithery.run/my-app/notion/.triggers/page.updated" \
  -H "Authorization: Bearer $SMITHERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "params": { "workspace_id": "w_123" } }'

4. Handle events at your URL

Store the secret returned in step 2 as SMITHERY_WEBHOOK_SECRET in your app, then verify incoming deliveries:
import { Webhook } from 'standardwebhooks'

app.post('/events', async (req, res) => {
  const wh = new Webhook(process.env.SMITHERY_WEBHOOK_SECRET!)
  const event = wh.verify(req.rawBody, req.headers)

  if (event.name === 'page.updated') {
    await handlePageUpdated(event.data)
  }

  res.status(204).end()
})

Fan in from multiple connections

Once you have triggers on more than one connection, register a namespace-scoped subscription to receive events from all of them at a single URL:
curl -X POST "https://smithery.run/my-app/.subscriptions" \
  -H "Authorization: Bearer $SMITHERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://my-app.example.com/events" }'
Route on event.connection_id to tell sources apart.

Discovering triggers

# List available trigger types on a connection
curl "https://smithery.run/my-app/notion/.triggers" \
  -H "Authorization: Bearer $SMITHERY_API_KEY"

# Get the schema for a specific trigger
curl "https://smithery.run/my-app/notion/.triggers/page.updated" \
  -H "Authorization: Bearer $SMITHERY_API_KEY"
{
  "name": "page.updated",
  "description": "Fires when a page in the watched workspace is updated.",
  "delivery": ["webhook"],
  "inputSchema": {
    "type": "object",
    "properties": {
      "workspace_id": { "type": "string" }
    },
    "required": ["workspace_id"]
  },
  "payloadSchema": {
    "type": "object",
    "properties": {
      "page_id": { "type": "string" },
      "updated_at": { "type": "string", "format": "date-time" }
    }
  }
}

Creating a trigger

curl -X POST "https://smithery.run/my-app/notion/.triggers/page.updated" \
  -H "Authorization: Bearer $SMITHERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "params": { "workspace_id": "w_123" } }'
{
  "id": "trg_01HW...",
  "name": "page.updated",
  "connection_id": "notion",
  "params": { "workspace_id": "w_123" },
  "created_at": "2026-04-22T12:00:00.000Z"
}
params are the trigger-specific inputs defined by the trigger’s inputSchema (see Discovering triggers above). The same trigger name can have multiple instances (e.g. watch two different workspaces) — each call creates a new instance with its own id.

Subscriptions

A subscription tells Smithery where to deliver events. Create one per destination URL:
  • Connection-scoped (/{namespace}/{connectionId}/.subscriptions) — receives events from one connection. Recommended starting point.
  • Namespace-scoped (/{namespace}/.subscriptions) — fans in events from every connection. Route on event.connection_id.
Each POST returns a subscription id and a one-time secret used to verify webhook signatures.

Receiving events

Smithery delivers events as HTTP POST to your subscription URL. The envelope matches the MCP events proposal’s webhook body shape:
{
  "id": "trg_01HW...",
  "name": "page.updated",
  "timestamp": "2026-04-22T12:00:00.000Z",
  "data": {
    "page_id": "...",
    "updated_at": "2026-04-22T12:00:00.000Z"
  },
  "connection_id": "notion",
  "namespace": "my-app"
}
FieldDescription
idTrigger id this event belongs to.
nameTrigger name, e.g. page.updated.
timestampISO 8601 timestamp from the upstream event.
dataEvent payload, matching the trigger’s payloadSchema.
connection_id, namespaceRouting metadata — useful when a subscription fans in events from multiple connections.
Dedupe on the webhook-id delivery header (see below).

Signature verification

Smithery signs every delivery using the Standard Webhooks specification. Your endpoint receives three headers:
HeaderValue
webhook-idUnique message identifier
webhook-timestampUnix seconds of delivery
webhook-signaturev1,<base64 HMAC-SHA256>
The signed payload is {id}.{timestamp}.{body}, HMAC’d with the subscription secret. Use any Standard Webhooks library to verify — SDKs exist for most languages.

Delivery semantics

  • At-least-once — dedupe on the webhook-id header.
  • Smithery retries 5xx, 408, and 429 responses and network failures with exponential backoff (currently up to 4 attempts over ~20 seconds). 4xx responses outside those codes are treated as terminal.
  • Your handler should be idempotent and return a 2xx status once the event is durably accepted.

Deleting a trigger

curl -X DELETE "https://smithery.run/my-app/notion/.triggers/page.updated/trg_01HW..." \
  -H "Authorization: Bearer $SMITHERY_API_KEY"
Deleting a trigger also deregisters its upstream webhook.

API reference

REST endpoints

All paths are relative to https://smithery.run. Requests require Authorization: Bearer $SMITHERY_API_KEY.
MethodPathPurpose
GET/{ns}/{conn}/.triggersList trigger types on a connection
GET/{ns}/{conn}/.triggers/{name}Get trigger type schema
POST/{ns}/{conn}/.triggers/{name}Create a trigger instance — body { params }
GET/{ns}/{conn}/.triggers/{name}/{id}Get trigger instance detail
DELETE/{ns}/{conn}/.triggers/{name}/{id}Delete a trigger instance
POST/{ns}/.subscriptionsCreate a namespace-wide subscription — body { url }
GET/{ns}/.subscriptionsList namespace subscriptions
DELETE/{ns}/.subscriptions/{id}Delete a namespace subscription
POST/{ns}/{conn}/.subscriptionsCreate a connection-scoped subscription
GET/{ns}/{conn}/.subscriptionsList connection-scoped subscriptions
DELETE/{ns}/{conn}/.subscriptions/{id}Delete a connection-scoped subscription

MCP methods

Available on any server advertising the ai.smithery/events extension during initialize. Field and method names track the MCP committee’s events proposal so migration to the standardized events/* namespace will be a prefix drop.
MethodParamsResult
ai.smithery/events/list{ events: [{ name, description, delivery, inputSchema, payloadSchema }] }
ai.smithery/events/subscribe{ id, name, params, delivery: { mode, url } }{}
ai.smithery/events/unsubscribe{ id, delivery: { url } }{}

Webhook delivery headers

HeaderValue
webhook-idUnique message identifier — dedupe on this
webhook-timestampUnix seconds
webhook-signaturev1,<base64 HMAC-SHA256> over {id}.{timestamp}.{body} using the subscription secret

Learn more