Skip to content

Add around_request hook for request instrumentation#309

Open
koic wants to merge 1 commit intomodelcontextprotocol:mainfrom
koic:add_around_request_hook_for_request_instrumentation
Open

Add around_request hook for request instrumentation#309
koic wants to merge 1 commit intomodelcontextprotocol:mainfrom
koic:add_around_request_hook_for_request_instrumentation

Conversation

@koic
Copy link
Copy Markdown
Member

@koic koic commented Apr 11, 2026

Motivation and Context

instrumentation_callback fires after request execution, making it impossible to wrap requests with Application Performance Monitoring (APM) spans (e.g. Datadog tracing). This adds around_request, which wraps request handling and allows executing code before and after each request.

For example, to wrap requests with a Datadog trace:

MCP.configure do |config|
  config.around_request = ->(data, &request_handler) {
    Datadog::Tracing.trace("mcp.#{data[:method]}") do
      request_handler.call
    end
  }
end

instrumentation_callback is soft-deprecated in favor of around_request.

How Has This Been Tested?

Added tests for around_request in configuration, instrumentation, and server test files. All existing tests continue to pass.

Breaking Changes

around_request itself is optional and defaults to a pass-through, and instrumentation_callback continues to work as before.

However, instrument_call now accepts a server_context: keyword and its block is invoked without arguments (previously yield block passed the block Proc as an argument). This affects anyone mixing MCP::Instrumentation into their own classes, though the public Server API is unchanged.

Resolves #302.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

## Motivation and Context

`instrumentation_callback` fires after request execution, making it impossible to wrap
requests with Application Performance Monitoring (APM) spans (e.g. Datadog tracing).
This adds `around_request`, which wraps request handling and allows executing code
before and after each request.

For example, to wrap requests with a Datadog trace:

```ruby
MCP.configure do |config|
  config.around_request = ->(data, &request_handler) {
    Datadog::Tracing.trace("mcp.#{data[:method]}") do
      request_handler.call
    end
  }
end
```

`instrumentation_callback` is soft-deprecated in favor of `around_request`.

## How Has This Been Tested?

Added tests for `around_request` in configuration, instrumentation,
and server test files. All existing tests continue to pass.

## Breaking Changes

`around_request` itself is optional and defaults to a pass-through,
and `instrumentation_callback` continues to work as before.

However, `instrument_call` now accepts a `server_context:` keyword and its block is invoked
without arguments (previously `yield block` passed the block Proc as an argument).
This affects anyone mixing `MCP::Instrumentation` into their own classes,
though the public `Server` API is unchanged.

Resolves modelcontextprotocol#302.
Copy link
Copy Markdown
Contributor

@atesgoral atesgoral left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

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.

Proposal: Instrumentation Middleware

2 participants