PATTERN Cited by 1 source
Subscribe-notify for updatable resource¶
Definition¶
Subscribe-notify for updatable resource is the MCP-server
pattern for streaming live content (logs, metrics,
notifications, event feeds) by structuring it as an
MCP resource with the
subscribe capability
enabled. The server pushes notifications/resources/updated
events on every content change; clients treat the event as a
cache-invalidation signal and re-read the resource (Source:
sources/2026-01-08-wix-mcp-resources-all-you-need-to-know).
Why this shape wins over alternatives¶
For live data in an MCP-native pipeline:
- Over polling โ polling wastes work for resources that rarely change and lags resources that change faster than the poll interval. Subscribe-notify converts cache invalidation from a polling loop into a push signal.
- Over sending data in tool responses โ a tool invocation returns data at that moment. For live content (logs, metrics) the agent would need to call the tool repeatedly, each call consuming context budget. A subscribed resource is a single URI the client can re-read lazily.
- Over a separate WebSocket / SSE channel โ the pattern uses whatever transport the MCP client and server already have established. No new transport, no new auth, no new config.
Implementation shape (TypeScript SDK)¶
const name = 'my-service-logs';
const uri = 'log://my-service-logs';
const description = 'Returns the last 10 log entries from my service';
let logEntries: string[] = [];
export function registerMyServiceLogsResource(server: McpServer) {
server.registerResource(
name,
uri,
{ description, mimeType: 'text/plain' },
async () => {
const last10 = logEntries.slice(-10).join('\n');
return {
contents: [{
type: 'text',
mimeType: 'text/plain',
uri,
text: last10 || 'No logs yet',
}],
};
},
);
// Emit an update whenever new data arrives:
function onNewLog(entry: string) {
logEntries.push(`[${new Date().toISOString()}] ${entry}`);
server.server.sendResourceUpdated({ uri }); // โ the push
}
// Demo: simulate updates
setInterval(() => onNewLog(`heartbeat`), 20000);
}
Required server declaration¶
const server = new McpServer(
{ name: 'my-server', version: '1.0.0' },
{
capabilities: {
resources: {
subscribe: true,
},
},
},
);
Without the subscribe: true capability the server can still
call sendResourceUpdated but clients will not wire up
notification handlers.
Canonical use cases¶
Per Wix:
- ๐ Live logs โ latest application events
- ๐ Metrics โ real-time monitoring data
- ๐ Notifications โ event streams
- ๐ก Live feeds โ data that changes frequently
Production caveats¶
The @modelcontextprotocol/sdk
v1.8.0 ships with limitations that affect production use:
- No SDK implementation of
subscribe. Clients that try to subscribe via the protocol method receive "method not found". Notifications still flow if the server emits them. - No per-subscriber targeting. Every
sendResourceUpdatedfans out to all connected clients. For a server with N clients each subscribed to a disjoint subset of resources, every client receives every notification โ O(N) wasted traffic per update. - The client must implement re-read. The notification
carries only the URI; clients are responsible for deciding
to re-read and for the actual
resources/readcall.
Server authors at scale will want to implement the subscribe
method themselves to filter notifications per subscriber, and
may want to coalesce bursty updates (e.g. a log source emitting
1000 entries/sec) into periodic batched notifications to avoid
flooding clients.
Pair with¶
Commonly combined with
patterns/expose-resource-as-tool-for-agent-discoverability
so clients that don't auto-discover resources still reach the
subscribed resource through tool listing. Combined pattern: the
agent finds the resource via a resource_link-returning tool,
reads it, and the client's resource layer re-reads on each
resources/updated notification.
Seen in¶
- sources/2026-01-08-wix-mcp-resources-all-you-need-to-know โ
canonical wiki source. Wix's working example simulates updates
every 20 s via
setIntervaland shows the full server-side emission path. Names the three SDK-v1.8.0 limitations (missingsubscribemethod, fan-out-to-all, no subscriber targeting) explicitly.