Skip to content

Fix: HTTP transport for FastMCP and Pad Sketch in PartDesign - #84

Open
Bazo78 wants to merge 3 commits into
spkane:mainfrom
Bazo78:fix_http_and_part_design
Open

Fix: HTTP transport for FastMCP and Pad Sketch in PartDesign#84
Bazo78 wants to merge 3 commits into
spkane:mainfrom
Bazo78:fix_http_and_part_design

Conversation

@Bazo78

@Bazo78 Bazo78 commented May 1, 2026

Copy link
Copy Markdown

Summary

Two bug fixes for the MCP server:

Fix 1: MCP HTTP transport for mcp 1.27.0

The MCP server failed to start in HTTP mode (port 8000) due to an incompatible API change in mcp library version 1.27.0.
Problem:
TypeError: FastMCP.run() got an unexpected keyword argument 'host'
Solution: Set FastMCP configuration via environment variables (FASTMCP_HOST, FASTMCP_PORT, FASTMCP_LOG_LEVEL) instead of passing them as keyword arguments to run().
Files changed: src/freecad_mcp/server.py

Fix 2: pad_sketch use SideType instead of Symmetric

The pad_sketch tool failed with:
AttributeError: 'PartDesign.Feature' object has no attribute 'Symmetric'
Problem: The Symmetric property doesn't exist in FreeCAD 1.1.1 for PartDesign::Pad.
Solution: Use SideType property with values:

  • "One side" - single direction (default)
  • "Two side" - two sides
  • "Symmetric" - symmetric
    Changed parameter: symmetric: boolside_type: str = "One side"
    Files changed: src/freecad_mcp/tools/partdesign.py

Summary by CodeRabbit

  • Refactor
    • Pad extrusion control changed from a simple toggle to a selectable side-type option, enabling more flexible and precise extrusion behavior.
    • HTTP server startup now uses centralized server settings (host, port, log level) instead of per-call arguments, simplifying configuration and improving deployment consistency.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

HTTP transport startup now configures FastMCP via the mcp instance settings (mcp.settings.host, mcp.settings.port, mcp.settings.log_level) and calls mcp.run(transport="streamable-http") without host/port args. Separately, pad_sketch replaces a boolean symmetric parameter with a string side_type, and sets pad.SideType in generated FreeCAD code.

Changes

HTTP Transport Configuration

Layer / File(s) Summary
Core Implementation
src/freecad_mcp/server.py
Set mcp.settings.host = "0.0.0.0", mcp.settings.port = config.http_port, mcp.settings.log_level = config.log_level; call mcp.run(transport="streamable-http") (removed direct host/port args).
Tests
tests/unit/test_server.py
Test updated to assert mcp.settings.host/port/log_level are set and that mcp.run() is called once with transport="streamable-http" (removed previous host/port-in-call assertions).

Pad Sketch Tool API

Layer / File(s) Summary
API / Data Shape
src/freecad_mcp/tools/partdesign.py
Function signature changed: symmetric: bool = Falseside_type: str = "One side".
Core Implementation
src/freecad_mcp/tools/partdesign.py
Generated FreeCAD code updated to set pad.SideType using side_type instead of setting pad.Symmetric.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

breaking-change

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures both main changes: HTTP transport fix for FastMCP and Pad Sketch's SideType update in PartDesign.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/freecad_mcp/tools/partdesign.py (2)

268-285: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add regression tests for the new side_type API surface.

Current coverage (see tests/unit/test_tools_partdesign.py:196-219) exercises only the default "One side" path. Please add tests for "Two side", "Symmetric", and an invalid side_type input.

As per coding guidelines, "All code must have tests - create unit tests, integration tests, edge cases, and regression tests".

Also applies to: 321-321

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/freecad_mcp/tools/partdesign.py` around lines 268 - 285, The test suite
currently only covers pad_sketch's default "One side" behavior; add unit tests
in tests/unit/test_tools_partdesign.py that call pad_sketch (the async function)
with side_type="Two side", side_type="Symmetric", and with an invalid side_type
value to exercise error handling; for the valid variations assert the returned
dict contains the expected extrusion parameters (e.g., correct length
distribution / flags that indicate two-sided or symmetric behavior and reversed
handling when reversed=True) and for the invalid input assert that the function
raises the appropriate exception or returns the expected error structure,
mirroring how existing tests assert on pad_sketch's result for "One side".

271-321: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate side_type before sending it to FreeCAD.

The docstring constrains valid values, but Line 321 forwards any string to pad.SideType. Invalid values fail later inside execute_python with a less actionable error path.

Suggested patch
 async def pad_sketch(
     sketch_name: str,
     length: float,
     side_type: str = "One side",
@@
 ) -> dict[str, Any]:
@@
-    bridge = await get_bridge()
+    allowedSideTypes = {"One side", "Two side", "Symmetric"}
+    if side_type not in allowedSideTypes:
+        raise ValueError(
+            "Invalid side_type. Use one of: One side, Two side, Symmetric."
+        )
+
+    bridge = await get_bridge()
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/freecad_mcp/server.py`:
- Around line 427-435: Add a regression test that exercises the HTTP startup
path where config.transport == TransportType.HTTP: instantiate or mock a config
with http_port and log_level, patch os.environ (or capture environment changes)
and mock mcp.run, then call the server startup function (the function that
contains this block which sets os.environ and calls mcp.run) and assert that
os.environ["FASTMCP_HOST"] == "0.0.0.0", os.environ["FASTMCP_PORT"] ==
str(config.http_port), os.environ["FASTMCP_LOG_LEVEL"] == config.log_level, and
that mcp.run was invoked with transport="streamable-http"; use deterministic
cleanup/reset of environment and restore mocks after the test.
- Around line 428-435: The current code sets FASTMCP_* environment variables
after the FastMCP instance (`mcp`) and its Pydantic `Settings` were already
instantiated, so those env vars have no effect; instead, mutate `mcp.settings`
directly (set `mcp.settings.host`, `mcp.settings.port`, and
`mcp.settings.log_level` from `config.http_port`/`config.log_level`) before
calling `mcp.run(transport="streamable-http")`; also update the test
`test_main_http_transport` to stop asserting a non-existent `port` argument on
`mcp.run()` and instead assert that `mcp.settings.port`, `mcp.settings.host`,
and `mcp.settings.log_level` are set correctly prior to `mcp.run()` being
invoked.

---

Outside diff comments:
In `@src/freecad_mcp/tools/partdesign.py`:
- Around line 268-285: The test suite currently only covers pad_sketch's default
"One side" behavior; add unit tests in tests/unit/test_tools_partdesign.py that
call pad_sketch (the async function) with side_type="Two side",
side_type="Symmetric", and with an invalid side_type value to exercise error
handling; for the valid variations assert the returned dict contains the
expected extrusion parameters (e.g., correct length distribution / flags that
indicate two-sided or symmetric behavior and reversed handling when
reversed=True) and for the invalid input assert that the function raises the
appropriate exception or returns the expected error structure, mirroring how
existing tests assert on pad_sketch's result for "One side".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7e55f022-310c-43a6-bd25-75866edee708

📥 Commits

Reviewing files that changed from the base of the PR and between d9a3711 and 28613b6.

📒 Files selected for processing (2)
  • src/freecad_mcp/server.py
  • src/freecad_mcp/tools/partdesign.py

Comment thread src/freecad_mcp/server.py
Comment thread src/freecad_mcp/server.py Outdated
- Use mcp.settings.host/port/log_level instead of os.environ
- Update test to verify settings are set correctly before run()
- Fixes ineffective workaround for mcp 1.27.0+ HTTP transport

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
tests/unit/test_server.py (1)

313-319: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

“Before run()” is not actually enforced by this test.

These assertions run after main() returns, so the test would still pass if
settings were applied after mcp.run(). Assert settings at call time via a
side_effect on mock_run.

Proposed fix
         with (
             patch.object(sys, "argv", DEFAULT_ARGV),
             patch.object(server_module, "get_config", return_value=mock_config),
             patch.object(server_module.mcp, "run") as mock_run,
             patch("builtins.print"),
         ):
+            def _assert_settings_at_run(
+                *_args: object, **_kwargs: object
+            ) -> None:
+                assert server_module.mcp.settings.host == "0.0.0.0"
+                assert server_module.mcp.settings.port == 8080
+                assert server_module.mcp.settings.log_level == "INFO"
+
+            mock_run.side_effect = _assert_settings_at_run
             server_module.main()
 
-            # Verify settings were set correctly BEFORE run() was called
-            assert server_module.mcp.settings.host == "0.0.0.0"
-            assert server_module.mcp.settings.port == 8080
-            assert server_module.mcp.settings.log_level == "INFO"
-
             # Verify run() was called with HTTP transport
             mock_run.assert_called_once_with(transport="streamable-http")

As per coding guidelines, "All code must have tests - create unit tests,
integration tests, edge cases, and regression tests".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_server.py` around lines 313 - 319, The test currently asserts
server_module.mcp.settings after main() returns, which doesn't guarantee they
were set before mcp.run() was called; modify the test to install a side_effect
on mock_run (the mocked mcp.run) that asserts server_module.mcp.settings.host ==
"0.0.0.0", port == 8080 and log_level == "INFO" at the moment run() is invoked,
then optionally return None; keep the existing post-call assertions or remove
them if redundant so the behavior is enforced at call time in main().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@tests/unit/test_server.py`:
- Around line 313-319: The test currently asserts server_module.mcp.settings
after main() returns, which doesn't guarantee they were set before mcp.run() was
called; modify the test to install a side_effect on mock_run (the mocked
mcp.run) that asserts server_module.mcp.settings.host == "0.0.0.0", port == 8080
and log_level == "INFO" at the moment run() is invoked, then optionally return
None; keep the existing post-call assertions or remove them if redundant so the
behavior is enforced at call time in main().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4ae29764-80ea-44a1-978b-01c2342cd4a5

📥 Commits

Reviewing files that changed from the base of the PR and between 28613b6 and f8101ed.

📒 Files selected for processing (2)
  • src/freecad_mcp/server.py
  • tests/unit/test_server.py

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.

1 participant