Metadata-Version: 2.4
Name: infra-mcp
Version: 0.1.3
Summary: Local stdio MCP server for read-only diagnosis of on-prem Linux VMs and PostgreSQL databases
Project-URL: Homepage, https://github.com/esp4ce/infra-mcp
Project-URL: Repository, https://github.com/esp4ce/infra-mcp
Author: esp4ce
License: MIT
Requires-Python: >=3.11
Requires-Dist: keyring>=24.0
Requires-Dist: mcp[cli]<2.0,>=1.28
Requires-Dist: paramiko<4,>=3.0
Requires-Dist: psycopg2-binary>=2.9
Requires-Dist: pydantic>=2.11
Requires-Dist: pyyaml>=6.0
Requires-Dist: sshtunnel>=0.4
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

<div align="center">

# infra-mcp

[![PyPI](https://img.shields.io/pypi/v/infra-mcp)](https://pypi.org/project/infra-mcp/)
[![Glama](https://img.shields.io/badge/Glama-grey?logo=data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMjAgMzAwIj48cGF0aCBkPSJNNDAgMEgyMFYxNDBINDBWMFpNMjAwIDBIMTgwVjE0MEgyMDBWMFpNMjAgMTBIMTBWMTEwSDIwVjEwWk0yMTAgMTBIMjAwVjExMEgyMTBWMTBaTTEwIDIwSDBWODBIMTBWMjBaTTIyMCAyMEgyMTBWODBIMjIwVjIwWk01MCA2MEg0MFYxNDBINTBWNjBaTTE4MCA2MEgxNzBWMTQwSDE4MFY2MFpNMTUwIDcwSDcwVjE3MEgxNTBWNzBaTTcwIDgwSDUwVjE0MEg3MFY4MFpNMTcwIDgwSDE1MFYxNDBIMTcwVjgwWk0yMCAxMzBIMTBWMTQwSDIwVjEzMFpNMjEwIDEzMEgyMDBWMTQwSDIxMFYxMzBaTTcwIDE0MEg2MFYyMTBINzBWMTQwWk0xNjAgMTQwSDE1MFYyMTBIMTYwVjE0MFpNMzAgMTUwSDIwVjMwMEgzMFYxNTBaTTYwIDE1MEg1MFYzMDBINjBWMTUwWk0xNzAgMTUwSDE2MFYzMDBIMTcwVjE1MFpNMjAwIDE1MEgxOTBWMzAwSDIwMFYxNTBaTTUwIDE2MEgzMFYzMDBINTBWMTYwWk0xOTAgMTYwSDE3MFYzMDBIMTkwVjE2MFpNODAgMTcwSDcwVjIyMEg4MFYxNzBaTTEzMCAxNzBIOTBWMTgwSDEzMFYxNzBaTTE1MCAxNzBIMTQwVjIyMEgxNTBWMTcwWk0yMCAxODBIMTBWMjYwSDIwVjE4MFpNOTAgMTgwSDgwVjIyMEg5MFYxODBaTTE0MCAxODBIMTMwVjIyMEgxNDBWMTgwWk0yMTAgMTgwSDIwMFYyNjBIMjEwVjE4MFpNMTAwIDE5MEg5MFYyMjBIMTAwVjE5MFpNMTMwIDE5MEgxMjBWMjIwSDEzMFYxOTBaTTcwIDIyMEg2MFYzMDBINzBWMjIwWk0xNjAgMjIwSDE1MFYzMDBIMTYwVjIyMFpNOTAgMjMwSDcwVjMwMEg5MFYyMzBaTTE1MCAyMzBIMTMwVjMwMEgxNTBWMjMwWk0xMzAgMjUwSDkwVjMwMEgxMzBWMjUwWiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=&logoColor=white)](https://glama.ai/mcp/servers/esp4ce/infra-mcp)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

*Read-only MCP access to on-prem Linux VMs and PostgreSQL databases over SSH.*

```
 agent ──stdio──▶ infra-mcp ──SSH──▶  VMs  (journald · log files)
                                  └──▶  DBs  (read-only PostgreSQL)
```

</div>

---

An agent can check service health, retrieve bounded logs, inspect DB state, and explore table schemas — without terminal access. Every remote operation is allowlist-gated and written to an append-only audit log.

## Install

```bash
uv tool install infra-mcp
# or
pip install infra-mcp
```

## Configure

Copy `infra-mcp.yaml.example` to `~/.infra-mcp/infra-mcp.yaml` and edit it.

```bash
# Generate a starter config from ~/.ssh/config
infra-mcp generate-config -o ~/.infra-mcp/infra-mcp.yaml

# Create the read-only PostgreSQL role(s)
infra-mcp setup

# Check VM reachability
infra-mcp test

# Refresh discovered services, log dirs, and databases (updates config in place)
infra-mcp discover --in-place
```

Override the config path with `--config` or `INFRA_MCP_CONFIG`.

## Run

```bash
infra-mcp run
```

Register as a **stdio** MCP server in your client (Claude Code, Cursor, …) with command `infra-mcp run`.

## Updates

`infra-mcp` checks PyPI for a newer release once a day and, when one exists, prints a
one-line hint to stderr telling you how to upgrade:

```bash
uv tool upgrade infra-mcp   # or: pip install --upgrade infra-mcp
```

The check runs in the background, never blocks startup, and never touches stdout. Print
the installed version with `infra-mcp --version`. Disable the check entirely by setting
`INFRA_MCP_NO_UPDATE_CHECK=1`.

## Tools

### VM & services

| Tool | Purpose |
|------|---------|
| `list_vms` | All VMs with reachability and watched services |
| `get_infra_overview` | Service states + DB health for one VM in a single call |
| `get_service_status` | systemd state, uptime, last 5 log lines |
| `get_service_logs` | Bounded journald logs, filtered by severity |
| `get_log_file` | Last N lines of an allowed log file, optional grep |

### Databases

| Tool | Purpose |
|------|---------|
| `get_db_status` | Connection counts, waiting locks, long-running query count |
| `query_db` | Bounded caller-supplied `SELECT` |
| `list_tables` | Tables in a database (schema + name), capped at 200 |
| `describe_table` | Columns, types, primary key, foreign keys for one table |

### Meta

| Tool | Purpose |
|------|---------|
| `get_audit_log` | Recent entries from the local audit log |

All output is bounded server-side (200 log lines, 100 DB rows, 200 tables/columns max). Truncation is always flagged with a `-- TRUNCATED:` marker. `list_tables` and `describe_table` cache results in memory (TTL: `schema_cache_ttl_hours`, default 24 h); pass `refresh: true` to force a live re-read.

## Security model

- SSH commands and systemd services are checked against a per-VM allowlist before any network call.
- All DB queries run as a read-only role inside a `READ ONLY` transaction.
- Log file paths are resolved against a per-VM directory allowlist (`..` traversal blocked).
- Every remote operation is appended to a local JSONL audit log.
