Skip to content

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.

Riya Sethi Riya Sethi · · 10 min read
Connect CompanyCam to Claude: Track Field Work and Documentation

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.

  1. Log into your Truto dashboard and navigate to the Integrated Accounts page.
  2. Select your connected CompanyCam account.
  3. Click the MCP Servers tab.
  4. Click Create MCP Server.
  5. 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.
  6. 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:

  1. Open Claude and navigate to Settings.
  2. Click on Integrations (or Connectors depending on your tier).
  3. Click Add MCP Server.
  4. Paste the Truto MCP URL (https://api.truto.one/mcp/...) into the Server URL field.
  5. Click Add. Claude will immediately send an initialize request 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:

  1. Claude calls list_all_company_cam_projects (searching by name "Oakwood Renovation") to retrieve the project_id.
  2. Claude calls create_a_company_cam_project_photo using the project_id, passing the public URL as the uri and setting the tag to "Progress".
  3. Claude calls create_a_company_cam_project_page using the project_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:

  1. Claude calls list_all_company_cam_projects to find the Downtown Office project_id.
  2. Claude calls list_all_company_cam_project_advanced_checklists to retrieve the checklist ID and the specific field_id for the HVAC Inspection.
  3. Claude calls update_a_company_cam_project_advanced_checklist_by_id passing the fields array to mark the specific field as failed.
  4. Claude calls create_a_company_cam_project_task to 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.methods array 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.tags array 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: true to require a valid Truto API token in the Authorization header, preventing anonymous access even if the MCP URL is leaked.
  • Automatic Expiry: Set an expires_at ISO 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.

More from our Blog