Metadata-Version: 2.4
Name: arch-insight-mcp
Version: 0.1.8
Summary: Model Context Protocol server for ARCH-Insight: search fact sheets, applications, tickets and monitor incidents from ChatGPT, Claude and Gemini.
Project-URL: Homepage, https://arch-insight.com
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: mcp<3,>=2.3
Requires-Dist: httpx>=0.27
Requires-Dist: uvicorn>=0.30
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Requires-Dist: anyio>=4; extra == "test"
Requires-Dist: ruff>=0.6; extra == "test"

# arch-insight-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) server for
ARCH-Insight. It lets ChatGPT, Claude, Gemini CLI and other MCP clients search
fact sheets, applications, helpdesk tickets, tasks, monitoring incidents and
finance transactions, and make a few clearly named changes (open or reply to a
ticket, create a task, acknowledge an incident, book a transaction, issue or
send an e-invoice). Nothing is deleted through it.

## Install and sign in (local, stdio)

```sh
uvx arch-insight-mcp login          # email + password; saves a refresh token
uvx arch-insight-mcp                # runs the stdio server
```

`login` stores the session in `~/.config/arch-insight/mcp-session.json`
(`%APPDATA%\arch-insight\` on Windows, mode 0600). Accounts that sign in with
Google can paste a refresh token instead:
`arch-insight-mcp login --refresh-token-stdin`.

Alternatively set `ARCH_REFRESH_TOKEN`, or `ARCH_ACCESS_TOKEN` for a
short-lived access token. `ARCH_API_URL` selects a self-hosted deployment.

For automation, set `ARCH_API_KEY` to a personal API key (`ai_live_…`, created
under Account → API keys). It is sent as `Authorization: Bearer` like an access
token, works for one organisation, and only for what its scopes allow (`read`,
`finance:write`, `finance:invoice`); a tool outside those scopes fails with the
API's explanation. `ARCH_API_KEY` wins over the other variables. Over HTTP a
client may present an API key as its bearer token too.

### Clients

- Claude Code: `/plugin marketplace add ARCH-Insight/claude-plugin`, then
  `/plugin install arch-insight@arch-insight` — or
  `claude mcp add arch-insight -- uvx arch-insight-mcp`.
- Claude Desktop: add to `claude_desktop_config.json`:
  `{"mcpServers": {"arch-insight": {"command": "uvx", "args": ["arch-insight-mcp"]}}}`
- Gemini CLI: install the extension from the release archive
  (`gemini-extension.tar.gz`) or `gemini extensions install <repo-url>`.

## Remote (Streamable HTTP, for ChatGPT)

```sh
docker run -p 8000:8000 \
  -e ARCH_MCP_PUBLIC_URL=https://mcp.arch-insight.com/mcp \
  arch-insight-mcp:<version>
```

The endpoint is `/mcp`. The server holds no credential: each request must carry
the user's ARCH-Insight bearer token, which is checked against
`/api/auth/me`. It publishes OAuth protected-resource metadata pointing at
`ARCH_OAUTH_ISSUER` (default `https://auth.arch-insight.com`), so clients that
speak MCP authorization (ChatGPT) sign the user in there. `/healthz` is a
liveness probe; `OPENAI_APPS_CHALLENGE` is served at
`/.well-known/openai-apps-challenge` for ChatGPT domain verification.

If the user's organisation requires MFA (`/api/auth/me` returns
`mfa_required: true`) and the token's session has not completed it
(`mfa_verified: false`), the token is refused: HTTP mode answers 401 with
`WWW-Authenticate: Bearer error="insufficient_user_authentication"`, stdio mode
fails every tool call with the same explanation. Tokens from ARCH-Insight's
OAuth server (ChatGPT) are always aal1, so for them the API waives the
requirement when the person approved that connector on the consent screen
after an MFA challenge (an MFA-backed grant, 30 days, revocable under Account
→ Connected apps); `/api/auth/me` then reports `mfa_required: false`.

| Variable | Default |
| --- | --- |
| `ARCH_API_URL` | `https://arch-insight.com` |
| `ARCH_MCP_PUBLIC_URL` | `http://<host>:<port>/mcp` |
| `ARCH_OAUTH_ISSUER` | `ARCH_AUTH_URL` or `https://auth.arch-insight.com` |
| `ARCH_MCP_ALLOWED_HOSTS` | host of `ARCH_MCP_PUBLIC_URL` |

## Tools

Read-only: `search`, `fetch` (ChatGPT deep-research shape),
`search_architecture`, `list_fact_sheets`, `get_fact_sheet`,
`list_applications`, `list_projects`, `list_tasks`, `list_tickets`,
`get_ticket`, `get_monitor_status`, `list_incidents`, `list_alerts`.

Writes: `create_ticket`, `reply_to_ticket`, `set_ticket_status`,
`create_task`, `acknowledge_incident`.

Finance: `finance_list_accounts`, `finance_list_transactions` (read-only);
`finance_create_transaction`; `finance_issue_invoice` (issues the e-invoice and
returns its XML and/or the PDF as base64, with an optional `format` such as
`zugferd`, `xrechnung-cii` or `xrechnung-ubl` — left out, the server default
applies); `finance_send_invoice` (e-mails it). Sending cannot be undone, so
`finance_send_invoice` does nothing unless called with `confirm: true`; without
it, it returns what it would send.

## Development

```sh
pip install -e '.[test]'
pytest && ruff check .
```
