takanarishimbo-ros2-exec-mcp


Nametakanarishimbo-ros2-exec-mcp JSON
Version 0.2.2 PyPI version JSON
download
home_pageNone
SummaryAn MCP server that executes ROS 2 (ros2) CLI commands
upload_time2025-08-21 08:57:54
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords cli executor mcp ros2 server
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [English](README.md) | [日本語](README_ja.md) | **README**

# ROS2 Exec MCP Server

A Model Context Protocol (MCP) server that executes ROS 2 (`ros2`) CLI commands.

## Features

- Execute ROS 2 CLI commands (e.g., `ros2 topic list`, `ros2 node list`)
- Configurable default timeout via environment variable
- Optional working directory control
- Secure by default: only allows commands starting with `ros2` (overridable)

## Usage

Below are examples for both stdio and streamable-http.

### Stdio (default)

MCP client example:

```json
{
  "mcpServers": {
    "ros2": {
      "command": "uvx",
      "args": ["takanarishimbo-ros2-exec-mcp"]
    }
  }
}
```

You can also configure timeout, default working directory, or allow non-ros2 commands:

```json
{
  "mcpServers": {
    "ros2": {
      "command": "uvx",
      "args": ["takanarishimbo-ros2-exec-mcp"],
      "env": {
        "ROS2_EXEC_TIMEOUT": "60",
        "DEFAULT_CWD": "/your/ros2/ws",
        "ALLOW_NON_ROS2": "true",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}
```

### streamable-http

Start the MCP server on the robot side first:

```bash
# Optional: set host/port if needed
MCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 MCP_PORT=8000 \
  uvx takanarishimbo-ros2-exec-mcp
```

MCP client example:

```json
{
  "mcpServers": {
    "ros2": {
      "url": "http://xxx.xxx.xxx.xxx:8000/mcp",
      "env": {
        "MCP_TRANSPORT": "streamable-http"
      }
    }
  }
}
```

## Environment Variables

- `ROS2_EXEC_TIMEOUT`: Default timeout seconds for command execution (default: `30`)
- `DEFAULT_CWD`: Default working directory for command execution (optional)
- `ALLOW_NON_ROS2`: If set to `true`, allows executing non-`ros2` commands (default: `false`)
- `MCP_TRANSPORT`: Transport mode. `stdio` (default) or `streamable-http`
- `MCP_HOST`: HTTP host/interface for `streamable-http` (default: `0.0.0.0`)
- `MCP_PORT`: HTTP port for `streamable-http` (default: `8080`)

## Available Tools

### `ros2_exec`

Execute a ROS 2 CLI command.

Parameters:

- `command` (required): Full command string, e.g., `"ros2 topic list"`
- `timeout` (optional): Timeout seconds (overrides `ROS2_EXEC_TIMEOUT`)
- `cwd` (optional): Working directory (overrides `DEFAULT_CWD`)

Returns combined stdout/stderr and exit code.

## Development

1.  Clone and install dependencies with `uv`:

    ```bash
    uv sync
    ```

2.  Run the server:

    ```bash
    uv run takanarishimbo-ros2-exec-mcp
    ```

3.  Test with MCP Inspector (optional):

    ```bash
    npx @modelcontextprotocol/inspector uv run takanarishimbo-ros2-exec-mcp
    ```

## Publishing to PyPI

This project uses PyPI's Trusted Publishers feature for secure, token-less publishing via GitHub Actions.

### 1. Configure PyPI Trusted Publisher

1. **Log in to PyPI** (create account if needed)

   - Go to https://pypi.org/

2. **Navigate to Publishing Settings**

   - Go to your account settings
   - Click on "Publishing" or go to https://pypi.org/manage/account/publishing/

3. **Add GitHub Publisher**
   - Click "Add a new publisher"
   - Select "GitHub" as the publisher
   - Fill in:
     - **Owner**: `TakanariShimbo` (your GitHub username/org)
     - **Repository**: `ros2-exec-mcp`
     - **Workflow name**: `pypi-publish.yml`
     - **Environment**: `pypi` (optional but recommended)
   - Click "Add"

### 2. Configure GitHub Environment (Recommended)

1. **Navigate to Repository Settings**

   - Go to your GitHub repository
   - Click "Settings" → "Environments"

2. **Create PyPI Environment**
   - Click "New environment"
   - Name: `pypi`
   - Configure protection rules (optional):
     - Add required reviewers
     - Restrict to specific branches/tags

### 3. Setup GitHub Personal Access Token (for release script)

The release script needs to push to GitHub, so you'll need a GitHub token:

1. **Create GitHub Personal Access Token**

   - Go to https://github.com/settings/tokens
   - Click "Generate new token" → "Generate new token (classic)"
   - Set expiration (recommended: 90 days or custom)
   - Select scopes:
     - ✅ `repo` (Full control of private repositories)
   - Click "Generate token"
   - Copy the generated token (starts with `ghp_`)

2. **Configure Git with Token**

   ```bash
   # Option 1: Use GitHub CLI (recommended)
   gh auth login

   # Option 2: Configure git to use token
   git config --global credential.helper store
   # Then when prompted for password, use your token instead
   ```

### 4. Release New Version

Use the release script to automatically version, tag, and trigger publishing:

```bash
# First time setup
chmod +x scripts/release.sh

# Increment patch version (0.1.0 → 0.1.1)
./scripts/release.sh patch

# Increment minor version (0.1.0 → 0.2.0)
./scripts/release.sh minor

# Increment major version (0.1.0 → 1.0.0)
./scripts/release.sh major

# Set specific version
./scripts/release.sh 1.2.3
```

### 5. Verify Publication

1. **Check GitHub Actions**

   - Go to "Actions" tab in your repository
   - Verify the "Publish to PyPI" workflow completed successfully

2. **Verify PyPI Package**
   - Visit: https://pypi.org/project/takanarishimbo-ros2-exec-mcp/
   - Or run: `pip show takanarishimbo-ros2-exec-mcp`

### Release Process Flow

1. `release.sh` script updates version in all files
2. Creates git commit and tag
3. Pushes to GitHub
4. GitHub Actions workflow triggers on new tag
5. Workflow uses OIDC to authenticate with PyPI (no tokens needed!)
6. Workflow builds project and publishes to PyPI
7. Package becomes available globally via `pip install` or `uvx`

## Code Quality

Uses `ruff` for linting and formatting:

```bash
uv run ruff check
uv run ruff check --fix
uv run ruff format
```

## Project Structure

```
ros2-exec-mcp/
├── src/
│   ├── __init__.py
│   ├── __main__.py
│   └── server.py
├── pyproject.toml
├── uv.lock
├── .github/
│   └── workflows/
│       └── pypi-publish.yml
├── scripts/
│   └── release.sh
├── docs/
│   ├── README.md
│   └── README_ja.md
└── .gitignore
```

## License

MIT

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "takanarishimbo-ros2-exec-mcp",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "cli, executor, mcp, ros2, server",
    "author": null,
    "author_email": "Takanari Shimbo <takanari.shimbo@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/62/bf/0d1bae7be5818a2a49fe4396a23512bd5cc33282baaa047da450698043cb/takanarishimbo_ros2_exec_mcp-0.2.2.tar.gz",
    "platform": null,
    "description": "[English](README.md) | [\u65e5\u672c\u8a9e](README_ja.md) | **README**\n\n# ROS2 Exec MCP Server\n\nA Model Context Protocol (MCP) server that executes ROS 2 (`ros2`) CLI commands.\n\n## Features\n\n- Execute ROS 2 CLI commands (e.g., `ros2 topic list`, `ros2 node list`)\n- Configurable default timeout via environment variable\n- Optional working directory control\n- Secure by default: only allows commands starting with `ros2` (overridable)\n\n## Usage\n\nBelow are examples for both stdio and streamable-http.\n\n### Stdio (default)\n\nMCP client example:\n\n```json\n{\n  \"mcpServers\": {\n    \"ros2\": {\n      \"command\": \"uvx\",\n      \"args\": [\"takanarishimbo-ros2-exec-mcp\"]\n    }\n  }\n}\n```\n\nYou can also configure timeout, default working directory, or allow non-ros2 commands:\n\n```json\n{\n  \"mcpServers\": {\n    \"ros2\": {\n      \"command\": \"uvx\",\n      \"args\": [\"takanarishimbo-ros2-exec-mcp\"],\n      \"env\": {\n        \"ROS2_EXEC_TIMEOUT\": \"60\",\n        \"DEFAULT_CWD\": \"/your/ros2/ws\",\n        \"ALLOW_NON_ROS2\": \"true\",\n        \"MCP_TRANSPORT\": \"stdio\"\n      }\n    }\n  }\n}\n```\n\n### streamable-http\n\nStart the MCP server on the robot side first:\n\n```bash\n# Optional: set host/port if needed\nMCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 MCP_PORT=8000 \\\n  uvx takanarishimbo-ros2-exec-mcp\n```\n\nMCP client example:\n\n```json\n{\n  \"mcpServers\": {\n    \"ros2\": {\n      \"url\": \"http://xxx.xxx.xxx.xxx:8000/mcp\",\n      \"env\": {\n        \"MCP_TRANSPORT\": \"streamable-http\"\n      }\n    }\n  }\n}\n```\n\n## Environment Variables\n\n- `ROS2_EXEC_TIMEOUT`: Default timeout seconds for command execution (default: `30`)\n- `DEFAULT_CWD`: Default working directory for command execution (optional)\n- `ALLOW_NON_ROS2`: If set to `true`, allows executing non-`ros2` commands (default: `false`)\n- `MCP_TRANSPORT`: Transport mode. `stdio` (default) or `streamable-http`\n- `MCP_HOST`: HTTP host/interface for `streamable-http` (default: `0.0.0.0`)\n- `MCP_PORT`: HTTP port for `streamable-http` (default: `8080`)\n\n## Available Tools\n\n### `ros2_exec`\n\nExecute a ROS 2 CLI command.\n\nParameters:\n\n- `command` (required): Full command string, e.g., `\"ros2 topic list\"`\n- `timeout` (optional): Timeout seconds (overrides `ROS2_EXEC_TIMEOUT`)\n- `cwd` (optional): Working directory (overrides `DEFAULT_CWD`)\n\nReturns combined stdout/stderr and exit code.\n\n## Development\n\n1.  Clone and install dependencies with `uv`:\n\n    ```bash\n    uv sync\n    ```\n\n2.  Run the server:\n\n    ```bash\n    uv run takanarishimbo-ros2-exec-mcp\n    ```\n\n3.  Test with MCP Inspector (optional):\n\n    ```bash\n    npx @modelcontextprotocol/inspector uv run takanarishimbo-ros2-exec-mcp\n    ```\n\n## Publishing to PyPI\n\nThis project uses PyPI's Trusted Publishers feature for secure, token-less publishing via GitHub Actions.\n\n### 1. Configure PyPI Trusted Publisher\n\n1. **Log in to PyPI** (create account if needed)\n\n   - Go to https://pypi.org/\n\n2. **Navigate to Publishing Settings**\n\n   - Go to your account settings\n   - Click on \"Publishing\" or go to https://pypi.org/manage/account/publishing/\n\n3. **Add GitHub Publisher**\n   - Click \"Add a new publisher\"\n   - Select \"GitHub\" as the publisher\n   - Fill in:\n     - **Owner**: `TakanariShimbo` (your GitHub username/org)\n     - **Repository**: `ros2-exec-mcp`\n     - **Workflow name**: `pypi-publish.yml`\n     - **Environment**: `pypi` (optional but recommended)\n   - Click \"Add\"\n\n### 2. Configure GitHub Environment (Recommended)\n\n1. **Navigate to Repository Settings**\n\n   - Go to your GitHub repository\n   - Click \"Settings\" \u2192 \"Environments\"\n\n2. **Create PyPI Environment**\n   - Click \"New environment\"\n   - Name: `pypi`\n   - Configure protection rules (optional):\n     - Add required reviewers\n     - Restrict to specific branches/tags\n\n### 3. Setup GitHub Personal Access Token (for release script)\n\nThe release script needs to push to GitHub, so you'll need a GitHub token:\n\n1. **Create GitHub Personal Access Token**\n\n   - Go to https://github.com/settings/tokens\n   - Click \"Generate new token\" \u2192 \"Generate new token (classic)\"\n   - Set expiration (recommended: 90 days or custom)\n   - Select scopes:\n     - \u2705 `repo` (Full control of private repositories)\n   - Click \"Generate token\"\n   - Copy the generated token (starts with `ghp_`)\n\n2. **Configure Git with Token**\n\n   ```bash\n   # Option 1: Use GitHub CLI (recommended)\n   gh auth login\n\n   # Option 2: Configure git to use token\n   git config --global credential.helper store\n   # Then when prompted for password, use your token instead\n   ```\n\n### 4. Release New Version\n\nUse the release script to automatically version, tag, and trigger publishing:\n\n```bash\n# First time setup\nchmod +x scripts/release.sh\n\n# Increment patch version (0.1.0 \u2192 0.1.1)\n./scripts/release.sh patch\n\n# Increment minor version (0.1.0 \u2192 0.2.0)\n./scripts/release.sh minor\n\n# Increment major version (0.1.0 \u2192 1.0.0)\n./scripts/release.sh major\n\n# Set specific version\n./scripts/release.sh 1.2.3\n```\n\n### 5. Verify Publication\n\n1. **Check GitHub Actions**\n\n   - Go to \"Actions\" tab in your repository\n   - Verify the \"Publish to PyPI\" workflow completed successfully\n\n2. **Verify PyPI Package**\n   - Visit: https://pypi.org/project/takanarishimbo-ros2-exec-mcp/\n   - Or run: `pip show takanarishimbo-ros2-exec-mcp`\n\n### Release Process Flow\n\n1. `release.sh` script updates version in all files\n2. Creates git commit and tag\n3. Pushes to GitHub\n4. GitHub Actions workflow triggers on new tag\n5. Workflow uses OIDC to authenticate with PyPI (no tokens needed!)\n6. Workflow builds project and publishes to PyPI\n7. Package becomes available globally via `pip install` or `uvx`\n\n## Code Quality\n\nUses `ruff` for linting and formatting:\n\n```bash\nuv run ruff check\nuv run ruff check --fix\nuv run ruff format\n```\n\n## Project Structure\n\n```\nros2-exec-mcp/\n\u251c\u2500\u2500 src/\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 __main__.py\n\u2502   \u2514\u2500\u2500 server.py\n\u251c\u2500\u2500 pyproject.toml\n\u251c\u2500\u2500 uv.lock\n\u251c\u2500\u2500 .github/\n\u2502   \u2514\u2500\u2500 workflows/\n\u2502       \u2514\u2500\u2500 pypi-publish.yml\n\u251c\u2500\u2500 scripts/\n\u2502   \u2514\u2500\u2500 release.sh\n\u251c\u2500\u2500 docs/\n\u2502   \u251c\u2500\u2500 README.md\n\u2502   \u2514\u2500\u2500 README_ja.md\n\u2514\u2500\u2500 .gitignore\n```\n\n## License\n\nMIT\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "An MCP server that executes ROS 2 (ros2) CLI commands",
    "version": "0.2.2",
    "project_urls": {
        "Homepage": "https://github.com/TakanariShimbo/ros2-exec-mcp",
        "Issues": "https://github.com/TakanariShimbo/ros2-exec-mcp/issues",
        "Repository": "https://github.com/TakanariShimbo/ros2-exec-mcp.git"
    },
    "split_keywords": [
        "cli",
        " executor",
        " mcp",
        " ros2",
        " server"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "23f73b18f116c321d4472d2545f57307ee711decbb256ff8ef810892516955b8",
                "md5": "d06945ad1921b164f270eccc45f11f71",
                "sha256": "5f4c7509b905c6971387b1c3f58d5fe99d42da679e85c60d4c9fe3f039074793"
            },
            "downloads": -1,
            "filename": "takanarishimbo_ros2_exec_mcp-0.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d06945ad1921b164f270eccc45f11f71",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 7258,
            "upload_time": "2025-08-21T08:57:54",
            "upload_time_iso_8601": "2025-08-21T08:57:54.061811Z",
            "url": "https://files.pythonhosted.org/packages/23/f7/3b18f116c321d4472d2545f57307ee711decbb256ff8ef810892516955b8/takanarishimbo_ros2_exec_mcp-0.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "62bf0d1bae7be5818a2a49fe4396a23512bd5cc33282baaa047da450698043cb",
                "md5": "390c567192618c7235c5ce6dfe31fffc",
                "sha256": "2597cc26f1d05a642cae07f4762db7ee6f5861049ffc5ad6fd843a079b93f223"
            },
            "downloads": -1,
            "filename": "takanarishimbo_ros2_exec_mcp-0.2.2.tar.gz",
            "has_sig": false,
            "md5_digest": "390c567192618c7235c5ce6dfe31fffc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 7431,
            "upload_time": "2025-08-21T08:57:54",
            "upload_time_iso_8601": "2025-08-21T08:57:54.830454Z",
            "url": "https://files.pythonhosted.org/packages/62/bf/0d1bae7be5818a2a49fe4396a23512bd5cc33282baaa047da450698043cb/takanarishimbo_ros2_exec_mcp-0.2.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-21 08:57:54",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "TakanariShimbo",
    "github_project": "ros2-exec-mcp",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "takanarishimbo-ros2-exec-mcp"
}
        
Elapsed time: 0.67857s