Skip to content

Added support for custom middleware being injected into the underlying MCP server instance#114

Merged
joe-clickhouse merged 9 commits intoClickHouse:mainfrom
andrei-katkov:middleware-injection
Feb 19, 2026
Merged

Added support for custom middleware being injected into the underlying MCP server instance#114
joe-clickhouse merged 9 commits intoClickHouse:mainfrom
andrei-katkov:middleware-injection

Conversation

@andrei-katkov
Copy link
Copy Markdown
Contributor

@andrei-katkov andrei-katkov commented Jan 26, 2026

This PR adds a new configuration option, which allows library users to inject their own middleware into the underlying FastMCP server instance. Middleware class is inferred by the module name provided in configuration.

The specified module is intended to provide a setup_middleware method that receives an instance of the MCP server.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jan 26, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Collaborator

@joe-clickhouse joe-clickhouse left a comment

Choose a reason for hiding this comment

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

Hi @andrei-katkov, thanks for the PR! This is a really nice addition. I left a few comments in the code and there are a few other points:

  1. Looks like there's a typo in the filename mpc_middleware_hook.py. Should it be ‎mcp_.... Notice the transposed "p" and "c".
  2. The current tests are reproducing the logic of the implementation inside the test instead of importing and invoking the actual code, which means they'll always pass even if someone later changes the actual implementation which is problematic. To test the actual code we don't want to mock the setup_middleware function. For example, to test if it correctly handles no configuration, we'll want to do something like:
import os
from unittest.mock import Mock, patch

# Import the actual function
# assuming the filename is fixed to mcp... instead of mpc...
from mcp_clickhouse.mcp_middleware_hook import setup_middleware


class TestMiddleware:
    def test_no_configuration(self):
        """Verify that if no env var is set nothing happens"""
        mock_mcp = Mock()

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("importlib.import_module") as mock_import,
        ):
           # Call the ACTUAL function we imported
            setup_middleware(mock_mcp)

            # Shouldn't attempt imports
            mock_import.assert_not_called()

Let me know if you have any questions about this or would like me to flesh this out further. Happy to help!

Comment thread README.md
Comment thread mcp_clickhouse/mcp_middleware_hook.py
Comment thread mcp_clickhouse/mcp_middleware_hook.py Outdated
logger.error(f"Failed to import middleware module '{middleware_module}': {e}")
except Exception as e:
logger.error(f"Failed to load middleware: {e}")
return mcp
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: The mcp object is modified in place, no need to return it as the caller ignores it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Indeed. This is now fixed in d36d32f. Thank you

@andrei-katkov
Copy link
Copy Markdown
Contributor Author

Hello, @joe-clickhouse. Thank you for your review. I've addressed the following concerns of yours:

  1. Typo was fixed (8b31b92)
  2. Tests were reworked to trigger the actual code paths as you suggested (d4fc8da)
  3. Setup middleware process now raises exception if module import or method invocation has failed (5741ae7)
  4. Added missing example module (3483366)
  5. Not returning the MCP object after modifying in place. (d36d32f)

Can you please review again? Thank you

@joe-clickhouse
Copy link
Copy Markdown
Collaborator

joe-clickhouse commented Feb 18, 2026

Hi @andrei-katkov, I hope you don't mind but I added a few final small changes. Mostly my fault for not noticing on the first review. Take a look when you have a chance, but I think this'll take us over the finish line on this one:

  1. You have a great section about middleware in the README, but I added some minimal env var notes to the section that talks about all the other env vars as well just so people can find them all in one place.
  2. I changed the raise in mcp_middleware_hook.py to be a bare raise instead of raise e in both exception handlers to preserve the original traceback.
  3. I moved some assertions in the test to be outside the pytest.raises blocks otherwise they'd never execute because when setup_middleware raises, execution immediately exit the context manager.

@andrei-katkov
Copy link
Copy Markdown
Contributor Author

andrei-katkov commented Feb 19, 2026

Hello, @joe-clickhouse. Your additional commits make total sense, and I have no objections to them. Let me know if anything else needs to be improved before we can merge it. Thank you very much.

@joe-clickhouse joe-clickhouse merged commit 68a9bcc into ClickHouse:main Feb 19, 2026
2 checks passed
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.

3 participants