Skip to content

feat: add MCP event definitions in the events/list format and a catalog endpoint - #1182

Open
alexluong wants to merge 7 commits into
feat/mcp-destinationfrom
feat/mcp-schemas
Open

alexluong wants to merge 7 commits into
feat/mcp-destinationfrom
feat/mcp-schemas

Conversation

@alexluong

@alexluong alexluong commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Let an operator define the events MCP Events (draft SEP-3415) clients can subscribe to, serve them as an MCP events/list catalog, and turn a subscription's arguments into a delivery filter. Experimental, behind EXPERIMENTAL_MCP_ENABLED.

Stacked on #1181. Deviations from the draft: see #1181.

Definitions use the draft's events/list shape, so a list from another MCP server can be loaded as is. The operator declares each event's inputSchema; Outpost checks it can be mapped to a filter and refuses it otherwise. A subscription must target a defined event, its arguments are checked against that event's inputSchema, and only events matching the arguments are delivered.

Changes

  1. Event definitions. EXPERIMENTAL_MCP_EVENTS_SCHEMA (experimental.mcp.events_schema in YAML) holds {"events": [{name, description?, inputSchema, payloadSchema, delivery?, _meta?}]}. In the environment, a value starting with { is the definitions as inline JSON, parsed as strictly as a .json file, and any other value is a path to a JSON or YAML file. In the YAML config a mapping is inline definitions and a string is always a path. URLs are rejected. Every name must be in TOPICS when that is set, delivery must include webhook when present, _meta is passed through, duplicate names and unknown fields are errors. An invalid definition fails startup with a message that names the setting. YAML definitions are parsed with YAML 1.2 rules, so values such as 2026-01-01 or yes in an enum stay strings, and duplicate keys are errors.
  2. Arguments. inputSchema is declared by the operator, so editing payloadSchema never changes which arguments clients may send. Each argument is a string, number, integer or boolean with no default, and must name a top-level payloadSchema property of a compatible type. additionalProperties must be false or absent, and every required name must be a property. Outpost matches each argument against the data field of the same name by equality. {"type": "object", "properties": {}} is the form for an event without arguments.
  3. Validation and filter. On create, the topic must be in the catalog (422, topics / not_found), config.arguments must satisfy the inputSchema, and an argument the schema doesn't list is refused. The arguments become the destination's filter, which can't be set directly or changed afterwards. This uses a new optional provider interface, CreateValidator, that runs before the verification call.
  4. Catalog endpoint. GET /api/v1/mcp/events (Admin API key) returns the events in configured order as an events/list result: name, description, inputSchema, payloadSchema, delivery: ["webhook"], plus resultType and nextCursor. topics=a,b, limit and cursor select and page. It returns 404 while MCP is off or no events are defined.

Behavior changes

  • With no definitions configured, creating an mcp destination is refused and GET /mcp/events returns 404. (feat: add experimental mcp destination type for MCP Events webhooks #1181 alone accepts any allowed topic.)
  • Checks run on create only. Subscriptions created before definitions were configured keep delivering unfiltered until recreated, and a later change to the definitions doesn't block rotating a subscription's secret.
  • New dependency: github.com/santhosh-tekuri/jsonschema/v6.

Not in this PR

  • Subscribe and unsubscribe handling: feat: add MCP subscribe and unsubscribe endpoints #1183.
  • Changing the catalog while Outpost runs: definitions are read at startup, and the server never sends listChanged (optional in the draft).
  • Ideas, not built: a dry-run endpoint that validates definitions without applying them; an endpoint that infers definitions from stored events; loading definitions from a URL; exporting the catalog as AsyncAPI.

🤖 Generated with Claude Code

@alexluong
alexluong force-pushed the feat/mcp-destination branch from 22e738d to 3fb2119 Compare October 30, 2026 13:15
@alexluong alexluong changed the title feat: add MCP event definitions and events endpoint feat: add MCP event definitions in the events/list format and a catalog endpoint Oct 30, 2026
alexluong and others added 7 commits October 31, 2026 03:40
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant