Skip to content

fix: make image save path platform-independent#307

Open
raphy0316 wants to merge 1 commit intorobotmcp:developfrom
raphy0316:fix/image-path
Open

fix: make image save path platform-independent#307
raphy0316 wants to merge 1 commit intorobotmcp:developfrom
raphy0316:fix/image-path

Conversation

@raphy0316
Copy link
Copy Markdown

@raphy0316 raphy0316 commented Mar 30, 2026

Summary

Fix image saving failure in uvx execution caused by CWD-dependent relative path (./camera).

Problem

Running:

uvx ros-mcp --transport=stdio

results in:

Permission denied: './camera'

But local execution works:

cd ~/ros-mcp-server && uv run server.py --transport=stdio

Root Cause

Image saving relied on a relative path:

./camera/received_image.jpeg

This depends on the current working directory (CWD), which differs between:

  • local execution
  • packaged (uvx) execution
  • MCP client runtime

As a result, the same relative path may resolve to different filesystem locations depending on how the server is launched. In packaged or client-managed execution, it can point to a directory that does not exist or is not writable, which leads to errors such as:

Permission denied: './camera'

Solution

  • Replace relative path with platform-independent path
  • Add centralized path utility (get_fixed_image_path)

Support:

  • ROS_MCP_CAMERA_DIR override
  • OS cache directory (platformdirs)
  • temp fallback

Changes

  • Remove ./camera usage
  • Add ros_mcp/utils/paths.py
  • Update image handlers to use get_fixed_image_path()

Result

  • Fixes permission error in uvx
  • Ensures image paths always resolve to a writable location
  • Consistent behavior across all execution modes

Testing

Tested using a locally built package via uv to simulate packaged execution.

"ros-mcp-prod-check": {
  "command": "wsl",
  "args": [
    "-d", "Ubuntu",
    "bash", "-lc",
    "uvx --from /home/hyuntaek/ros-mcp-server/dist/ros_mcp-3.0.1.tar.gz ros-mcp --transport=stdio"
  ]
}

Verified:

  • error reproduced before fix
  • resolved after fix
  • image decode/save/analysis all working

Related

Closes #301

Copy link
Copy Markdown

@Tyrrnien81 Tyrrnien81 left a comment

Choose a reason for hiding this comment

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

I checked the diff, and replacing ./camera with a fixed path utility makes sense for solving the uvx permission error. The priority order in get_camera_dir() looks reasonable.

One thing I noticed: topics.py (lines 388 and 539) still reads from ./camera/received_image.jpeg, but websocket.py now saves to a different path through get_fixed_image_path(). This means subscribe_once and subscribe_for_duration won't find the saved image after this change. The fix should be straightforward since it just needs the same import and path update in topics.py.

Also, platformdirs isn't in pyproject.toml, so the tempdir fallback will always be used on a normal install. Could be worth adding it as a dependency later.

The core fix is solid, so approving. The topics.py part can be a follow-up.

@stex2005
Copy link
Copy Markdown
Collaborator

stex2005 commented Apr 6, 2026

Please update the base branch e check format and linting errors.

@raphy0316
Copy link
Copy Markdown
Author

@stex2005 Thank you for letting me know. I've updated the PR and cleaned up the commits as well.

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.

4 participants