Metadata-Version: 2.4
Name: aten-thoth-mcp-proxy
Version: 0.1.14
Summary: Thoth governance proxy for Claude Desktop / MCP servers
Author: Aten Engineering
Author-email: engineering@aten.security
Requires-Python: >=3.12,<3.15
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: anyio (>=4.0)
Requires-Dist: httpx (>=0.27)
Project-URL: Documentation, https://docs.aten.security/thoth/mcp-proxy
Project-URL: Homepage, https://aten.security/thoth
Description-Content-Type: text/markdown

# aten-thoth-mcp-proxy

Thoth governance sidecar for Claude Desktop and MCP servers. Intercepts every
`tools/call` and enforces HIPAA/SOC2 policy before the upstream MCP server executes.

## Install

```bash
pip install aten-thoth-mcp-proxy
thoth --version
```

On first run, `thoth` now bootstraps a local profile at `~/.thoth` (Linux/macOS/Windows),
creates these files if missing:

- `~/.thoth/intent_map.json`
- `~/.thoth/proxy_api_key.json` (permission tightened to `0600` where supported)

and sets runtime defaults when not already configured:

- `THOTH_API_KEY_FILE=~/.thoth/proxy_api_key.json`
- `THOTH_ENV=prod`
- `THOTH_ENFORCER_URL=https://enforce.<tenant>.<apex-domain>`
- `THOTH_GOVAPI_URL=https://grid.<tenant>.<apex-domain>`
- `THOTH_GOV_API_URL=https://grid.<tenant>.<apex-domain>` (legacy alias)

`<apex-domain>` defaults to `aten.security` and can be overridden with `THOTH_APEX_DOMAIN`.
You only need to provide tenant/user/endpoint identity:
`THOTH_TENANT_ID`, `THOTH_USER_ID`, and `THOTH_ENDPOINT_ID`.

## Usage

### Wrap a single MCP server

```bash
thoth run \
  --agent-id gdrive \
  --tenant-id your-org \
  --enforcement-mode progressive \
  --api-key "$THOTH_API_KEY" \
  -- npx -y @modelcontextprotocol/server-gdrive
```

### Wrap your entire Claude Desktop config (idempotent)

```bash
thoth wrap-config \
  --tenant-id your-org \
  --auto-thoth-bin \
  --inherit-path \
  --env THOTH_APEX_DOMAIN=aten.security \
  --enforcement-mode progressive \
  --output ~/Library/Application\ Support/Claude/claude_desktop_config.json \
  ~/Library/Application\ Support/Claude/claude_desktop_config.json
```

### `wrap-config` flags for constrained PATH environments

`thoth wrap-config` supports explicit runtime wiring for Claude Desktop's stripped
environment:

- `--thoth-bin /full/path/to/thoth`
  - Set wrapped `command` to an absolute `thoth` path.
- `--auto-thoth-bin`
  - Auto-resolve the current `thoth` executable path.
- `--env KEY=VALUE` (repeatable)
  - Merge environment variables into each wrapped MCP server.
- `--inherit-path`
  - Inject current shell `PATH` (de-duplicated, platform separator-aware).

If `--thoth-bin` is not provided, `wrap-config` still resolves a full `thoth`
path automatically.

### Cross-platform binary resolution

`thoth` resolves executables explicitly before spawning upstream MCP servers.
This is required because MCP clients often run in minimal environments (Claude
Desktop, CI runners, containers) where shell-initialized PATH entries are not
available.

Resolution order:

1. `shutil.which(...)` with the effective runtime `PATH`
2. Platform fallback directories:
   - macOS/Linux: `/usr/local/bin`, `/opt/homebrew/bin`, `/usr/bin`, `/bin`
   - Windows: `%ProgramFiles%`, `%ProgramFiles(x86)%`, `%LocalAppData%`, `C:\Windows\System32`
3. Explicit fallback scan with Windows `PATHEXT` handling (`.exe`, `.cmd`, `.bat`)
4. Fail-fast error with searched paths and actionable install hints

`thoth` never uses `shell=True` and never depends on `.bashrc` / `.zshrc` /
`nvm` initialization to find binaries.

### Why spawn failures happen

Most `Failed to spawn process: No such file or directory` errors are caused by
runtime environment differences, not by MCP logic:

- `npx`/`node`/`npm` not available in constrained `PATH`
- Windows command resolution differences (`PATHEXT`, `.cmd` vs `.exe`)
- GUI/sandbox runtime PATHs differing from your interactive shell
- Non-JSON output on stdout breaking MCP JSON-RPC streams

The proxy now validates runtime dependencies and logs diagnostics to `stderr`
without polluting MCP `stdout`.

### Recommended command patterns

Safest (absolute executable path):

```json
{
  "command": "/absolute/path/to/node",
  "args": ["/absolute/path/to/server.js"]
}
```

Fallback (Node package through `npx`, resolved safely by proxy):

```json
{
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you"]
}
```

### Show governance state

```bash
thoth status
```

### Emit endpoint health for Jamf Smart Groups

```bash
thoth health --json
```

## Environment variables

| Variable | Description |
|---|---|
| `THOTH_API_KEY` | API key from your Thoth dashboard |
| `THOTH_API_KEY_FILE` | Path to a file containing API key material (recommended over embedding secrets in args/config) |
| `THOTH_EVENT_INGEST_TOKEN` | Optional token sent as `X-Thoth-Event-Ingest-Token` for `/v1/events/batch` telemetry ingest |
| `THOTH_ENFORCER_URL` | Override enforcer URL (default: Thoth cloud) |
| `THOTH_ENFORCER_FAILURE_DECISION` | Enforcer outage fallback (`block`, `step_up`, `allow`); in `staging`/`prod`, `allow` is ignored unless override is set |
| `THOTH_ENFORCER_ALLOW_FALLBACK_OVERRIDE` | Emergency override to allow `THOTH_ENFORCER_FAILURE_DECISION=allow` in `staging`/`prod` |
| `THOTH_USER_ID` | Per-user identifier for audit trail (email or LDAP uid) |
| `THOTH_GOVAPI_URL` | GovAPI base URL for endpoint registration/check-in |
| `THOTH_GOV_API_URL` | Legacy alias for `THOTH_GOVAPI_URL` (accepted for compatibility) |
| `THOTH_APEX_DOMAIN` | Apex domain used for derived defaults (default: `aten.security`) |
| `THOTH_GOVAPI_BEARER_TOKEN` | Optional bearer token for GovAPI auth |
| `THOTH_GOVAPI_API_KEY` | Optional API key header for GovAPI auth |
| `THOTH_ENDPOINT_ID` | Stable endpoint ID override (defaults to hostname) |
| `THOTH_ENROLLMENT_SOURCE` | Enrollment source (`jamf`, `intune`, `manual`, `unmanaged`) |
| `THOTH_ENV` | Endpoint environment (`dev`, `staging`, `prod`) |
| `THOTH_HEARTBEAT_INTERVAL_SECONDS` | Heartbeat cadence to GovAPI (default: `60`) |
| `THOTH_TLS_VERIFY` | Enable strict TLS certificate validation for outbound HTTP (`true` by default) |
| `THOTH_TLS_CA_BUNDLE` | Optional custom CA bundle path used for enforcer/GovAPI TLS validation |
| `THOTH_TLS_PINNED_CERT_SHA256` | Optional comma-separated SHA-256 leaf cert fingerprints for certificate pinning (`sha256:<hex>` or plain 64-char hex) |
| `THOTH_TLS_PIN_CACHE_SECONDS` | Certificate pin verification cache TTL in seconds (default: `300`) |
| `THOTH_TLS_REQUIRE_AWS_BACKED_CERTS` | Require TLS cert trust metadata to be AWS-backed (`THOTH_TLS_AWS_ACM_CERT_ARN` or `THOTH_TLS_AWS_PRIVATE_CA_ARN`) |
| `THOTH_TLS_AWS_ACM_CERT_ARN` | ACM certificate ARN used for enforcer/GovAPI TLS trust attestation |
| `THOTH_TLS_AWS_PRIVATE_CA_ARN` | ACM Private CA ARN used for enforcer/GovAPI TLS trust attestation |
| `THOTH_REQUIRE_NON_ROOT` | Require proxy to run as non-root (`true` by default in `staging`/`prod`) |
| `THOTH_EXPECTED_PROXY_USER` | Optional expected OS username for proxy runtime validation |
| `THOTH_EXPECTED_PROXY_UID` | Optional expected OS uid for proxy runtime validation |

### Secret handling in `wrap-config`

By default, `thoth wrap-config` does **not** embed `--api-key` into generated config args.
Use environment variables (or `THOTH_API_KEY_FILE`) at runtime instead.

If you must embed a key for a break-glass scenario, pass `--embed-api-key` explicitly.

## Session intent (HIPAA minimum-necessary)

```bash
thoth run \
  --agent-id phi-boundary \
  --tenant-id your-org \
  --session-intent phi_eligibility_check \
  --enforcement-mode block \
  --api-key "$THOTH_API_KEY" \
  -- npx -y @mcp/server-phi-boundary
```

## Enterprise fleet deployment

See [Enterprise Fleet Deployment](https://docs.aten.security/thoth/mcp/fleet-deployment)
for Jamf + Intune deployment guides.

### Jamf setup script

Use `setup-claude-mcp.sh` (included in this package root) to generate governed
Claude config without any manual Python post-processing:

```bash
TENANT_ID=acme \
APEX_DOMAIN=aten.security \
ENFORCER_URL=https://enforce.acme.aten.security \
BASE_CONFIG_PATH=/tmp/base-config.json \
CONFIG_PATH="$HOME/Library/Application Support/Claude/claude_desktop_config.json" \
bash setup-claude-mcp.sh
```

## Why the proxy is open source

The proxy is intentionally open source. Security and compliance buyers — the exact people
deploying this — need to audit what runs on their employees' machines. An opaque binary
raises questions; readable source closes them.

The moat is not here. The proxy is ~250 lines that intercept a JSON-RPC call and POST to an
enforcer. Anyone can write this. What competitors cannot replicate is the enforcer logic, the
MOSES behavioral baselines, the compliance packs, and the session telemetry that compounds
with every governed customer. All of that is server-side and never ships in this package.

## Stable public API

The following are part of the stable public API surface as of v0.1.0. Breaking changes require
a major version bump and a migration guide:

| Interface | Stable |
|---|---|
| `thoth run` CLI flags | ✅ |
| `thoth wrap-config` CLI flags and `intent_map.json` schema | ✅ |
| `thoth status` output format | ✅ |
| `--session-intent` flag name and string values | ✅ |
| `THOTH_API_KEY`, `THOTH_ENFORCER_URL`, `THOTH_USER_ID` env vars | ✅ |
| JSON-RPC error codes `-32001` (BLOCK) and `-32002` (STEP_UP) | ✅ |

The `session_intent` string values (e.g. `phi_eligibility_check`, `calendar_management`) are
defined by the enforcer's compliance packs, not this package. New intent values are additive
and non-breaking; removing or renaming an existing value is a breaking change on the enforcer side.

## License

Apache 2.0

