Skip to content

Conversation

@bburda
Copy link
Contributor

@bburda bburda commented Jan 29, 2026

This PR introduces an MCP (Model Context Protocol) adapter around the ros2_medkit SOVD HTTP API, including an async HTTP client, MCP tool server, stdio/HTTP entrypoints, configuration, packaging, tests, and CI/Docker integration.

- Add async HTTP client (SovdClient) with full ros2_medkit API coverage:
  - Discovery: areas, components, apps, functions
  - Operations: execution-based model (create/list/get/cancel executions)
  - Data: ROS 2 topic read/write support
  - Configurations: ROS 2 parameter management
  - Faults: system-wide and entity-specific fault handling
  - Relationships: subareas, subcomponents, dependencies, hosts

- Implement MCP server with 40+ tools for ros2_medkit entity interaction
- Add stdio transport (ros2-medkit-mcp-stdio) for Claude Desktop
- Add HTTP transport (ros2-medkit-mcp-http) for web-based clients
- Support for all SOVD entity types: areas, components, apps, functions

- Add comprehensive test suite (25 tests, all passing)
- Use Poetry for dependency management
- Type-safe Pydantic models for all tool arguments
- Response parsing handles both direct arrays and wrapped {items: [...]} format

Key architectural decisions:
- No backward compatibility layers - only new SOVD execution model
- List operations gracefully handle missing /apps and /functions endpoints
- Execution model: POST /executions creates, GET lists/gets, DELETE cancels
- Entity-agnostic API (entity_type parameter for components/apps/areas/functions)
- Add docker-publish.yml workflow for GitHub Container Registry
  - Build and push on main branch and version tags
  - Tags: latest (main), semver (v1.2.3), sha-short
  - Build-only validation on pull requests
  - Multi-platform: linux/amd64, linux/arm64

- Update Dockerfile to default to HTTP server mode
- Document VS Code MCP configuration with Docker in README
- Update examples with SSE transport type for VS Code
- Add .pre-commit-config.yaml with ruff (lint + format) and mypy
- Add dev dependencies: pre-commit, ruff, mypy
- Configure ruff in pyproject.toml (target-version, lint rules, isort)
- Configure mypy with strict settings and Pydantic plugin
- Fix type annotations in server_http.py (add return types)
- Update CI to run ruff lint, ruff format --check, and mypy
Copilot AI review requested due to automatic review settings January 29, 2026 17:30
@bburda bburda self-assigned this Jan 29, 2026
Copy link

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 introduces an MCP (Model Context Protocol) adapter around the ros2_medkit SOVD HTTP API, including an async HTTP client, MCP tool server, stdio/HTTP entrypoints, configuration, packaging, tests, and CI/Docker integration.

Changes:

  • Add an async SovdClient with high-level methods for SOVD entities, faults, operations, data, and configurations, plus Pydantic models for tool args/results and a dispatcher-based MCP server (mcp_app).
  • Provide stdio and HTTP (SSE) server entrypoints, example MCP configs, Dockerfile/docker‑compose, and Poetry-based project configuration with CI workflows and pre-commit hooks.
  • Introduce tests for the client, configuration, and filtering logic plus pytest configuration that avoids ROS 2 plugin conflicts.

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/ros2_medkit_mcp/config.py Defines frozen Settings model and environment-driven defaults for base URL, auth, and timeouts used by the client and servers.
src/ros2_medkit_mcp/client.py Implements the async SovdClient wrapper around the SOVD HTTP API, including error handling and typed endpoint helpers.
src/ros2_medkit_mcp/models.py Adds Pydantic argument models for MCP tools, a ToolResult wrapper, and helper filter_entities used by tools and tests.
src/ros2_medkit_mcp/mcp_app.py Builds the MCP Server, registers all tools/resources, and dispatches tool calls to SovdClient.
src/ros2_medkit_mcp/server_stdio.py Adds the stdio transport entrypoint wiring SovdClient and mcp_app to mcp.server.stdio.
src/ros2_medkit_mcp/server_http.py Adds the HTTP/SSE transport entrypoint using Starlette and uvicorn, with health endpoint and MCP message routes.
src/ros2_medkit_mcp/__init__.py Declares the package and its version.
tests/test_tools.py Provides tests for SovdClient behaviour, filter_entities, and Settings, using mocked HTTP responses.
tests/conftest.py Configures pytest to avoid ROS 2 launch testing plugin conflicts by adjusting sys.path and ignoring certain files.
tests/__init__.py Marks the tests package and documents its purpose.
run_tests.py Adds a helper script to run pytest in isolation from a ROS 2 installation.
pyproject.toml Sets up Poetry project metadata, runtime/dev dependencies, test and lint config, and entrypoint scripts.
examples/mcp-stdio.json Example MCP stdio configuration for running the server via Poetry.
examples/mcp-http.json Example MCP HTTP (SSE) configuration for connecting to a running HTTP server.
examples/README.md Documents example MCP configurations and environment variables.
docker-compose.yml Defines a docker-compose service for running the HTTP MCP server against a ros2_medkit gateway.
Dockerfile Containerizes the MCP adapter with Poetry-managed dependencies and an entrypoint supporting stdio/HTTP modes.
README.md Expands project documentation with overview, usage, tool descriptions, Docker integration, and development workflow.
.pre-commit-config.yaml Configures pre-commit hooks for formatting, linting, and type checking.
.gitignore Tweaks ignore rules, including keeping poetry.lock under version control.
.github/workflows/ci.yml Adds CI workflow for tests, linting, mypy, and Docker build.
.github/workflows/docker-publish.yml Adds workflow for building and publishing multi-arch Docker images to GHCR.

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

- Add PULL_REQUEST_TEMPLATE.md with checklist for ruff, mypy, tests
- Add ISSUE_TEMPLATE/bug.md for bug reports
- Add ISSUE_TEMPLATE/issue.md for feature requests
- Add copilot-instructions.md with project architecture and conventions
@bburda bburda changed the title Feat/initial server ros2_medkit MCP inital version Jan 29, 2026
@bburda bburda requested a review from mfaferek93 January 29, 2026 17:39
BREAKING CHANGE: parameter names changed for entity-agnostic support

- New tools: sovd_health, sovd_area_get, sovd_component_get, sovd_update_execution
- Renamed: sovd_component_data to sovd_entity_data
- Renamed: sovd_component_topic_data to sovd_entity_topic_data
- All faults/data/operations/configuration tools now accept entity_type
- Parameter component_id renamed to entity_id for consistency
Copy link

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

Copilot reviewed 21 out of 23 changed files in this pull request and generated 4 comments.


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

- Move _default_timeout outside Settings class to fix Pydantic default_factory
- Remove dead HTTPStatusError handler from client.py
- Add explanatory comment to empty except in conftest.py
- Fix README documentation:
  - Correct base_url default (no /api/v1)
  - Update sovd_entities_list to mention apps and functions
  - Fix operation tool names (create/get/cancel_execution)
- Use DependenciesArgs instead of SubcomponentsArgs in dispatcher
- Add tests for call_tool dispatcher (aliases, formatting, integration)

Note: server_http.py ASGI pattern is correct - MCP SSE transport
handles responses internally via the context manager.
Note: test_settings_immutable uses ValidationError (Pydantic v2 behavior).
Changed handle_sse and handle_messages from Request-based handlers to
proper ASGI apps with signature (scope, receive, send) -> None to match
Starlette expectations and avoid runtime errors.

This addresses the PR review finding about handlers not returning Response.
Copilot AI review requested due to automatic review settings January 30, 2026 16:28
- Fix DependenciesArgs field access (entity_id instead of component_id)
- Fix base_url default to include /api/v1 suffix
- Update README tool names (sovd_entity_data, sovd_entity_topic_data)
- Update pyproject.toml authors field
- Update test assertion for new base_url default
@bburda bburda force-pushed the feat/initial-server branch from f3ac9e7 to 5b02843 Compare January 30, 2026 16:30
Copy link

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

Copilot reviewed 26 out of 28 changed files in this pull request and generated 5 comments.


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

Comment on lines +175 to +180
List faults for a specific component.

**Arguments:**
- `component_id` (required, string): The component identifier

**Returns:** Array of fault objects from `GET /components/{component_id}/faults`
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

The sovd_faults_list documentation here describes the argument as component_id, but the tool schema and argument model use entity_id (with an optional entity_type), which will confuse MCP clients and users. Please update this section to document entity_id (and entity_type if applicable) so it matches the actual tool interface.

Suggested change
List faults for a specific component.
**Arguments:**
- `component_id` (required, string): The component identifier
**Returns:** Array of fault objects from `GET /components/{component_id}/faults`
List faults for a specific entity.
**Arguments:**
- `entity_id` (required, string): The entity identifier
- `entity_type` (optional, string): The entity type (for example, `"components"`); defaults to the tool's standard entity type if omitted
**Returns:** Array of fault objects from `GET /{entity_type}/{entity_id}/faults`

Copilot uses AI. Check for mistakes.
@mfaferek93 mfaferek93 self-requested a review January 30, 2026 16:53
@bburda bburda merged commit 72f3d2d into main Jan 30, 2026
3 checks passed
@bburda bburda deleted the feat/initial-server branch January 30, 2026 17:11
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