MCP 1.26+ includes "meta":null in serialization, earlier versions don't.
Parse JSON and check the meaningful fields instead of exact string match.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MCP 1.26.0 now includes `meta: null` in ReadResourceContents JSON
serialization. Update the test snapshot to match.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates pydocket dependency to the new branch with proper asyncio
cancellation handling that works on Python 3.10+.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Temporarily pulls pydocket from chrisguidry/docket to explore
compatibility with the upcoming 0.17 release.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tasks belong in capabilities.tasks (first-class field) per SEP-1686,
not capabilities.experimental.tasks. This fixes VS Code Copilot 1.107+
integration which checks capabilities.tasks?.requests?.tools?.call.
Changes:
- Update get_task_capabilities() to return ServerTasksCapability types
- Override get_capabilities() in LowLevelServer to set tasks field
- Remove experimental_capabilities parameter usage
- Update test to verify correct location
Fixes#2870
Removes all the verbose debug logging added during diagnosis while
preserving the essential fix: Context.__aenter__ sets _current_docket
and _current_worker from server instance attributes. This ensures
ContextVars work in ASGI environments where lifespan and request
handlers run in sibling async contexts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All three handlers (tool, prompt, resource) now have identical patterns:
- Debug logging for docket access, Redis writes, docket.add, subscriptions
- Try/except with traceback logging around Redis and docket operations
- Consistent error messages with instance_id
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove redundant ContextVar handling:
- _lifespan_manager no longer re-sets ContextVars in early-return branch
- Handler fallback logic removed (no more `if docket is None: docket = server._docket`)
The authoritative place for request-context ContextVars is now Context.__aenter__,
which sets _current_docket and _current_worker from server instance attributes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
pydocket 0.16.5 fixes an issue where worker_group_name was passed as
a KEY instead of ARGV in Lua scripts, causing ACL failures when Redis
users are restricted to key patterns.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tracing where the Redis ACL error occurs - the initial Redis writes
succeed but error happens somewhere after.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When Redis operations fail, log the full traceback to help diagnose
ACL and permission issues in production environments.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds detailed logging to Context.__aenter__ and __aexit__ to track:
- When Context is entered/exited
- Values of server._docket and server._worker
- ContextVar values before and after setting
- Token values for debugging reset issues
This will help diagnose why ContextVars might not propagate in Lambda.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of relying on ContextVar propagation from lifespan (which fails
in Lambda), set _current_docket and _current_worker when entering a
Context for each request. This ensures user dependencies like
CurrentDocket() and CurrentWorker() work in all environments.
The values come from server._docket and server._worker which are always
available after lifespan initialization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ContextVars set during lifespan don't propagate to request handlers
in Lambda (works fine locally). As a workaround, fall back to using
server._docket when the ContextVar returns None.
This is a Lambda-specific issue - possibly related to how Lambda Web
Adapter or Lambda's asyncio runtime handles context propagation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When FastMCP runs with uvicorn, the lifespan is entered twice:
1. FastMCP's outer context (during http_app setup)
2. Starlette's ASGI lifespan (which request handlers inherit from)
The second call was skipping ContextVar setup because _lifespan_result_set
was already True. This caused _current_docket.get() to return None in
request handlers even though server._docket was correctly set.
Fix: Always set ContextVars when entering _lifespan_manager, using the
already-initialized values from self._docket and self._worker.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>