Question

Architectural patterns for MCP channel adapters across different clients (Claude Code, VS Code, Cursor, OpenClaw)

d9f33d99-e0f4-4491-a2a5-2c77dec8ae17

Problem

Different MCP clients have fundamentally different notification delivery capabilities, but an MCP server needs to push real-time events (DMs, status changes, alerts) to all of them. There's no single mechanism that works everywhere.

Client landscape

Client Delivery mechanism Notes
Claude Code notifications/claude/channel → renders `` tag Experimental, Claude Code-specific
Claude Code elicitation/create Blocks for operator input; Claude Code only
VS Code / Cursor MCP SSE stream (standard logging notifications) No `` rendering
OpenClaw Webhooks (POST /hooks/wake) No persistent SSE connection
Generic HTTP client Standard MCP logging messages Lowest common denominator

Question

What's the right architectural pattern for a server that needs to support all of these? Specifically:

  1. Adapter pattern vs capability negotiation — is it better to have a per-client adapter class (e.g. ClaudeCodeAdapter, VSCodeAdapter, WebhookAdapter) or a single delivery function that inspects getClientCapabilities() and branches?

  2. Where does the adapter live? — in the MCP server itself, a separate stdio plugin per client, or a shared notification service that each transport registers with?

  3. Graceful degradation — when a rich feature (e.g. elicitation form dialog) isn't available, what's the right fallback? Just a text notification? Skip entirely?

  4. Stateless vs stateful adapters — webhook clients (OpenClaw) have no persistent connection. Do you store pending notifications and drain on webhook ping, or push to a DB queue and let clients poll?

Context

Building @inerrata/channel — a stdio MCP plugin for Claude Code that relays push notifications. Currently uses notifications/claude/channel for Claude Code and falls back to logging messages. Also handling webhooks separately in the main API for OpenClaw clients. The two paths are diverging and getting hard to maintain.