companycam-mcp
README.md
# companycam-mcp
Remote [MCP](https://modelcontextprotocol.io) server for the [CompanyCam API](https://docs.companycam.com/reference), built for use as a **claude.ai custom connector** (and any other MCP client that speaks Streamable HTTP).
- **Transport:** MCP Streamable HTTP (stateless JSON-RPC over POST) — no SSE stream, no sessions
- **Runtime:** single zero-dependency Vercel serverless function ([api/_lib/mcp-core.ts](api/_lib/mcp-core.ts))
- **Auth to CompanyCam:** server-side `COMPANYCAM_API_TOKEN` (Bearer)
- **Auth to the endpoint** (two equivalent modes, same `MCP_SHARED_SECRET`):
- Secret path: `https://<deployment>/mcp/<MCP_SHARED_SECRET>` — for the claude.ai custom-connector dialog
- Bearer header: `https://<deployment>/mcp` with `Authorization: Bearer <MCP_SHARED_SECRET>` — for Claude Tag "Connect an app" credentials (see [.mcp.json](.mcp.json), which registers this repo as a Claude Tag plugin pointing at `/mcp`)
## Tools (26)
No delete tools are exposed by design — the shared server-side token means every connector user acts as the token owner, so destructive operations are limited to archiving (reversible).
| Area | Tools |
|---|---|
| Company / users | `get_company`, `get_current_user`, `list_users` |
| Projects | `list_projects`, `get_project`, `create_project`, `update_project`, `archive_project`, `restore_project`, `update_project_notepad` |
| Project people | `list_project_assigned_users`, `assign_user_to_project` |
| Project content | `list_project_documents`, `list_project_comments`, `add_project_comment` |
| Photos | `list_project_photos`, `list_photos`, `get_photo`, `add_photo`, `update_photo_description` |
| Photo metadata | `list_photo_tags`, `add_photo_tags`, `list_photo_comments`, `add_photo_comment` |
| Tags | `list_tags`, `create_tag` |
Notes:
- `add_photo` requires the image to already be hosted at a **publicly accessible URL** — that's how the CompanyCam API works (it downloads from `uri`).
- Write tools accept `acting_user_email` to attribute the action to a specific CompanyCam user (`X-CompanyCam-User` header).
- Photo responses collapse the `uris` renditions array into a `{type: url}` map to keep chat context small.
## Environment variables (Vercel)
| Var | Purpose |
|---|---|
| `COMPANYCAM_API_TOKEN` | CompanyCam API access token (CompanyCam → Settings → API) |
| `MCP_SHARED_SECRET` | Random string that becomes the secret path segment of the connector URL |
## Add to claude.ai
Settings → Connectors → **Add custom connector**:
- **Name:** CompanyCam
- **Remote MCP server URL:** `https://<production-domain>/mcp/<MCP_SHARED_SECRET>`
- Leave OAuth fields empty (auth is the secret URL + server-side token).
## Develop
```bash
npm install
npm test # local protocol smoke tests, no network needed
vercel deploy # preview
vercel deploy --prod
```
Smoke-test a deployment:
```bash
curl -s https://<domain>/mcp/<secret> -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues