Connect CompanyCam to Claude: Track Field Work and Documentation
Learn how to connect CompanyCam to Claude using a managed MCP server. This guide covers architecture, setup steps, hero tools, and real-world field workflows.
If your team needs to connect CompanyCam to Claude to automate field documentation, manage site photography workflows, or streamline project check-ins, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's tool calls and CompanyCam's REST API. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on /connect-companycam-to-chatgpt-manage-projects-and-site-visuals/ or explore our broader architectural overview on /connect-companycam-to-ai-agents-automate-billing-and-checklists/.
Giving a Large Language Model (LLM) read and write access to a field-first documentation platform like CompanyCam is an engineering challenge. You have to handle OAuth 2.0 token lifecycles, map complex media upload schemas to MCP tool definitions, and deal with CompanyCam's domain-specific pagination and resource taxonomies. Every time an endpoint shifts - like the migration from legacy checklists to advanced checklists - you have to update your server code, redeploy, and test the integration.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for CompanyCam, connect it natively to Claude, and execute complex field documentation workflows using natural language.
The Engineering Reality of the CompanyCam API
A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against specialized B2B APIs is painful. CompanyCam is built to handle massive volumes of media from disparate field teams, and its API reflects that complexity.
If you decide to build a custom CompanyCam MCP server, here are the specific integration challenges you will face:
Fragmented Taxonomies for Media vs. Projects
CompanyCam enforces strict structural boundaries between how you organize a job site and how you organize the media within it. An LLM might logically try to "tag a project" or "label a photo," but the API uses labels exclusively for projects (e.g., "In Progress", "Phase 1") and tags exclusively for photos (e.g., "Damage", "Before"). A custom MCP server must guide the LLM to use the correct distinct endpoints (project_labels.create vs photo_tags.create), otherwise the API will reject the payload with 422 errors.
Legacy vs. Advanced Checklists
CompanyCam is actively supporting two entirely different checklist architectures: Classic (Legacy) and Advanced. Classic checklists are flat lists of tasks and sub-tasks. Advanced checklists rely on a complex field tree schema where sections are treated as fields with a field_type of "section". If an LLM attempts to parse or update an advanced checklist using the legacy endpoints, the structure will fail to deserialize. Your MCP server must expose strictly scoped tools that differentiate these two data models, ensuring the LLM understands when to call project_advanced_checklists.update versus project_legacy_checklists.update.
Two-Step Binary Uploads
When dealing with media, CompanyCam does not allow direct binary uploads in a single API request unless you are providing a public uri. If you are uploading local files, you must orchestrate a two-step process: first calling uploads.create to generate a short-lived presigned S3 URL and retrieve an upload_id, then PUTting the raw bytes to AWS, and finally calling project_photos.create with that upload_id. Managing this asynchronous file flow natively within an MCP tool call requires significant state management that an LLM cannot handle natively.
Strict Cursor Pagination Limits
CompanyCam relies heavily on cursor-based pagination for listing resources like projects, photos, and documents. The maximum limit per page is strictly capped at 100 (defaulting to 50). If an LLM asks for "all photos on a project," a naive API call will return a truncated list. Your MCP server must either handle the cursor loop internally or explicitly instruct the LLM on how to pass the next_cursor value back in subsequent tool calls without modifying the string.
How to Generate a CompanyCam MCP Server
Truto abstracts away OAuth, pagination, and schema mapping. By reading the connected CompanyCam account's documented resources, Truto dynamically generates an MCP-compliant JSON-RPC server. You can generate this server via the Truto UI or programmatically via the API.
Method 1: Via the Truto UI
If you are testing workflows locally in Claude Desktop or setting up a one-off connection for your internal team, the UI is the fastest path.
- Log into your Truto dashboard and navigate to the Integrated Accounts page.
- Select your connected CompanyCam account.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Select your configuration. You can filter by methods (e.g.,
read,write) or tags (e.g.,projects,photos) to limit what the LLM can do. - Click Save and copy the generated MCP Server URL (it will look like
https://api.truto.one/mcp/abc123def456...).
Method 2: Via the Truto API
For production applications where you need to programmatically provision MCP servers for your end-users, you can use the Truto REST API. This creates a secure, hashed token in the Truto control plane and returns a ready-to-use URL.
curl -X POST https://api.truto.one/integrated-account/{integrated_account_id}/mcp \
-H "Authorization: Bearer YOUR_TRUTO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CompanyCam Field Ops MCP",
"config": {
"methods": ["read", "write"],
"tags": ["projects", "photos", "checklists"]
},
"expires_at": "2026-12-31T23:59:59Z"
}'The response contains the exact URL you will provide to the Claude client:
{
"id": "mcp_srv_89xyz",
"name": "CompanyCam Field Ops MCP",
"url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}Connecting the MCP Server to Claude
Once you have your Truto MCP URL, you need to register it with your Claude environment. Because Truto MCP servers use standard HTTP POST payloads, they are natively compatible with any MCP client.
Method A: Via the Claude UI (Web/Desktop)
If you are using the consumer-facing Claude application:
- Open Claude and navigate to Settings.
- Click on Integrations (or Connectors depending on your tier).
- Click Add MCP Server.
- Paste the Truto MCP URL (
https://api.truto.one/mcp/...) into the Server URL field. - Click Add. Claude will immediately send an
initializerequest to discover the available CompanyCam tools.
Method B: Via Manual Config File (Claude Desktop)
If you are developing locally with Claude Desktop, you can register the server using the claude_desktop_config.json file. Truto provides an SSE (Server-Sent Events) wrapper that bridges the local client to the remote Truto server.
Open your configuration file:
- Mac:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add the following JSON block, replacing the URL with your Truto URL:
{
"mcpServers": {
"companycam-truto": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://api.truto.one/mcp/YOUR_DYNAMIC_TOKEN"
]
}
}
}Restart Claude Desktop. The agent will now have access to CompanyCam tools directly in the chat interface.
Hero Tools for CompanyCam
The Truto MCP server dynamically generates tools based on CompanyCam's API documentation. Here are the 6 highest-leverage tools for automating field documentation workflows.
list_all_company_cam_projects
This tool is the entry point for almost every CompanyCam workflow. It fetches the active projects (jobs/sites) associated with the company, returning IDs, statuses, addresses, and geofence coordinates. The LLM uses this to find the target project_id required by downstream tools.
"Find the project ID for the site located at 123 Main St, and let me know its current status."
create_a_company_cam_project_photo
This tool uploads a photo to a specific project. It accepts either a uri (a public image URL that CompanyCam downloads) or an upload_id (if handling binary files). It also accepts optional parameters like captured_at, description, and GPS coordinates.
"Upload this exterior damage photo to the 123 Main St project and tag it as 'Roofing Issue'."
create_a_company_cam_project_page
Pages are rich-text notes or reports authored natively inside CompanyCam. This tool allows the LLM to draft daily site logs, weather updates, or incident reports and attach them directly to a project.
"Draft a daily site log for the Oakwood Renovation project noting that the drywall installation is complete, and create it as a new page."
update_a_company_cam_project_advanced_checklist_by_id
Advanced checklists enforce complex quality assurance standards. This tool allows the LLM to set answers and mark specific fields or sections as complete. The MCP tool enforces the strict schema requirements needed to mutate the checklist field tree safely.
"Mark the 'Foundation Inspection' section of the advanced checklist as complete for the Downtown Office project."
update_a_company_cam_project_task_by_id
This tool edits a single assignable task in a project's Tasks section. The LLM can change the text, mark it complete, or reassign it to different users in a single call. This is crucial for dispatching rework or tracking punch-list items.
"Assign the task 'Fix exposed wiring in kitchen' on the Smith Residence project to the electrical subcontractor and mark its status as incomplete."
create_a_company_cam_project_document_folder
Folders keep project media and documents organized. If an LLM is generating weekly reports or processing multiple permits, it can use this tool to create a dedicated directory on the project before uploading the files.
"Create a new document folder called 'City Permits' on the Highland Park project."
For the complete tool inventory and schema details, visit the CompanyCam integration page.
Workflows in Action
By chaining these tools together, Claude can execute multi-step field operations based entirely on natural language. Here are two concrete examples.
Scenario 1: Field Documentation and Reporting
Persona: Site Superintendent
A superintendent uses Claude on their mobile device at the end of the day to log progress and attach visual proof of completed work.
"Pull up the Oakwood Renovation project. I just uploaded a photo of the completed drywall to this public link: [URL]. Add that photo to the project, tag it as 'Progress', and then draft a daily log page saying that the framing and drywall are finished for the first floor."
Tool execution sequence:
- Claude calls
list_all_company_cam_projects(searching by name "Oakwood Renovation") to retrieve theproject_id. - Claude calls
create_a_company_cam_project_photousing theproject_id, passing the public URL as theuriand setting the tag to "Progress". - Claude calls
create_a_company_cam_project_pageusing theproject_id, generating a rich-text document with the title "Daily Log" and the requested summary text.
The user gets back a confirmation that the photo is secured in the project gallery and the daily report is filed.
sequenceDiagram
participant User as Site Superintendent
participant Claude as Claude Desktop
participant MCP as Truto MCP Server
participant CC as CompanyCam API
User->>Claude: "Add this photo to Oakwood Renovation and draft a log..."
Claude->>MCP: Call list_all_company_cam_project_search_results
MCP->>CC: GET /v2/projects (search)
CC-->>MCP: Project ID returned
MCP-->>Claude: Project ID
Claude->>MCP: Call create_a_company_cam_project_photo
MCP->>CC: POST /v2/projects/{id}/photos
CC-->>MCP: Photo URI created
MCP-->>Claude: Success confirmation
Claude->>MCP: Call create_a_company_cam_project_page
MCP->>CC: POST /v2/projects/{id}/pages
CC-->>MCP: Page created
MCP-->>Claude: Page ID
Claude-->>User: "Photo uploaded and daily log page created."Scenario 2: QA Checklist and Issue Tracking
Persona: Quality Assurance Manager
A QA Manager reviews a site remotely and spots a defect. They use Claude to update the checklist and dispatch a task for rework.
"Find the advanced checklist for the Downtown Office project. Mark the 'HVAC Inspection' field as failed. Then, create a new task on the project for the mechanical team to review the ductwork in the lobby."
Tool execution sequence:
- Claude calls
list_all_company_cam_projectsto find the Downtown Officeproject_id. - Claude calls
list_all_company_cam_project_advanced_checkliststo retrieve the checklist ID and the specificfield_idfor the HVAC Inspection. - Claude calls
update_a_company_cam_project_advanced_checklist_by_idpassing thefieldsarray to mark the specific field as failed. - Claude calls
create_a_company_cam_project_taskto generate a new assignable task for the rework.
flowchart TD
A["User asks to fail HVAC QA<br>for Downtown Office"] --> B["Claude calls<br>list_all_company_cam_projects"]
B --> C["Claude calls<br>list_all_company_cam_project_advanced_checklists"]
C --> D["Claude receives<br>checklist ID and field tree"]
D --> E["Claude calls<br>update_a_company_cam_project_advanced_checklist_by_id"]
E --> F["Checklist field marked failed"]
F --> G["Claude calls<br>create_a_company_cam_project_task"]
G --> H["Task assigned to mechanical team<br>for rework"]Handling Rate Limits in Production
CompanyCam enforces rate limits to ensure API stability across heavy media payloads. It is critical to understand that Truto does not retry, throttle, or apply backoff logic on rate limit errors.
When CompanyCam returns an HTTP 429 Too Many Requests error, Truto passes that error directly back to the caller. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) conforming to the IETF specification.
The caller - your MCP client or AI agent - is strictly responsible for interpreting these headers, applying exponential backoff, and retrying the tool call. Do not assume the integration layer will absorb rate limit penalties on your behalf.
Security and Access Control
When generating MCP servers via Truto, you have granular control over what the AI agent can access.
- Method Filtering: Use the
config.methodsarray to restrict the server to specific operations (e.g.,["read"]ensures the LLM can only query data, never update checklists or delete photos). - Tag Filtering: Use the
config.tagsarray to limit tools by domain (e.g.,["photos", "documents"]). Tools outside these tags are omitted from the server. - Authentication Requirements: Enable
require_api_token_auth: trueto require a valid Truto API token in theAuthorizationheader, preventing anonymous access even if the MCP URL is leaked. - Automatic Expiry: Set an
expires_atISO datetime to create short-lived servers, ideal for granting temporary access to contractors or automated build jobs.
Wrapping Up
Integrating CompanyCam with Claude via an MCP server moves your AI workflows out of the chat window and into the field. By leveraging Truto to auto-generate the JSON-RPC interface, you avoid the heavy lifting of maintaining OAuth tokens, normalizing pagination cursors, and reverse-engineering complex checklist schemas.
Instead of wasting engineering cycles updating integration boilerplate every time CompanyCam shifts an endpoint, your team can focus on building intelligent agentic workflows that orchestrate site safety, enforce quality assurance, and streamline field reporting.
FAQ
- How do I connect CompanyCam to Claude Desktop?
- You can connect CompanyCam to Claude Desktop by generating an MCP server URL via Truto, then adding that URL to your claude_desktop_config.json file using the @modelcontextprotocol/server-sse transport command.
- Can Claude upload photos to CompanyCam?
- Yes. Using the create_a_company_cam_project_photo tool, Claude can attach photos to a project by passing a public image URI or a pre-uploaded binary upload_id.
- How does Truto handle CompanyCam API rate limits?
- Truto does not absorb or retry rate limits. If CompanyCam returns an HTTP 429, Truto passes the error to the caller and normalizes the rate limit headers. The caller must implement retry and backoff logic.
- Can I restrict Claude to read-only access for CompanyCam?
- Yes. When generating the MCP server in Truto, you can configure method filtering by passing ["read"] to the config.methods array, preventing the LLM from making any POST, PUT, or DELETE calls.