Notifications
Send real-time notifications from server to clients using Server-Sent Events (SSE).
Overview
Added in: v1.7.0
Protocol: MCP 2025-11-25
Transport: SSE (Server-Sent Events)
Notifications allow servers to push updates to clients in real-time:
- ✅ Tool invocation progress - Long-running operations
- ✅ Resource updates - File changes, database updates
- ✅ Custom events - Application-specific notifications
- ✅ Session management - Connection state
Quick Start
1. Server-Side: Send Notification
Inject INotificationSender to send notifications:
using Mcp.Gateway.Tools.Notifications;
// Option 1: Constructor injection (class must be registered in DI)
public class MyTools
{
private readonly INotificationSender _notificationSender;
public MyTools(INotificationSender notificationSender)
{
_notificationSender = notificationSender;
}
[McpTool("long_operation")]
public async Task<JsonRpcMessage> LongOperation(JsonRpcMessage request)
{
// Send progress notification
await _notificationSender.SendNotificationAsync(
NotificationMessage.Progress("Starting operation..."));
await Task.Delay(1000);
await _notificationSender.SendNotificationAsync(
NotificationMessage.Progress("50% complete"));
await Task.Delay(1000);
return ToolResponse.Success(request.Id, new { done = true });
}
}
// Register in DI:
builder.Services.AddScoped<MyTools>();
// Option 2: Method parameter injection (no registration needed)
public class MyTools
{
[McpTool("long_operation")]
public async Task<JsonRpcMessage> LongOperation(
JsonRpcMessage request,
INotificationSender notificationSender) // ← Automatically injected!
{
// Send progress notification
await notificationSender.SendNotificationAsync(
NotificationMessage.Progress("Starting operation..."));
await Task.Delay(1000);
await notificationSender.SendNotificationAsync(
NotificationMessage.Progress("50% complete"));
await Task.Delay(1000);
return ToolResponse.Success(request.Id, new { done = true });
}
}
Parameter resolution order:
JsonRpcMessage- The request (always first parameter)- Additional parameters - Resolved from DI container
2. Client-Side: Receive Notifications
// Open SSE connection
const eventSource = new EventSource('http://localhost:5000/mcp', {
headers: {
'MCP-Protocol-Version': '2025-11-25',
'MCP-Session-Id': sessionId
}
});
// Listen for notifications
eventSource.addEventListener('message', (event) => {
const notification = JSON.parse(event.data);
console.log('Notification:', notification);
});
eventSource.addEventListener('error', (error) => {
console.error('SSE error:', error);
});
Notification Types
Resource Updated
await _notificationSender.SendNotificationAsync(
NotificationMessage.ResourcesUpdated("file://data/users.json"));
await _notificationSender.SendNotificationAsync(
NotificationMessage.ResourcesUpdated());
Tools Changed
await _notificationSender.SendNotificationAsync(
NotificationMessage.ToolsChanged());
Prompts Changed
await _notificationSender.SendNotificationAsync(
NotificationMessage.PromptsChanged());
Custom Notifications
await _notificationSender.SendNotificationAsync(
new NotificationMessage(
JsonRpc: "2.0",
Method: "notifications/custom",
Params: new { message = "Custom event" }));
Session Management
Notifications require session management:
// In Program.cs
builder.AddToolsService(); // Automatically includes session management
// Sessions are created on first POST request
// Session ID returned in MCP-Session-Id header
SSE Format
Notifications are sent as Server-Sent Events:
id: 1
event: message
data: {"jsonrpc":"2.0","method":"notifications/progress","params":{"message":"Processing..."}}
id: 2
event: message
data: {"jsonrpc":"2.0","method":"notifications/resources/updated","params":{"uri":"file://data/users.json"}}
Best Practices
1. Keep Messages Small
// ✅ GOOD - Small message
await _notificationSender.SendNotificationAsync(
NotificationMessage.Progress("Step 1 complete"));
// ❌ BAD - Large payload
await _notificationSender.SendNotificationAsync(
NotificationMessage.Progress(largeDataString));
2. Use Resource Subscriptions
// ✅ GOOD - Targeted notifications
await _notificationSender.SendNotificationAsync(
NotificationMessage.ResourcesUpdated("file://specific.json"));
// Only subscribers receive this
// ❌ BAD - Broadcast to all
await _notificationSender.SendNotificationAsync(
NotificationMessage.Progress("Update"));
// All sessions receive this
3. Handle Connection Loss
eventSource.addEventListener('error', (error) => {
// Reconnect automatically
setTimeout(() => {
eventSource = new EventSource(url);
}, 5000);
});
See Also
- Resource Subscriptions - Subscribe to specific resources
- Session Management - Session lifecycle (Coming Soon)
- Getting Started - Quick start guide