## Summary
This PR adds support for custom tool callbacks and comprehensive e2e
testing for MCP calculator functionality.
## Key Features Added
- **Custom tool permission callbacks** - Allow dynamic tool permission
control via `can_use_tool` callback
- **E2E test suite** - Real Claude API tests validating MCP tool
execution end-to-end
- **Fixed MCP calculator example** - Now properly uses `allowed_tools`
for permission management
## Changes
### Custom Callbacks
- Added `ToolPermissionContext` and `PermissionResult` types for tool
permission handling
- Implemented `can_use_tool` callback support in SDK client
- Added comprehensive tests in `tests/test_tool_callbacks.py`
### E2E Testing Infrastructure
- Created `e2e-tests/` directory with pytest-based test suite
- `test_mcp_calculator.py` - Tests all calculator operations with real
API calls
- `conftest.py` - Pytest config with mandatory API key validation
- GitHub Actions workflow for automated e2e testing on main branch
- Comprehensive documentation in `e2e-tests/README.md`
### Bug Fixes
- Fixed MCP calculator example to use `allowed_tools` instead of
incorrect `permission_mode`
- Resolved tool permission issues preventing MCP tools from executing
## Testing
E2E tests require `ANTHROPIC_API_KEY` environment variable and will fail
without it.
Run locally:
```bash
export ANTHROPIC_API_KEY=your-key
python -m pytest e2e-tests/ -v -m e2e
```
Run unit tests including callback tests:
```bash
python -m pytest tests/test_tool_callbacks.py -v
```
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kashyap Murali <kashyap@anthropic.com>
Hide hooks, tool permission callbacks, and SDK MCP server APIs from
public interface while keeping implementation code intact. These
features are not yet stable and should not be documented or exposed to
users.
Changes:
- Remove hook-related exports (HookCallback, HookContext, HookMatcher)
from __all__
- Remove tool permission exports (CanUseTool, ToolPermissionContext)
from __all__
- Remove SDK MCP exports (tool, create_sdk_mcp_server, SdkMcpTool) from
__all__
- Delete examples using unstable APIs (tool_permission_callback.py,
mcp_calculator.py)
- Remove SDK MCP server documentation from README
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds comprehensive support for tool permission callbacks and hook
callbacks to the Python SDK, enabling fine-grained control over tool
execution and custom event handling.
## Key Changes
- **Tool Permission Callbacks**: Control which tools Claude can use and
modify their inputs
- type with async support
- with suggestions from CLI
- for structured responses
- **Hook Callbacks**: React to events in the Claude workflow
- type for event handlers
- for conditional hook execution
- Support for tool_use_start, tool_use_end events
- **Integration**: Full plumbing through ClaudeCodeOptions → Client →
Query
- **Examples**: Comprehensive example showing permission control
patterns
- **Tests**: Coverage for all callback scenarios
## Implementation Details
- Callbacks are registered during initialization phase
- Control protocol handles can_use_tool and hook_callback requests
- Backwards compatible with dict returns for tool permissions
- Proper error handling and type safety throughout
Builds on top of #139's control protocol implementation.
---------
Co-authored-by: Dickson Tsai <dickson@anthropic.com>