Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Oct 26, 2025

feat: MCP progress notifications and middleware headers support

Summary

This PR adds end-to-end support for MCP tool progress notifications and middleware interoperability via transport headers.

Key changes:

  • New event type MCPToolProgressEvent to emit progress updates from MCP tools via the CrewAI event bus.
  • MCPToolWrapper now:
    • Accepts an optional progress_callback callable, agent, and task context.
    • Registers a progress handler on the MCP client session to:
      • Invoke the provided progress_callback.
      • Emit MCPToolProgressEvent with tool/server metadata plus optional agent/task context.
    • Passes custom HTTP headers to the MCP streamable HTTP client for middleware (e.g., auth, tracing).
  • Agent and BaseAgent:
    • BaseAgent gains two fields: mcp_progress_enabled (bool, default False) and mcp_server_headers (dict[str, str] | None).
    • Agent._get_external_mcp_tools(server_ref, task: Task | None = None) threads progress and headers through to MCPToolWrapper. Default task=None preserves compatibility for existing call sites.
  • Events exports:
    • Expose MCPToolProgressEvent in crewai.events for easy access.
  • Documentation:
    • Adds “Progress Notifications” and “Middleware Support with Headers” sections, with examples for enabling progress, listening for events, configuring headers, and combining both.
  • Tests:
    • New test suite for MCPToolWrapper validating:
      • Initialization with/without progress_callback.
      • Emission of MCPToolProgressEvent with expected fields.
      • Header passthrough behavior (headers present when provided, absent otherwise).
      • Basic integration flow with progress and headers.
    • Tests use sys.modules stubbing to simulate mcp, mcp.client, and mcp.client.streamable_http with a correct async context manager for streamablehttp_client and an async ClientSession. This ensures CI runs without external MCP dependencies.

Files of interest:

  • lib/crewai/src/crewai/events/types/tool_usage_events.py: adds MCPToolProgressEvent
  • lib/crewai/src/crewai/events/init.py: exports MCPToolProgressEvent
  • lib/crewai/src/crewai/tools/mcp_tool_wrapper.py: progress and headers support, event emission
  • lib/crewai/src/crewai/agents/agent_builder/base_agent.py: new config fields
  • lib/crewai/src/crewai/agent.py: threads progress and headers into MCPToolWrapper
  • lib/crewai/tests/tools/test_mcp_tool_wrapper.py: new tests covering feature behavior
  • docs/en/mcp/dsl-integration.mdx: new docs and examples

CI status: All checks passing (tests, type-checker, lint, CodeQL).

Review & Testing Checklist for Human

4 items

  • Event bus API in docs vs implementation: In code/tests, the event bus registration method is register_handler(event_type, handler). The docs currently show crewai_event_bus.register(MCPToolProgressEvent, ...). Please confirm the correct public API and update the docs snippet accordingly to prevent user confusion.
  • Progress semantics with MCP SDK: Confirm that the MCP client session supports session.on_progress and that progress_notification has progress, optional total, and message fields across supported MCP versions. If not universal, consider guarding with safe checks or documenting requirements.
  • Headers passthrough on real server: With a real MCP server over streamable HTTP, verify that mcp_server_headers are received server-side (e.g., Authorization, X-Client-ID). Confirm behavior when mcp_server_headers is None (i.e., no headers are sent).
  • Backward compatibility: Validate that existing agents and flows that don’t set mcp_progress_enabled or mcp_server_headers are unaffected. Check that Agent._get_external_mcp_tools’ new optional task parameter doesn’t break existing call sites.

Recommended test plan:

  1. Real MCP server sanity check
    • Run an MCP server that can emit progress notifications (e.g., a demo tool that reports progress 0→100 with messages).
    • Create an Agent with mcp_progress_enabled=True and attach a handler for MCPToolProgressEvent.
    • Kick off a task that uses an MCP tool and verify that progress events arrive with expected fields, and the tool completes.
  2. Middleware/headers check
    • Configure Agent.mcp_server_headers with Authorization and a custom X-Request-ID.
    • On the server, log incoming headers and confirm they match what was set.
  3. Regression check
    • Run a standard Agent without mcp_progress_enabled and without mcp_server_headers, verify tool execution behaves exactly as before.
  4. Docs quick run
    • Try the examples in the new docs sections to ensure they run unmodified (modulo the event bus API method name noted above).

Notes

  • Progress emission is opt-in via mcp_progress_enabled; leaving it False preserves current behavior and avoids event traffic for users who don’t need it.
  • MCPToolProgressEvent includes agent/task metadata when available; if absent, fields are None by design.
  • Tests rely on sys.modules stubs for mcp.* to avoid adding new test-only dependencies; this is intentional for CI stability.
  • Link to Devin run: https://app.devin.ai/sessions/50e74c33ad8343b792684cb03a53f7fc
  • Requested by: João (joao@crewai.com)
Implements progress reporting and HTTP headers support for MCP tool integration
to address issue #3797.

Changes:
- Add MCPToolProgressEvent to event system for real-time progress tracking
- Extend MCPToolWrapper to support progress callbacks and event emission
- Add mcp_progress_enabled flag to Agent for opt-in progress notifications
- Add mcp_server_headers to Agent for middleware authentication/tracking
- Thread progress and headers configuration through Agent._get_external_mcp_tools
- Add comprehensive test coverage for progress and headers features
- Update MCP DSL documentation with progress and headers examples

Features:
- Progress notifications emitted as MCPToolProgressEvent via event bus
- Optional progress callback for custom progress handling
- HTTP headers passthrough for authentication and middleware integration
- Agent and task context included in progress events
- Opt-in design ensures backward compatibility

Tests:
- Unit tests for MCPToolWrapper progress and headers functionality
- Integration tests for Agent MCP configuration
- Mock-based tests to avoid network dependencies

Documentation:
- Added Progress Notifications section with examples
- Added Middleware Support with Headers section
- Included complete examples for common use cases

Fixes #3797

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring
devin-ai-integration bot and others added 4 commits October 26, 2025 09:52
- Fix event bus API: use register_handler instead of register
- Fix mock import paths: patch mcp.client.streamable_http.streamablehttp_client and mcp.ClientSession at their actual import locations

Co-Authored-By: João <joao@crewai.com>
- Add autouse fixture to stub mcp, mcp.client, and mcp.client.streamable_http modules
- Revert patch targets to module-local names (crewai.tools.mcp_tool_wrapper.*)
- This fixes ModuleNotFoundError in CI where mcp package is not installed
- The stub fixture ensures tests can run without requiring the actual mcp package

Co-Authored-By: João <joao@crewai.com>
- Remove all patch() calls for module-local names (streamablehttp_client, ClientSession)
- Rely solely on sys.modules stub fixture for mcp module imports
- Patch ClientSession.__init__ directly to configure mock behavior
- This fixes AttributeError issues where patch() tried to access non-existent module attributes

Co-Authored-By: João <joao@crewai.com>
- Change fake_streamablehttp_client from async def to regular def
- async with expects an object with __aenter__/__aexit__, not a coroutine
- Add __path__ to make mcp modules look like packages
- Add last_kwargs tracking for header assertions
- Add proper assertions to verify headers are passed/not passed
- This fixes TypeError: 'coroutine' object does not support async context manager protocol

Co-Authored-By: João <joao@crewai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant