Skip to content

feat: expose session context to MCP tool handlers via get_tool_context()#824

Open
Nik-Reddy wants to merge 1 commit intoanthropics:mainfrom
Nik-Reddy:feat/tool-context-session-history-823
Open

feat: expose session context to MCP tool handlers via get_tool_context()#824
Nik-Reddy wants to merge 1 commit intoanthropics:mainfrom
Nik-Reddy:feat/tool-context-session-history-823

Conversation

@Nik-Reddy
Copy link
Copy Markdown

Fixes #823

I've been building tool handlers that need to know things about the current session — like reading back conversation history to avoid repeating work, or just knowing the session ID for logging purposes. Right now there's no way to get that info from inside an @tool function.

This adds a ToolContext dataclass and a get_tool_context() function that tool handlers can call to grab session metadata (session_id, transcript_path, cwd, etc.) and optionally read back conversation history.

How it works

The SDK already receives session metadata through hook callbacks (PreToolUse, PostToolUse) before a tools/call request comes in. This PR captures that metadata into a contextvar, so by the time the tool handler runs, the context is already there.

From inside a tool handler:

`python
from claude_agent_sdk import get_tool_context

@tool
def my_tool(args):
ctx = get_tool_context()
if ctx:
history = ctx.get_conversation_history()
# do something with prior messages
`

get_conversation_history() is an explicit method (not a property) since it does file I/O to parse the JSONL transcript — wanted to make that cost obvious to the caller.

What's changed

  • types.py — new ToolContext dataclass with get_conversation_history()
  • _internal/_tool_context.py — contextvar module for storing/retrieving context
  • _internal/query.py — captures session metadata from hook inputs, sets the contextvar before MCP tool dispatch, resets it after
  • __init__.py — exports get_tool_context and ToolContext
  • tests/test_tool_context.py — 16 tests covering the happy path, missing context, file I/O edge cases, contextvar isolation

Design notes

  • This is a best-effort API — get_tool_context() returns None if no hooks fired before the tool call. Felt like the right tradeoff vs. raising an error.
  • No parameter injection into tool signatures — tools opt in by calling the function explicitly. Keeps backward compatibility and avoids any magic.
  • Conversation history comes from the existing JSONL transcript, no new storage mechanism.

All existing tests still pass (460 total).

…ntext()

Tools registered with @tool can now call get_tool_context() to access
session_id, transcript_path, and conversation history during execution.
Context is best-effort — depends on hook callbacks having fired before
the tool call to provide session metadata.

Fixes anthropics#823
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: expose session context to SDK MCP tool handlers

1 participant