Metadata-Version: 2.4
Name: psr-cloud-mcp
Version: 0.5.2
Summary: MCP server for PSR Cloud (local stdio)
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: mcp[cli]>=1.0
Requires-Dist: psr-cloud>=0.3.23

# PSR Cloud MCP Server

MCP server that exposes PSR Cloud HPC operations as AI tools, built on top of
[pycloud](https://pypi.org/project/psr-cloud/) (`psr-cloud` on PyPI).

## Prerequisites

1. **Python 3.10+**
2. **Credentials.** The server picks one of two paths automatically — you only
   need to set up the one that fits you:
   - *Personal Access Token (recommended).* Go to `sso.psr-inc.com/profile`,
     log in with your corporate PSR Google account, generate a token under
     *PSR Cloud — Personal Access Tokens*, and save it (shown only once). Then
     export `PSR_CLOUD_EMAIL` and `PSR_CLOUD_ACCESS_TOKEN` (see below).
   - *PSR Cloud Desktop fallback.* If you already have PSR Cloud Desktop
     installed and signed in, leave both env vars unset — the MCP server will
     reuse the credentials cached at
     `%APPDATA%\PSR\PSRCloud\EPSRConfig.xml`. This path only works on Windows.

## Installation

### From PyPI

```bash
pip install psr-cloud-mcp
```

### From the Git repository

```bash
pip install git+https://github.com/your-org/psr-cloud-mcp.git
```

### Local development clone

```bash
git clone https://github.com/your-org/psr-cloud-mcp.git
cd psr-cloud-mcp/local
pip install -e .
```

## Configuring Claude Code

Add to `~/.claude/settings.json` (or `settings.local.json` for local-only):

```json
{
  "mcpServers": {
    "psr-cloud": {
      "command": "psr-cloud-mcp",
      "env": {
        "PSR_CLOUD_EMAIL": "yourname@psr-inc.com",
        "PSR_CLOUD_ACCESS_TOKEN": "<your-token>"
      }
    }
  }
}
```

If you prefer not to store the token in the config file, omit the `env` block and
set the variables in your shell profile instead. Or, if you already have PSR
Cloud Desktop signed in, omit the `env` block entirely — the server will fall
back to the credentials saved by Desktop.

## Configuring Claude Desktop

Open the Claude Desktop config file:

- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

Add the `psr-cloud` entry under `mcpServers`:

```json
{
  "mcpServers": {
    "psr-cloud": {
      "command": "psr-cloud-mcp",
      "env": {
        "PSR_CLOUD_EMAIL": "yourname@psr-inc.com",
        "PSR_CLOUD_ACCESS_TOKEN": "<your-token>"
      }
    }
  }
}
```

If `psr-cloud-mcp` is not on the system PATH (common on Windows), use the full
path to the executable:

```json
{
  "mcpServers": {
    "psr-cloud": {
      "command": "C:\\Users\\<user>\\AppData\\Local\\Programs\\Python\\Python3xx\\Scripts\\psr-cloud-mcp.exe",
      "env": {
        "PSR_CLOUD_EMAIL": "yourname@psr-inc.com",
        "PSR_CLOUD_ACCESS_TOKEN": "<your-token>"
      }
    }
  }
}
```

To find the exact executable path on Windows, run:

```powershell
where.exe psr-cloud-mcp
```

After saving the file, restart Claude Desktop. The PSR Cloud tools will appear
in the tools panel (hammer icon).

## Available tools

| Tool | Description |
|---|---|
| `list_cases` | List cases from the last N days |
| `get_cases` | Get details for specific case IDs |
| `get_case_status` | Poll execution status of a case |
| `get_case_log` | Retrieve execution log text |
| `list_download_files` | List result files available for a case |
| `run_case` | Submit a new model run |
| `cancel_case` | Cancel a running or queued case |
| `download_case_files` | Schedule a background download to a local path; returns a `job_id` |
| `get_download_status` | Poll a background download by `job_id` |
| `list_downloads` | List all background downloads tracked by this server |
| `list_clusters` | List the PSR Cloud clusters available to your account |
| `get_programs` | List available programs (SDDP, OPTGEN, …) |
| `get_program_versions` | List versions for a program |
| `get_execution_types` | List execution types for a program + version |
| `get_memory_per_process_ratios` | List valid memory ratio strings |

## Choosing a cluster

Every cluster-scoped tool above accepts an optional `cluster` argument. Omit it
to use your account's default cluster — the right choice for most users. Pass a
name (run `list_clusters` to see them) to operate against a specific cluster;
unknown names are rejected with the list of valid options.

## Typical AI workflow

```
get_programs()
  → get_program_versions("SDDP")
  → get_execution_types("SDDP", "18.0")
  → run_case(name="my-run", data_path="/path/to/data", program="SDDP", ...)
  → get_case_status(case_id)         # poll until SUCCESS
  → list_case_files(case_id)
  → download_case_files(case_id, output_path="/path/to/results")  # returns job_id
  → get_download_status(job_id)      # poll until status is "done"
```
