Skip to content

Conversation

@ryoppippi
Copy link
Member

@ryoppippi ryoppippi commented Dec 22, 2025

Summary

  • Add stackone-ai-node as submodule to access MCP mock server
  • Add pytest fixtures that automatically start bun server when needed
  • Rewrite fetch_tools tests to use real MCP protocol instead of monkeypatching

What Changed

  • Submodule: vendor/stackone-ai-node provides the MCP mock server implementation
  • Nix flake: Added bun, pnpm, typescript-go for running the mock server
  • Test infrastructure: tests/conftest.py with session-scoped mcp_mock_server fixture
  • Mock server: tests/mocks/serve.ts imports from Node SDK and exposes /mcp and /actions/rpc
  • Tests: Renamed test_toolset_mcp.pytest_fetch_tools.py, now uses real MCP server

Why

The previous tests used monkeypatch to mock _fetch_mcp_tools, which didn't test the actual MCP protocol communication. This change provides integration tests that exercise the full flow through the MCP SDK, improving confidence in the implementation.

Coverage remains at 90% with more realistic test coverage of the MCP client code paths.

Testing

uv run pytest tests/test_fetch_tools.py -v

All 133 tests pass (22 in test_fetch_tools.py).


Summary by cubic

Added an MCP mock server and pytest fixtures to run integration tests for fetch_tools against a real MCP protocol. Replaced monkeypatch-based tests with end-to-end checks for headers, tool creation, and RPC execution.

  • New Features

    • Added stackone-ai-node as a vendor submodule to provide the MCP mock server.
    • Introduced a session-scoped mcp_mock_server fixture that starts the bun server and returns the base URL.
    • Added a Hono server at tests/mocks/serve.ts exposing /mcp and /actions/rpc.
    • Rewrote tests: added tests/test_fetch_tools.py and removed tests/test_toolset_mcp.py; added an integration marker in pyproject.toml.
  • Migration

    • Initialize submodule: git submodule update --init.
    • Use the Nix devShell to get bun/pnpm/typescript-go, or ensure bun is installed.
    • Run: uv run pytest tests/test_fetch_tools.py -v.

Written for commit 48ad92b. Summary will update automatically on new commits.

Add the Node.js version of stackone-ai SDK as a submodule in
vendor/stackone-ai-node. This provides access to the MCP mock
server implementation for testing Python SDK's fetch_tools
functionality against a real MCP protocol server.
Add Node.js tooling required to run the MCP mock server for testing:
- bun: Fast JavaScript runtime used to run the mock server
- pnpm: Package manager for installing Node dependencies
- typescript-go: TypeScript compiler
Add pytest fixtures and Hono-based MCP mock server for testing
fetch_tools against a real MCP protocol implementation:

- tests/conftest.py: Session-scoped fixture that starts bun server
  automatically when tests require mcp_mock_server
- tests/mocks/serve.ts: Standalone HTTP server importing createMcpApp
  from stackone-ai-node submodule, exposes /mcp and /actions/rpc

The server is started once per test session and provides the same
tool configurations as the Node SDK tests for consistency.
Replace monkeypatch-based tests with integration tests using the
actual MCP protocol via the Hono mock server. This provides more
realistic coverage of the fetch_tools() implementation.

Changes:
- Rename test_toolset_mcp.py to test_fetch_tools.py for clarity
- Use mcp_mock_server fixture for most tests (real MCP protocol)
- Keep monkeypatch tests only for schema normalisation logic
- Add integration marker for MCP server tests
- Add tests for MCP headers, tool creation, and RPC execution

The tests now exercise the full MCP client flow including
_fetch_mcp_tools(), header building, and tool response parsing.
Copilot AI review requested due to automatic review settings December 22, 2025 21:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces monkeypatched test mocks with a real MCP protocol integration test setup. The tests now use an actual MCP mock server imported from the stackone-ai-node submodule, providing end-to-end validation of MCP protocol communication instead of testing stubbed method calls.

Key Changes

  • Added stackone-ai-node as a Git submodule to access its MCP mock server implementation
  • Created pytest fixtures that automatically start a Bun-based HTTP server for integration tests
  • Rewrote all fetch_tools tests to use real MCP protocol communication instead of monkeypatching

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vendor/stackone-ai-node Added submodule reference to the Node SDK containing the MCP mock server
tests/test_toolset_mcp.py Removed old monkeypatched tests
tests/test_fetch_tools.py New integration tests using real MCP server communication
tests/mocks/serve.ts TypeScript server that imports from the submodule and exposes MCP endpoints
tests/conftest.py Pytest configuration with session-scoped fixture for starting the mock server
pyproject.toml Added integration test marker
flake.nix Added bun, pnpm, and typescript-go to support running the mock server
.gitmodules Configured the stackone-ai-node submodule

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# Node.js for MCP mock server
bun
pnpm
typescript-go
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The package name 'typescript-go' appears unusual for TypeScript tooling. Verify this is the correct package name in nixpkgs. The standard TypeScript package is typically named 'typescript' or 'nodePackages.typescript'.

Suggested change
typescript-go
typescript

Copilot uses AI. Check for mistakes.
Comment on lines +112 to +116

@pytest.fixture
def mcp_server_url(mcp_mock_server: str) -> str:
"""Alias for mcp_mock_server for clearer test naming."""
return mcp_mock_server
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The fixture 'mcp_server_url' is defined but never used in the test files. This creates an unnecessary alias that duplicates the 'mcp_mock_server' fixture without adding value. Consider removing this fixture to reduce code duplication.

Suggested change
@pytest.fixture
def mcp_server_url(mcp_mock_server: str) -> str:
"""Alias for mcp_mock_server for clearer test naming."""
return mcp_mock_server

Copilot uses AI. Check for mistakes.
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 8 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="flake.nix">

<violation number="1" location="flake.nix:99">
P3: Misleading comment: Bun is not Node.js. Consider updating the comment to reflect that Bun (a separate JavaScript runtime) is being used, e.g., `# Bun runtime for MCP mock server`.</violation>
</file>

<file name="tests/conftest.py">

<violation number="1" location="tests/conftest.py:20">
P3: `SO_REUSEADDR` is set after `bind()`, making it ineffective. Socket options must be set before binding. Since this function just finds a free port (binding to port 0), the `SO_REUSEADDR` line is unnecessary and can be removed.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

# security
gitleaks

# Node.js for MCP mock server
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 22, 2025

Choose a reason for hiding this comment

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

P3: Misleading comment: Bun is not Node.js. Consider updating the comment to reflect that Bun (a separate JavaScript runtime) is being used, e.g., # Bun runtime for MCP mock server.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At flake.nix, line 99:

<comment>Misleading comment: Bun is not Node.js. Consider updating the comment to reflect that Bun (a separate JavaScript runtime) is being used, e.g., `# Bun runtime for MCP mock server`.</comment>

<file context>
@@ -95,6 +95,11 @@
               # security
               gitleaks
+
+              # Node.js for MCP mock server
+              bun
+              pnpm
</file context>
Suggested change
# Node.js for MCP mock server
# Bun runtime for MCP mock server
Fix with Cubic

"""Find a free port on localhost."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("", 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 22, 2025

Choose a reason for hiding this comment

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

P3: SO_REUSEADDR is set after bind(), making it ineffective. Socket options must be set before binding. Since this function just finds a free port (binding to port 0), the SO_REUSEADDR line is unnecessary and can be removed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/conftest.py, line 20:

<comment>`SO_REUSEADDR` is set after `bind()`, making it ineffective. Socket options must be set before binding. Since this function just finds a free port (binding to port 0), the `SO_REUSEADDR` line is unnecessary and can be removed.</comment>

<file context>
@@ -0,0 +1,116 @@
+    &quot;&quot;&quot;Find a free port on localhost.&quot;&quot;&quot;
+    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+        s.bind((&quot;&quot;, 0))
+        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        return s.getsockname()[1]
+
</file context>
Fix with Cubic

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.

2 participants