Skip to content

Connect Procore to Claude: Control Daily Logs, Crews, and Project Webhooks

Learn how to connect Procore to Claude using Truto's managed MCP server. A technical guide to automating RFIs, project webhooks, and construction crews.

Roopendra Talekar Roopendra Talekar · · 10 min read

If your team uses ChatGPT, check out our guide on connecting Procore to ChatGPT or explore our broader architectural overview on connecting Procore to AI Agents.

If you need to connect Procore to Claude to automate RFIs, orchestrate project webhooks, or manage construction crews and daily logs, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's LLM tool calls and Procore's complex REST APIs. 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.

Giving a Large Language Model (LLM) read and write access to a sprawling construction management ecosystem like Procore is an engineering challenge. You have to handle OAuth 2.0 token lifecycles, map massive JSON schemas to MCP tool definitions, and deal with Procore's strict API quotas and complex project-scoping rules. Every time Procore updates an endpoint or deprecates a resource, 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 Procore, connect it natively to Claude, and execute complex construction management workflows using natural language.

The Engineering Reality of the Procore 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. Procore is built to manage massive construction projects, intricate budgets, and multi-tiered contractor relationships. Its API reflects that complexity.

If you decide to build a custom Procore MCP server, here are the specific integration challenges you will face:

Multiple Procore Zones (MPZ) and Dynamic Routing Unlike most SaaS APIs that have a single base URL (e.g., api.github.com), Procore isolates customer data across multiple geographic and infrastructure zones. A company might be hosted on us02.procore.com while another is on a completely different base URL. Your MCP server cannot hardcode the API endpoint. It must first authenticate, query the MPZ endpoint to determine the correct routing zone for the specific company, and dynamically rewrite the base URL for all subsequent requests. Truto handles this base URL resolution natively via its proxy API layer.

Strict Company and Project Scoping Procore's API enforces strict hierarchical scoping. You almost never query "all RFIs." Instead, virtually every operational endpoint requires a project_id, and many administrative endpoints require a company_id. Furthermore, the API often expects specific custom headers like Procore-Company-Id to accompany requests. An LLM cannot simply guess these hierarchical relationships. Your MCP server must present tools that explicitly enforce these requirements in their input schemas, ensuring Claude always provides the necessary context before attempting a mutation.

Rate Limits and 429 Handling Procore enforces rate limits to ensure platform stability. When building an MCP server, you must decide how to handle HTTP 429 Too Many Requests. Truto does not retry, throttle, or apply backoff on rate limit errors automatically. Instead, when Procore returns a 429, Truto passes that error to the caller, normalizing the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. The MCP client (or the LLM agent framework) is responsible for reading these headers and executing its own backoff strategy.

Step 1: Generating the Managed Procore MCP Server

Instead of writing custom Node.js or Python code to handle Procore's MPZ routing, OAuth refresh tokens, and schema mapping, you can use Truto to generate an MCP server dynamically.

Truto derives MCP tool definitions directly from its internal documentation records and config.resources. A tool only appears in the MCP server if it has a corresponding documentation entry - acting as a strict quality gate to ensure only well-documented endpoints are exposed to the LLM.

You can create the MCP server in two ways: via the Truto UI or programmatically via the API.

Method 1: Via the Truto UI

For quick setups and testing, the dashboard is the fastest route:

  1. Log into your Truto account and navigate to the Integrated Accounts page.
  2. Select your active Procore connection.
  3. Click the MCP Servers tab.
  4. Click Create MCP Server.
  5. Select your desired configuration (name, method filters like read or write, tag filters, and expiration).
  6. Copy the generated MCP server URL. It will look like https://api.truto.one/mcp/a1b2c3d4....

Method 2: Via the Truto API

For programmatic provisioning (e.g., generating temporary MCP servers for AI agents in your own application), use the Truto API. This endpoint validates that the integration has tools available, generates a secure hashed token stored in Cloudflare KV, 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_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Procore Agent Server",
    "config": {
      "methods": ["read", "write"],
      "tags": ["project_management", "core"]
    },
    "expires_at": "2026-12-31T23:59:59Z"
  }'

The response will contain the authenticated URL required by Claude:

{
  "id": "abc-123",
  "name": "Procore Agent Server",
  "config": {
    "methods": ["read", "write"],
    "tags": ["project_management", "core"]
  },
  "expires_at": "2026-12-31T23:59:59Z",
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}

Step 2: Connecting the MCP Server to Claude

Once you have the Truto MCP URL, you need to register it with your AI client. The server is fully self-contained - the URL contains a cryptographic token that encodes the account, tools, and authentication. No additional setup is required.

Method 1: Via the Claude UI

If you are using a UI-based client that supports remote MCP connections (like Claude Desktop or ChatGPT):

  1. In Claude Desktop, go to Settings -> Integrations -> Add MCP Server.
  2. In ChatGPT, go to Settings -> Apps -> Advanced settings -> Developer mode -> Custom connectors.
  3. Paste the Truto MCP URL (https://api.truto.one/mcp/...).
  4. Click Add or Save. The client will immediately perform a handshake, send an initialize JSON-RPC request, and fetch the available Procore tools.

Method 2: Via Manual Configuration File

If you are configuring Claude Desktop manually via its configuration file, you must use the official Server-Sent Events (SSE) transport wrapper, as Claude Desktop currently expects local stdio execution by default.

Edit your claude_desktop_config.json file:

{
  "mcpServers": {
    "procore-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/YOUR_TRUTO_TOKEN"
      ]
    }
  }
}

Restart Claude Desktop. The application will use the npx wrapper to connect to the remote Truto SSE endpoint, exposing all Procore tools natively in the chat interface.

Security and Access Control

Giving an LLM unconstrained access to a live construction management system is incredibly dangerous. An LLM hallucination could result in deleting project crews or modifying locked budgets. Truto's MCP tokens include native governance controls at the server level:

  • Method Filtering (config.methods): Restrict an MCP server to specific operation types. Setting this to ["read"] limits the LLM to get and list operations, physically preventing it from creating or updating records.
  • Tag Filtering (config.tags): Scope access to specific functional areas. For example, setting tags to ["rfis", "daily_logs"] ensures the LLM cannot even see the tools related to budgets or payroll.
  • Extra Authentication (require_api_token_auth): When set to true, the MCP URL alone is not enough. The caller must also pass a valid Truto API token in the Authorization header. This is critical for zero-trust environments where URLs might be exposed in logs.
  • Automatic Expiration (expires_at): Truto enforces time-to-live via Cloudflare KV expirations and Durable Object cleanup alarms. Creating an MCP server with a 24-hour expiration ensures that short-lived AI agents do not leave behind persistent backdoor access to Procore.

Procore Hero Tools for Claude

When Claude lists the tools available on your Procore MCP server, it receives dynamically generated schemas based on Procore's API documentation. Truto merges query parameters and request bodies into a single, flat input namespace for the LLM, making it incredibly simple for Claude to reason about the required inputs.

Here are six high-leverage hero tools that transform Claude into a capable construction management agent.

List All Procore Company Projects

This is the foundational tool. Because almost all Procore endpoints require a project_id, the LLM must call this tool first to map human-readable project names (e.g., "Downtown Highrise") to their internal integer IDs.

  • MCP Tool Name: list_all_procore_company_projects
  • Required Inputs: company_id
  • Returns: A list of project objects including id, name, project_number, and stage_name.

"Find the project ID for the 'Downtown Highrise' project under our primary company ID 8472."

List All Procore RFIs

Retrieves the Requests for Information (RFIs) for a specific project. This tool supports rich filtering via query parameters, allowing the LLM to find overdue RFIs or RFIs assigned to specific users.

  • MCP Tool Name: list_all_procore_rfis
  • Required Inputs: project_id
  • Returns: Detailed RFI records including id, subject, number, status, and assignees.

"List all overdue RFIs for the Downtown Highrise project. Summarize the subjects and who is currently holding the ball in court."

Update a Procore RFI Reply by ID

Allows the LLM to modify an existing response on an RFI. This is crucial for agents tasked with cleaning up draft replies, adding official attachments, or finalizing the answer text based on new documentation.

  • MCP Tool Name: update_a_procore_rfi_reply_by_id
  • Required Inputs: project_id, rfi_id, id (the reply ID), and the payload.
  • Returns: The updated reply object.

"Update the reply with ID 992 on RFI #42 for the Highrise project. Change the text to state that the structural beam spec is approved as per the architect's latest drawings, and mark it as the official answer."

List All Procore Crews

Retrieves the workforce configuration for a specific project. This tool returns the crews, their leads, and the equipment assigned to them, which is essential for resource planning workflows.

  • MCP Tool Name: list_all_procore_crews
  • Required Inputs: project_id
  • Returns: Crew records including id, name, lead_party_id, and equipment_ids.

"Show me all the crews currently active on the Highrise project, and list the names of the crew leads."

Create a Procore Punch Item

Allows the LLM to programmatically log safety or quality issues on the job site. The LLM can extract deficiencies from daily reports or field notes and turn them into actionable punch list items in Procore.

  • MCP Tool Name: create_a_procore_punch_item
  • Required Inputs: project_id, name (inside the punch_item body object).
  • Returns: The created punch item record.

"Create a new punch item for the Highrise project. The issue is 'Exposed wiring near stairwell B on level 4'. Set the priority to High and the due date for tomorrow."

Create a Procore Project Webhook Hook

Enables the LLM to configure event-driven integrations. If an agent determines that a new external system needs real-time updates when an RFI changes, it can use this tool to register the webhook destination with Procore.

  • MCP Tool Name: create_a_procore_project_webhook_hook
  • Required Inputs: company_id, project_id, api_version, destination_url.
  • Returns: The created webhook hook configuration.

"Register a new webhook for the Highrise project. Set the destination URL to 'https://api.mycompany.com/webhooks/procore' and use API version v2."

To view the complete inventory of Procore tools, schemas, and required parameters, visit the Truto Procore integration page.

Workflows in Action

Connecting Procore to Claude via an MCP server turns a chat interface into a powerful operational command center. Here is exactly how Claude handles complex, multi-step workflows using the tools described above.

Scenario 1: The Site Superintendent's Daily RFI Triage

A superintendent needs to quickly assess the status of critical questions blocking construction and draft a reply to an urgent structural issue.

"Find the project ID for 'Downtown Highrise' (company ID 102). Then, list all open RFIs. For the RFI regarding 'Elevator Shaft Framing', draft a reply stating that the framing dimensions have been approved by the structural engineer, and update the reply record in the system."

Execution Steps:

  1. Claude calls list_all_procore_company_projects with { company_id: 102 } to retrieve the project list and identifies the ID for "Downtown Highrise" (e.g., 4059).
  2. Claude calls list_all_procore_rfis with { project_id: 4059 } and applies filters for open status. It scans the returned JSON to find the ID for the "Elevator Shaft Framing" RFI (e.g., rfi_id: 882).
  3. Claude calls list_all_procore_rfi_replies to find the specific draft reply ID that needs updating.
  4. Claude formulates the payload and calls update_a_procore_rfi_reply_by_id, passing the required IDs and the new plain_text_body.
sequenceDiagram
    participant Claude as "Claude Desktop"
    participant Truto as "Truto MCP Router"
    participant Procore as "Procore API"

    Claude->>Truto: tools/call list_all_procore_company_projects<br>{company_id: 102}
    Truto->>Procore: GET /projects
    Procore-->>Truto: Project List
    Truto-->>Claude: Result: Project ID 4059
    
    Claude->>Truto: tools/call list_all_procore_rfis<br>{project_id: 4059, status: "open"}
    Truto->>Procore: GET /rfis
    Procore-->>Truto: RFI List
    Truto-->>Claude: Result: RFI ID 882

    Claude->>Truto: tools/call update_a_procore_rfi_reply_by_id<br>{project_id: 4059, rfi_id: 882...}
    Truto->>Procore: PATCH /rfi_replies/id
    Procore-->>Truto: Updated Reply
    Truto-->>Claude: Success Confirmation

Scenario 2: Project Manager Logging Deficiencies

A Project Manager finishes a site walk and uploads a raw text note detailing several quality issues. They want Claude to translate these notes into formal Procore Punch Items.

"I just walked the Highrise site (project ID 4059). I noticed the drywall in unit 402 is cracked, and the paint in the lobby is peeling. Create two separate punch items for these issues, and list the active crews on the project so I know who to assign them to later."

Execution Steps:

  1. Claude parses the natural language request and isolates the two distinct issues.
  2. Claude calls create_a_procore_punch_item with { project_id: 4059, punch_item: { name: "Drywall cracked in unit 402" } }.
  3. Claude calls create_a_procore_punch_item a second time with { project_id: 4059, punch_item: { name: "Paint peeling in lobby" } }.
  4. Claude calls list_all_procore_crews with { project_id: 4059 } to retrieve the current workforce data.
  5. Claude synthesizes the results, confirming the creation of the two punch items and listing the available crews to the user.

Strategic Wrap-Up

Building a custom integration layer for Procore is a significant operational burden. Between managing OAuth 2.0 refresh cycles, navigating the MPZ base URL routing, and normalizing heavily nested pagination structures, a custom build quickly drains engineering resources.

By leveraging Truto's managed MCP architecture, you shift that operational burden to the infrastructure layer. Truto handles the authentication state, dynamically derives clean JSON Schema inputs from documentation, and provides a secure, zero-data-retention proxy straight to Procore. This allows your team to focus entirely on building high-value AI agent workflows, rather than fighting with the realities of enterprise construction APIs.

FAQ

How does Truto handle Procore API rate limits?
Truto does not automatically retry or backoff on Procore rate limits. When Procore returns an HTTP 429 error, Truto passes it directly to the MCP client, standardizing the rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The caller is responsible for implementing retry logic.
Do I need to hardcode Procore base URLs for different companies?
No. Procore uses Multiple Procore Zones (MPZ), meaning different companies have different base API URLs. Truto handles this base URL resolution dynamically through its proxy API, ensuring requests route to the correct zone automatically.
Can I prevent Claude from deleting Procore project data?
Yes. When you generate the MCP server in Truto, you can use method filtering (e.g., config.methods: ['read']) to strictly limit the server to GET and LIST operations, physically blocking the LLM from executing mutations.
What authentication does the Truto MCP server use?
The MCP URL itself contains a secure, hashed cryptographic token for authentication. For higher security, you can enable require_api_token_auth, which forces the client to also provide a valid Truto API key in the Authorization header.

More from our Blog