Metadata-Version: 2.5
Name: allem-mcp
Version: 0.1.0
Summary: MCP server for the Allem AI governance platform — lets AI coding assistants check, log, and inspect agent governance during development
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Description-Content-Type: text/markdown

# Allem MCP Server

Connect any MCP-capable AI assistant (Claude Code, Claude Desktop, …) to the
Allem governance platform. Once connected, the assistant can register agents,
run pre-flight authorization checks, log actions to the tamper-evident audit
chain, read compliance intelligence, manage authorization scopes, and
cryptographically verify the audit chain — which means it can write and test
an Allem integration for you.

Transport: stdio (runs locally next to your dev environment).

## 60-second setup

### 1. Get the two required settings

- `ALLEM_BASE_URL` — where your Allem platform lives.
  **There is no default on purpose** — you must say which environment you mean:
  - local development: `http://localhost:8000`
  - production: your hosted Allem URL
- `ALLEM_API_KEY` — an org API key (`alm_sk_test_...` or `alm_sk_live_...`),
  created in the Allem console under Settings → API Keys.

### 2a. Claude Code

```bash
claude mcp add allem \
  --env ALLEM_BASE_URL=http://localhost:8000 \
  --env ALLEM_API_KEY=alm_sk_test_YOUR_KEY \
  -- uv run --directory /path/to/allem-platform/sdk/allem-mcp allem-mcp
```

### 2b. Claude Desktop

Add to `claude_desktop_config.json` (Settings → Developer → Edit Config):

```json
{
  "mcpServers": {
    "allem": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/allem-platform/sdk/allem-mcp", "allem-mcp"],
      "env": {
        "ALLEM_BASE_URL": "http://localhost:8000",
        "ALLEM_API_KEY": "alm_sk_test_YOUR_KEY"
      }
    }
  }
}
```

### 3. Try it

Ask your assistant: *"List my Allem agents and verify the audit chain."*

## Tools

| Tool | What it does | Writes? |
|---|---|---|
| `allem_check_action` | Pre-flight check: may this agent do this action? Denials come back as data (reason, severity, failed checks, any freeze) — never as an error. | records the check in the audit chain |
| `allem_log_action` | Record an action into the hash-chained audit log; returns event hash + chain height. | append-only |
| `allem_list_agents` | List registered agents with status and mode. | read-only |
| `allem_get_agent` | One agent in full: record + Five Threads scores + freeze state. | read-only |
| `allem_register_agent` | Onboard an agent (idempotent; starts in observation mode). | creates |
| `allem_get_compliance_status` | healthy / warning / critical / frozen, with reasons. | read-only |
| `allem_get_thread_explanations` | Plain-language explanation of each thread score. | read-only |
| `allem_get_framework_assessment` | SOC 2 / ISO 27001 / GDPR / EU AI Act control assessments. | read-only |
| `allem_get_recommendations` | Prioritized governance recommendations. | read-only |
| `allem_list_events` / `allem_get_event` | Browse the audit chain. `allem_list_events` returns `{events, lifecycle_events_excluded, how_many_were_excluded}`: the server applies the exclusion and says how many run starts, heartbeats and run ends it left out of the window. The client holds no list of its own — `event_type` is free text an agent chooses, and a private vocabulary of reserved words here hid events Allem counted everywhere else. | read-only |
| `allem_list_verdicts` | Governance verdicts with filters (thread, severity, since) + pagination. | read-only |
| `allem_list_scopes` | An agent's authorization scope versions, newest first. | read-only |
| `allem_create_scope` | New scope version. Safe by design: versioned and audit-chained, never rewrites history. | creates version |
| `allem_activate_scope` | **Switches the agent from observation to live enforcement.** Marked destructive — after this, actions can be denied and freezes issued. | changes behavior |
| `allem_verify_chain` | Walk the whole chain and recompute every SHA-256 link — proof nothing was altered. | read-only |

Agents can be referenced by their friendly `external_id` (e.g.
`shuffle-triage-bot`) everywhere — no need for database ids.

## Deliberately not included

- **Freeze lift / unfreeze** — requires a console **admin login** (session
  auth), not an API key. Un-freezing an agent is a human decision made in the
  Allem console; no API key, and therefore no MCP tool, can do it. Don't hunt
  for it here.
- Anything else admin-session-gated (user management, API key management).

## Development

```bash
cd sdk/allem-mcp
uv sync --extra dev
uv run --extra dev python -m pytest          # unit tests (mocked HTTP)
uv run python scripts/e2e_local.py           # end-to-end vs local platform
uv run python scripts/seed_evals.py          # seed data for evals.xml
npx @modelcontextprotocol/inspector uv run allem-mcp   # interactive inspector
```

Note: the dev venv is pinned to Python 3.11 (`.python-version`). Python 3.14
skips `.pth` files that carry the macOS *hidden* file flag, which breaks uv's
editable installs — 3.11 matches the platform's locked stack and avoids this.

## Follow-ups (out of scope for v1)

- Publishing to an MCP registry (with Asif).
- Website / `llms.txt` update to advertise the server.
- Remote streamable-HTTP transport, if demand appears.
