Metadata-Version: 2.4
Name: ocp-mcp-server
Version: 0.2.0b10
Summary: Open Collaboration Platform (OCP) MCP server for Claude Desktop [BETA]
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx-sse>=0.4.0
Requires-Dist: httpx<1.0,>=0.27.0
Requires-Dist: mcp<2.0.0,>=1.0.0
Description-Content-Type: text/markdown

# OCP MCP Server — Claude Desktop Integration

Gives Claude Desktop direct access to the Open Collaboration Platform (OCP) — 394 API endpoints plus smart tools for searching and managing BIM objects.

---

## Prerequisites

| Requirement | Notes |
|---|---|
| **macOS** | Windows not yet supported |
| **Python 3.10+** | Check with `python3 --version`. Download from [python.org](https://www.python.org/downloads/) if needed |
| **Claude desktop** | Download from [claude.ai/download](https://claude.ai/download) |
| **BimPlus account** | You need your Nemetschek email and password |

---

## Security Notes

**⚠️ Token storage in `runtime_config.json`**

When you authenticate, your token is saved to `~/.config/ocp-mcp/runtime_config.json`. **This file contains live tokens and should NEVER be committed to version control.**

**Guidelines:**
- ✅ `.gitignore` already contains `runtime_config.json` — verify this before committing
- ✅ Restrict file permissions: `chmod 600 runtime_config.json` (owner read-only)
- ✅ Never share this file or its contents with others
- ✅ Tokens automatically expire; re-authenticate when needed

**SSL Verification (Advanced)**
By default, SSL certificate verification is **enabled** (`verify_ssl=true`). For staging environments with self-signed certificates, you can disable it via environment variable:
```bash
export BIMPLUS_VERIFY_SSL=false
```
Or in `runtime_config.json`:
```json
{
  "verify_ssl": "false"
}
```
⚠️ Only disable for development/staging — always enable for production.

---

## Installation (2 minutes)

### Option A — uvx (recommended, no git clone needed)

**1. Open Terminal** — press `Cmd+Space`, type `Terminal`, press Enter.

**2. Add to Claude Desktop config** (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "ocp": {
      "command": "uvx",
      "args": ["--prerelease=allow", "ocp-mcp-server"]
    }
  }
}
```

**3. Restart Claude Desktop** — quit (`Cmd+Q`) and reopen it.

**4. Authenticate** — in a new Claude conversation, type:

```
Use authenticate_bimplus to log me in
```

Claude will ask for your email and password and save the token for future sessions.

> **Requires:** [uv](https://docs.astral.sh/uv/getting-started/installation/) installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)

---

### Option B — local install (from source)

**1. Download and extract** the zip file to a permanent location on your Mac.  
   > Tip: put it somewhere it won't be accidentally deleted, e.g. `~/Applications/bimplus-mcp/`

**2. Open Terminal** — press `Cmd+Space`, type `Terminal`, press Enter.

**3. Run the installer:**

```bash
cd /path/to/bimplus-api-mcp
bash install.sh
```

**4. Restart Claude Desktop** — quit (`Cmd+Q`) and reopen it.

**5. Authenticate** — same as step 4 above.

---

## What you can do after setup

Just ask Claude in plain English:

- *"Show me all models in team acme-corp"*
- *"Find all doors on the second floor"*
- *"What are the properties of element XYZ?"*
- *"Search for walls with fire rating EI60"*

---

## Smart tools (LLM-friendly)

This server exposes all API endpoints from `swagger.json` and also provides higher-level tools that combine multiple API calls.

### `ocp_help`
- Purpose: Front-door routing tool. Returns available capabilities and example prompts.
- Use when: Prompt contains "OCP", "BimPlus", "construction platform", or when unsure which tool to use.
- Trigger phrases: "what can OCP do", "help with OCP", "what tools are available", "open OCP".
- Output: Full list of capabilities with example prompts.

### `set_bimplus_config`
- Purpose: Save runtime connection settings (token, base URL, team, credentials).
- Use when: Authentication or API calls fail due to missing config.
- Output: Saved config with sensitive fields masked.

### `get_bimplus_config`
- Purpose: Read current runtime settings.
- Use when: You want to verify what token/team/base URL is active.
- Output: Current config with sensitive fields masked. Shows a first-run hint if no config file exists yet.

### `authenticate_bimplus`
- Purpose: Log in with stored credentials and save a fresh token.
- Primary tool for: "login to OCP", "log in to OCP", "authenticate OCP", "connect to BimPlus".
- Required config first: `user_id`, `password`, `application_id`.
- Output: Auth status and token metadata.

### `start_sso_login`
- Purpose: Full browser-based SSO login — opens the Allplan login page and captures the token automatically via OAuth2 PKCE. No manual token copy-paste required.
- Use when: "Login to OCP with SSO", "browser login", "login via portal".
- Flow: browser opens → user logs in → token saved automatically.
- Optional input: `clear_password` (default `true`), `timeout_seconds` (default `120`).
- Output: Login status and masked token metadata.

### `set_bimplus_sso_token`
- Purpose: Manually paste a Bearer token (fallback when browser login isn't possible).
- Use when: You already have an OCP/BimPlus access token from another source.
- Required input: `token`.
- Optional input: `token_type` (default `Bearer`), `clear_password` (default `true`).
- Output: Token validation status and masked token metadata.

### `list_my_teams`
- Purpose: List teams available to the current user.
- Use when: You ask "list my teams" / "show available teams" / "search team".
- Optional input: `query`, `limit`.
- Output: Normalized team rows (`id`, `name`, `slug`).

### `list_team_projects`
- Purpose: List projects in a team and optionally search by name/ID.
- Use when: You ask "list all projects" / "search team project".
- Optional input: `team_slug`, `query`, `limit`.
- Output: Normalized project rows (`id`, `name`, `number`, `status`).

### `list_project_models`
- Purpose: List models (project divisions) in the current project and optionally filter them.
- Use when: You ask "show the model names" / "which models are available here" / "list models" / "what models are in this project".
- Optional input: `team_slug`, `project_id`, `query`, `limit`.
- Output: Normalized model rows (`id`, `name`) plus the current model when available.

### `search_objects`
- Purpose: Run object search across project topology with optional filters.
- Required input: `project_id`.
- Filter options:
   - `conditions`: structured equality filters.
   - `filter_string`: raw advanced BIMPlus filter syntax.
- Output: Filtered result hierarchy/export payload.

### `count_elements_by_type`
- Purpose: Count objects per element type in a project.
- Required input: `project_id`.
- Optional input: `team_slug`, `include_zero`, `max_concurrency`.
- Output: Per-type counts, per-discipline totals, and errors.

### `count_elements_by_property_value`
- Purpose: Count objects where a property equals a value for a specific type.
- Required input: `project_id`, `type_name_or_id`, `property_name`, `property_value`.
- Optional input: `case_sensitive`, `trim_whitespace`, `sample_limit`.
- Output: Matched count, sample IDs, and top value distribution.

### `bulk_update_property_by_filter`
- Purpose: Safely update an attribute for all objects matched by a filter.
- Required input: `project_id`, `type_name_or_id`, `filter_property_name`, `filter_property_value`, `attribute_id`, `new_value`.
- Safety flow:
   - Preview first with `dry_run=true`.
   - Apply only with `dry_run=false` and `confirm=true`.
   - Optionally verify read-back with `verify=true` and `target_property_name`.
- Output: Match summary, update status, failed IDs, verification details.

### `project_dashboard_insights`
- Purpose: Build a one-call project dashboard with project details, issue summaries, element totals, top types, and area/volume insights.
- Required input: `project_id`.
- Optional input: `team_slug`, `top_n_types`, `sample_issue_limit`, `include_element_samples`, `area_property_names`, `volume_property_names`.
- Output: Normalized dashboard JSON suitable for charts/tables and follow-up analysis.

### Generic API endpoint tools
- Purpose: Direct access to each endpoint in the BIMPlus OpenAPI spec.
- Naming: Derived from HTTP method and path, for example `get_by_teamslug_projects_by_projectid_element_types`.
- Output: HTTP status and raw endpoint response.

---

## Example prompts

**Getting started**
- "What can OCP do?" *(routes to ocp_help)*
- "Login to OCP." *(credentials in config)*
- "Login to OCP with SSO." *(browser opens automatically)*
- "Login to OCP with SSO token <paste token>." *(manual paste fallback)*

**Discovery**
- "List my teams."
- "List all projects in my current team."
- "Which models are available here?"
- "Show OCP projects in team <slug>."

**Analysis**
- "Count all object types in project <project_id>."
- "How many Columns have material C30/37?"
- "Show project dashboard for <project_id>."
- "Search OCP objects where material is C30/37."

**Edits**
- "Preview updating Product name to Claude for Columns where material is C30/37."
- "Apply that update now with confirm=true and verify using target property Product name."

**Low-level**
- "Call get_by_teamslug_projects_by_projectid_element_types for team <team_slug> and project <project_id>."

---

## Tool Catalog Modes And Fallback

This server supports three catalog modes:

- `smart`: smart tools only (lowest token usage)
- `hybrid`: smart tools + curated autogenerated endpoints
- `full`: smart tools + full autogenerated endpoint catalog (can be capped)

To reduce "tool not available" responses while staying efficient, smart mode can expose a fallback slice:

- `tool_catalog_fallback_mode`: `off` | `hybrid` | `full`
- `tool_catalog_fallback_limit`: number of fallback autogenerated tools to expose in smart mode

You can set these via `set_bimplus_config`:

```text
Set tool_catalog_mode to "smart"
Set tool_catalog_fallback_mode to "hybrid"
Set tool_catalog_fallback_limit to 25
```

Or directly in `runtime_config.json` / env vars (`BIMPLUS_TOOL_CATALOG_*`).

---

## Session1 Regression Script

You can run a full scenario regression matching the historical `session1.md` workflow.

### Safe mode (default, no writes)

```bash
.venv/bin/python scripts/session1_regression.py
```

This runs authentication, read-only checks, the new model discovery step, and the bulk-update **dry-run** safety step.
If stored credentials are stale, the auth step falls back to validating the existing session token so the rest of the regression can still complete.

### Full parity mode (includes write apply)

```bash
.venv/bin/python scripts/session1_regression.py --apply-writes
```

This also executes the bulk update apply step and writes data (same target value used in session: `Claude`).

### Useful flags

```bash
.venv/bin/python scripts/session1_regression.py \
   --team-slug ctf-nemetschek-allplan-gmbh-ft \
   --project-id 3e9fed73-0c06-48fb-888a-d5b2ad7b3c05 \
   --model-id 9deba3db-2c4a-4ce6-b1ec-45c5b2b35929 \
   --keep-config
```

Notes:
- Exit code is `0` when all scenarios pass, otherwise `1`.
- By default, the script restores your previous runtime config after execution.

---

## Changing your team or project

```
Set the BimPlus team slug to "my-team-name"
Set the BimPlus project ID to "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```

Claude will remember these settings between sessions.

---

## Troubleshooting

**"bimplus-api" does not appear in Claude's tools**
- Make sure you fully quit and reopened Claude desktop after installation.
- Re-run `bash install.sh` to check for errors.

**Authentication fails**
- Ask Claude: *"What is the current BimPlus config?"* to verify the token field.
- Try authenticating again: *"Run authenticate_bimplus"*
- If you see HTTP 401 Unauthorized, update `password` and/or `application_id` via `set_bimplus_config`, then retry.
- Do not store masked values (e.g. `Micr...09`) in `runtime_config.json`; authentication requires the full plaintext password.

### Prefer SSO Login (No Password In Config)

The easiest way — no password, no copy-paste:

```text
Login to OCP with SSO.
```

Claude opens the Allplan login page in your browser. Once you complete login, the token is captured and saved automatically. The whole flow takes about 15 seconds.

**How it works under the hood:**
1. A temporary local HTTP server starts on port `8766`.
2. Your browser opens to the Allplan Keycloak login page (OAuth2 PKCE flow).
3. After login, Keycloak redirects to `http://localhost:8766/callback` with an authorization code.
4. The server exchanges the code for a Keycloak token, then exchanges that for a BimPlus Identity token via `/v2/cross-token` → `/v2/cross-authorize`.
5. The Identity token is saved to config; the local server shuts down.

**Fallback — paste a token manually:**

If the browser flow isn't available, call `set_bimplus_sso_token` and paste a token directly:

```text
Use set_bimplus_sso_token with:
- token: <PASTE_ACCESS_TOKEN>
- token_type: Identity
- clear_password: true
```

The server validates via `GET /v2/authorize` before saving.

**Config knobs:**
- `sso_callback_port` — local port for the OAuth redirect (default `8766`)
- `sso_auth_server` — Keycloak base URL (auto-derived from `base_url` if empty)

**Python not found**
- Install Python 3.10+ from [python.org](https://www.python.org/downloads/) and re-run `install.sh`.

---

## What install.sh does

1. Checks that Python 3.10+ is installed
2. Creates a local `.venv` virtual environment (uses `uv` if available, otherwise `python -m venv`)
3. Installs the two dependencies: `mcp` and `httpx`
4. Patches `~/Library/Application Support/Claude/claude_desktop_config.json` to register the `bimplus-api` MCP server entry pointing at the local venv and `server.py`

It is safe to re-run — it will update an existing installation in place.

---

## Sharing with colleagues

Send them the zip and this message:

> Extract the zip somewhere permanent (e.g. `~/Applications/bimplus-mcp/`), open Terminal, run `bash install.sh`, restart Claude desktop, then ask Claude to run `authenticate_bimplus` with your Nemetschek credentials.

---

## Files in this package

| File | Purpose |
|---|---|
| `server.py` | The MCP server (all logic lives here) |
| `swagger.json` | Full BimPlus API specification |
| `pyproject.toml` | Python package metadata |
| `install.sh` | Automated setup script |
| `README.md` | This file |

`runtime_config.json` is created automatically the first time you authenticate — it stores your token locally and is never sent anywhere except to the BimPlus API.
