rosettahub-mcp-server 0.2.0
MCP server for managing RosettaHUB user AWS cloud accounts via SOAP API
Requires Python: >=3.10
Keywords: aws, classroom, cloud, education, mcp, model-context-protocol, rosettahub

<p align="center">
  <h1 align="center">rosettahub-mcp-server</h1>
  <p align="center">
    An MCP server for managing RosettaHUB user AWS cloud accounts
  </p>
</p>

<p align="center">
  <a href="https://github.com/danielcregg/rosettahub-mcp-server/actions/workflows/ci.yml"><img src="https://github.com/danielcregg/rosettahub-mcp-server/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <a href="https://pypi.org/project/rosettahub-mcp-server/"><img src="https://img.shields.io/pypi/v/rosettahub-mcp-server?color=blue" alt="PyPI"></a>
  <a href="https://pypi.org/project/rosettahub-mcp-server/"><img src="https://img.shields.io/pypi/pyversions/rosettahub-mcp-server" alt="Python"></a>
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
  <a href="https://codecov.io/gh/danielcregg/rosettahub-mcp-server"><img src="https://codecov.io/gh/danielcregg/rosettahub-mcp-server/branch/main/graph/badge.svg" alt="Coverage"></a>
</p>

---

[RosettaHUB](https://www.rosettahub.com/) is a platform used by educators to provision and manage user AWS cloud environments. This [MCP](https://modelcontextprotocol.io/) server wraps the RosettaHUB SOAP API into **16 tools** and **2 resources**, letting AI assistants like [Claude](https://claude.ai) manage user accounts through natural language.

> **Example:** *"Show me which users have used over 80% of their budget"* or *"Run `aws ec2 describe-instances` across all user accounts"*

## Quick Start

### Install

```bash
pip install rosettahub-mcp-server
```

### Configure

```bash
export RH_API_KEY="your-rosettahub-api-key"
export RH_ORG="Your-Org-Name"
```

### Add to Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "rosettahub": {
      "command": "uvx",
      "args": ["rosettahub-mcp-server"],
      "env": {
        "RH_API_KEY": "your-api-key",
        "RH_ORG": "Your-Org-Name"
      }
    }
  }
}
```

### Add to Claude Code

```bash
claude mcp add rosettahub -e RH_API_KEY=your-key -e RH_ORG=Your-Org -- rosettahub-mcp-server
```

## Tools

### Account & API Info

| Tool | Description |
|---|---|
| `test_connection` | Test the API connection and return authenticated user info |
| `list_accounts` | List your own RosettaHUB cloud accounts |
| `list_user_accounts` | List all user accounts with budget details |
| `list_users` | List all federated users in the organization |
| `list_api_methods` | List all available RosettaHUB SOAP API methods |

### AWS Execution

| Tool | Description |
|---|---|
| `aws_exec` | Run an AWS CLI command across **all** user accounts |
| `aws_exec_user` | Run an AWS CLI command on **one** user's account |
| `ec2_list` | List EC2 instances across all user accounts |
| `get_sts_credentials` | Get temporary AWS STS credentials for a user |
| `get_console_url` | Get a sign-in URL for a user's AWS Console |

### Budget Management

| Tool | Description |
|---|---|
| `budget_status` | Show budget, spending, and remaining balance for all users |
| `budget_transfer` | Transfer budget to all user accounts |
| `budget_transfer_user` | Transfer budget to one user's account |

### Access Control

| Tool | Description |
|---|---|
| `quarantine_user` | Quarantine a user (restrict cloud access) |
| `unquarantine_user` | Unquarantine a user (restore cloud access) |
| `set_allowed_regions` | Set which AWS regions a user can use |

## Resources

| URI | Description |
|---|---|
| `rosettahub://users` | JSON list of current user logins |
| `rosettahub://budget-summary` | JSON budget data for all users |

## Configuration

| Environment Variable | Required | Default | Description |
|---|---|---|---|
| `RH_API_KEY` | Yes | — | Your RosettaHUB API key |
| `RH_ORG` | Yes | — | Your RosettaHUB organization name |
| `RH_AWS_REGION` | No | `eu-west-1` | Default AWS region for commands |
| `RH_WSDL_URL` | No | RosettaHUB public API | Override WSDL endpoint URL |

## Security

- **Command validation** — All AWS commands must start with `aws ` to prevent arbitrary execution
- **Region validation** — Region parameters are validated against AWS format to prevent flag injection
- **No shell injection** — Commands run with `shell=False` using `shlex.split()`
- **Subprocess timeout** — AWS CLI calls are capped at 60 seconds to prevent hung processes
- **Minimal subprocess environment** — Only AWS credentials and PATH are passed to child processes
- **Temporary credentials** — AWS access uses short-lived STS sessions (1 hour default), never long-term keys
- **Logging to stderr** — stdout is reserved for MCP JSON-RPC transport

## Architecture

```
src/rosettahub_mcp_server/
├── server.py        # FastMCP instance and entry point
├── config.py        # Environment variable loading
├── client.py        # Singleton SOAP client (zeep)
├── types.py         # TypedDict return types
├── tools/
│   ├── account_tools.py    # 5 account/API info tools
│   ├── aws_tools.py        # 5 AWS execution tools
│   ├── budget_tools.py     # 3 budget tools
│   └── user_mgmt_tools.py  # 3 access control tools
└── resources/
    └── user_resources.py # 2 MCP resources
```

## Development

```bash
git clone https://github.com/danielcregg/rosettahub-mcp-server.git
cd rosettahub-mcp-server
pip install -e ".[dev]"
```

### Run tests

```bash
pytest -v
```

All tests use mocked SOAP responses — no API key needed.

### Lint & type check

```bash
ruff check src/ tests/
mypy src/ --ignore-missing-imports
```

### Run locally

```bash
export RH_API_KEY="your-key"
export RH_ORG="Your-Org"
rosettahub-mcp-server
```

## Disclaimer

This is an unofficial, community-maintained integration. It is not affiliated with, endorsed by, or sponsored by [RosettaHUB](https://www.rosettahub.com/). "RosettaHUB" is a trademark of its respective owner.

## License

MIT — see [LICENSE](LICENSE) for details.

<!-- mcp-name: io.github.danielcregg/rosettahub-mcp-server -->