modelcontextprotocol / modelcontextprotocol/typescript-sdk
Bug Report-1: Missing Cancellation Logging Implementation
Nobody has claimed this yet.
- #1034 by @KKonstantinov — closed without merging
- Dominant language
- TypeScript
- Stars
- 13.4k
- Forks
- 2.2k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 4
Description
Summary
The TypeScript SDK violates the MCP specification by not implementing logging for cancellation reasons, which is explicitly required for debugging purposes.
Specification Violation
According to the MCP specification, cancellation notifications should include logging requirements:
Receivers of cancellation notifications SHOULD:
Both parties SHOULD log cancellation reasons for debugging
Current Implementation Issue
Location
File: src/shared/protocol.ts
Functions:
Protocol.request()method -cancelfunction (lines 582-601)Protocolconstructor - cancellation notification handler (lines 231-236)
Architecture Context
Protocolis a base class inherited by bothClientandServer- Both sending and receiving cancellation notifications happen in the shared base class
- The specification requires both parties to log cancellation reasons
Problem
The current implementation lacks logging for cancellation reasons on both sides:
1. Sender Side (cancel function)
const cancel = (reason: unknown) => {
this._responseHandlers.delete(messageId);
this._progressHandlers.delete(messageId);
this._cleanupTimeout(messageId);
this._transport?.send({
jsonrpc: "2.0",
method: "notifications/cancelled",
params: {
requestId: messageId,
reason: String(reason), // ✅ Reason is sent
},
});
// ❌ Missing: No logging of why the request was cancelled
};
2. Receiver Side (notification handler)
this.setNotificationHandler(CancelledNotificationSchema, (notification) => {
const controller = this._requestHandlerAbortControllers.get(
notification.params.requestId,
);
controller?.abort(notification.params.reason);
// ❌ Missing: No logging of received cancellation notification
});
Impact
- Specification Compliance: Violates explicit MCP requirement for logging cancellation reasons
- Debugging Difficulty: No visibility into why requests are being cancelled
- Troubleshooting: Difficult to diagnose cancellation-related issues in production
- Monitoring: No audit trail for cancellation events
Proposed Fix
1. Sender Side Logging
Add logging in the cancel function:
const cancel = (reason: unknown) => {
// Log cancellation reason for debugging
console.log(`[${this.constructor.name}] Cancelling request ${messageId}: ${String(reason)}`);
this._responseHandlers.delete(messageId);
this._progressHandlers.delete(messageId);
this._cleanupTimeout(messageId);
this._transport?.send({
jsonrpc: "2.0",
method: "notifications/cancelled",
params: {
requestId: messageId,
reason: String(reason),
},
});
};
2. Receiver Side Logging
Add logging in the notification handler:
this.setNotificationHandler(CancelledNotificationSchema, (notification) => {
// Log received cancellation notification for debugging
console.log(`[${this.constructor.name}] Received cancellation for request ${notification.params.requestId}: ${notification.params.reason || 'No reason provided'}`);
const controller = this._requestHandlerAbortControllers.get(
notification.params.requestId,
);
controller?.abort(notification.params.reason);
});
3. Alternative: Configurable Logging
Make logging configurable to avoid console spam in production:
constructor(private _options?: ProtocolOptions) {
// Add logging option
const enableCancellationLogging = this._options?.enableCancellationLogging ?? true;
this.setNotificationHandler(CancelledNotificationSchema, (notification) => {
if (enableCancellationLogging) {
console.log(`[${this.constructor.name}] Received cancellation for request ${notification.params.requestId}: ${notification.params.reason || 'No reason provided'}`);
}
// ... rest of handler
});
}
Testing
The fix should be tested with:
- Client cancelling requests (should log cancellation reason)
- Server cancelling requests (should log cancellation reason)
- Client receiving cancellation notifications (should log received cancellation)
- Server receiving cancellation notifications (should log received cancellation)
- Different cancellation reasons (timeout, manual abort, error conditions)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading src/shared/protocol.ts, especially Protocol.request()'s cancel function and the cancellation notification handler in the constructor. Check how cancellation is sent and received, then add coverage for client and server cancellation with different reasons. Done means both sides provide cancellation-reason logging without changing cancellation behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100