npm package: @iris.interactive/iris-dev-mcp
Description: A Model Context Protocol (MCP) server that lets AI agents interact with your local Docker PHP-FPM projects.
Latest version: 1.0.1

# iris-dev-mcp

A Model Context Protocol (MCP) server that lets AI agents interact with your local Docker PHP-FPM projects. It exposes tools to:
- discover running PHP-FPM containers
- open a persistent interactive shell session inside a container
- execute commands within that session and capture output/exit codes
- list and close sessions

This server communicates over stdio and is intended to be launched by an MCP-compatible client (e.g., Claude Desktop, custom MCP clients, etc.).

## Prerequisites
- Node.js 18+ (ESM)
- pnpm
- Docker Desktop/Engine running
- One or more running containers that look like PHP-FPM (by label, name, or image containing `php-fpm`)

## Installation
```bash
pnpm install
```

## Build
```bash
pnpm build
```
For development (watch build):
```bash
pnpm dev
```

## Run (as an MCP server)
After building, start the stdio server:
```bash
node dist/index.js
```
You should see logs on stderr similar to:
```
Docker version: 26.x.x
MCP Server running on stdio
```
The process will wait for an MCP client to connect over stdio.

### Example: Configure in an MCP client
Point your MCP client to run this command from the project directory. For example, a generic configuration might look like:
```json
{
  "iris-dev-mcp": {
    "command": "node",
    "args": ["dist/index.js"],
    "cwd": "/absolute/path/to/iris-dev-mcp"
  }
}
```
Consult your MCP client's documentation for the exact configuration format.

## Tools (API)
Below are the exposed MCP tools and their parameters/returns. All responses are returned as `text` content with a JSON payload.

- list_projects_container
  - Description: List running local projects PHP containers.
  - Params: none
  - Returns: Array of containers with fields: `id`, `names`, `image`, `state`, `status`, `labels`.
  - Example response (content[0].text):
    ```json
    [
      {
        "id": "a1b2c3...",
        "names": ["/myapp-php-fpm-1"],
        "image": "php:8.2-fpm",
        "state": "running",
        "status": "Up 2 hours",
        "labels": {"com.docker.compose.service": "php-fpm"}
      }
    ]
    ```

- create_terminal_session
  - Description: Create a persistent interactive shell session inside a project container.
  - Params:
    - containerId: string (you can pass a prefix; must match a running php-fpm-like container)
    - shell: string (optional, default: "/bin/bash")
    - workingDir: string (optional, default: "/var/www")
    - env: record<string, string> (optional)
  - Returns: `{ sessionId, containerId, shell, createdAt }`

- session_exec
  - Description: Execute a shell command inside an existing session and capture stdout/stderr and exit code.
  - Params:
    - sessionId: string
    - command: string
    - timeoutMs: positive integer (optional, default 30000)
  - Returns: `{ sessionId, command, exitCode, output }`

- list_sessions
  - Description: List all active terminal sessions.
  - Params: none
  - Returns: Array of `{ sessionId, containerId, shell, createdAt }`

- close_session
  - Description: Close an active terminal session.
  - Params:
    - sessionId: string
  - Returns: `{ ok: true, sessionId }` (or `{ ok: true, message: "Not found" }` if it didn't exist)

## How containers are detected
A container is considered a PHP-FPM project container if any of the following are true:
- Label `com.docker.compose.service` is `php-fpm`
- Label `service` is `php-fpm`
- Container name contains `php-fpm`
- Image name contains `php-fpm`

## Development
- Format: `pnpm format`
- Lint/Check: `pnpm check`
- Build (watch): `pnpm dev`

## Notes
- Only one command can run at a time per session; concurrent commands will be rejected.
- By default, commands timeout after 30s (configurable via `timeoutMs`).
- When providing `containerId`, you can use a short prefix; it must match a running, recognized container.
- The server logs to stderr; tool responses are returned via MCP protocol messages.

## License
No license specified.