Skip to content

Releases: TylerIlunga/procore-mcp-server

v2.0.0 — 7-tool default surface and verb_noun naming

Choose a tag to compare

@TylerIlunga TylerIlunga released this 21 Aug 10:59
e3c9da2

Breaking changes

  • The default tool surface is now the 7 discovery tools. Set PROCORE_TOOL_MODE=all to restore the previous per-endpoint surface.
  • 836 generated tool names changed. data/tool-renames.json maps every old name to its current one.

Coverage is identical in both modes — procore_api_call reaches every Procore endpoint either way. Only the size of the advertised tool list differs.

Why the default changed

Registering one tool per endpoint emits roughly 4.7 MB (~1.2M tokens) of tool definitions, which exceeds every current model's context window. The old default wasn't merely inefficient — it couldn't work in a real client.

Filtering can't rescue it: the most aggressive structural filter (non-deprecated + non-peripheral + non-bulk + shallowest paths) still leaves 897 tools, because the Procore API genuinely has ~3,000 operations. So the fix is the lean mode that already existed, promoted to the default.

Consistent verb_noun naming

Procore's operation titles reach for whatever verb the doc author preferred — "List RFIs", "Show RFI", "Get All Equipment", "Retrieve Note" — so the same action wore six different verbs. Read synonyms now resolve to list_ or get_, chosen from the endpoint's actual response shape rather than from its prose, so the name is correct by construction and agrees with the description.

This also repaired 617 tools whose verb actively contradicted what they return (show_rfiget_rfi, get_all_equipment_categories_companylist_equipment_categories_company).

Verbs naming a distinct action — reorder, recycle, restore, sync, send, close, assign, and add/remove in their association sense — are deliberately preserved, since flattening them onto a CRUD prefix would reintroduce the name-vs-semantics bugs fixed in v1.3.0–v1.6.0.

Distinct leading verbs dropped 97 → 79; the five canonical CRUD verbs now cover 86% of the surface.

Also in this release

  • The 7 discovery tools were rewritten against all six tool-quality dimensions — including that the four discovery tools and procore_get_config read only the bundled catalog, so they make no Procore request, need no credentials, and cost no rate limit.
  • procore_api_call now carries destructiveHint: true, since a DELETE through it is genuinely reachable.
  • procore_set_config's key is a strict enum matching the handler's own allowlist.
  • Endpoints differing only by a narrowing parent id now get a for_<parent> suffix instead of an opaque _2. No numeric-suffix names remain.

v1.6.0 — Naming and truncation fixes

Choose a tag to compare

@TylerIlunga TylerIlunga released this 20 Aug 03:00
60f6b54

Naming and truncation fixes

Fourth pass, targeting Server Coherence complaints not covered by the prior three releases.

  • HTTP-verb-style names. Three tools carried a bare HTTP-method word as their OAS summary ("POST Company Role"), producing tool names like post_company_role/patch_company_role. Normalized to natural verbs at the source.
  • Cross-version sibling pairing. Filler articles ("a", "an", "the") no longer cause two names for the same operation to miss each other during version-sibling grouping.
  • All 6 remaining opaque numeric-suffix names fixed (create_timecard_entry_project_2, list_project_tools_2, ...) — the collision resolver now catches cascading renames instead of falling back to a bare digit, and a scopeless sibling in a scope-spanning family gets an explicit _unscoped label.
  • Multipart upload boilerplate removed from file-upload PATCH/PUT tools — they were incorrectly told to "send only the fields you intend to change."
  • Description truncation fixed — two independent truncation limits were fighting each other and severing a markdown file-format table mid-row on a schedule-file upload tool; both are now aligned, and the sentence-boundary rollback no longer mistakes an abbreviation ("e.g.") for the end of a sentence.

No breaking changes to tool names beyond the 3 HTTP-verb renames (post_company_rolecreate_company_role, patch_company_roleupdate_company_role) and the 6 numeric-suffix renames listed above.

v1.5.0 — Scalar-response and description-inheritance fixes

Choose a tag to compare

@TylerIlunga TylerIlunga released this 20 Aug 02:19
c9795a1

Scalar-response and description-inheritance fixes

Third pass, driven by re-checking the live Glama score page (which had not synced against v1.4.0 yet) against the tools it named, cross-referencing each against what's actually shipped.

  • Scalar/binary response false positive. A raw CSV export (type: "string", format: "binary") was classified as a JSON collection whenever Procore's spec happened to declare page/per_page on it. A file body can never be "a JSON array of records" — this is now an unconditional false, ahead of all pagination/text-signal override logic.
  • Description inheritance. Two classes of Procore's own OAS text turned out to be actively wrong: a GET endpoint described with a "Creates ..." leading verb (a real spec error), and a sub-resource action inheriting its base resource's description byte-for-byte (e.g. signature_requests vs signature_requests/{id}/signature, webhook hooks vs their triggers, project people vs the inactive-people variant). Both now fall back to the tool's own summary-driven synthesis instead of repeating the wrong text.
  • Article agreement. "Creates an new X" and "Retrieves an single X" both picked the article from the resource label instead of the inserted adjective — fixed at all three call sites (33 tools affected).

New verify-manifest.ts invariants guard both the article-agreement class and the GET-described-as-create class going forward.

No breaking changes to tool names in this release.

v1.4.0 — Collection-detection fixes and cross-version disambiguation

Choose a tag to compare

@TylerIlunga TylerIlunga released this 19 Aug 08:11
9698e25

Collection-detection fixes and cross-version disambiguation

Follow-up to v1.3.0. The Glama score page hadn't re-synced against that release yet, so this release was driven by auditing the live page directly and cross-referencing every stale D/C-tier tool against the shipped code — 130 of 131 were already resolved; the two remaining structural complaints (Disambiguation, Naming Consistency) hadn't been touched yet.

  • Collection detection, widened and hardened. Response schemas are now unwrapped more aggressively — any single-property object wrapping an array counts as an envelope, regardless of key name (Procore's v1.0 endpoints often envelope under the plural resource name, e.g. { exchange_rates: [...] }), allOf branches are merged into one schema before judging collection-ness (an allOf composes properties; it doesn't offer alternatives the way oneOf does, so one branch's optional array field shouldn't make the whole merged object look like a list), and a wildcard content-type schema is used when application/json isn't declared. Two genuine false positives surfaced and got fixed in the process: show_company_vendor and show_recycled_checklist_template declare page/per_page in Procore's own spec with no textual list signal behind it.
  • Cross-version disambiguation. 82 tools that carry out the same operation as a sibling tool at a different Procore API version — previously indistinguishable apart from a version-number suffix — now name their sibling(s) directly in the description.
  • A new verify-manifest.ts invariant guards against a bulk endpoint ever being paired as a "version sibling" of the single-record version of the same operation.

No breaking changes to tool names in this release.

v1.3.0 — Glama quality score fixes

Choose a tag to compare

@TylerIlunga TylerIlunga released this 19 Aug 06:28
6f4dbc2

Glama quality score fixes

Glama's overall quality score is 70% Tool Definition Quality + 30% Server Coherence, and the definition-quality half is 60% mean + 40% minimum across all ~2,900 generated tools — so a handful of badly-described tools were capping the whole catalog at a B. This release fixes the generator bugs behind those low scores.

  • Collection detection: returnsCollection now unwraps Procore's v2.x { data: [...] } response envelope and falls back to declared page/per_page params, instead of only recognizing a bare JSON array. 254 list endpoints were previously described as single-record fetches and denied pagination in their input schema.
  • Purpose synthesis: descriptions now derive from the operation's actual verb (reorder/recycle/assign/sync/upsert/restore/...) instead of a generic CRUD-by-HTTP-method template — a POST named reorder_company_role no longer reads "Creates a new company role", and recycle_* tools no longer claim an irreversible delete.
  • Resource labeling: fixed trailing-scope stripping that severed "Timesheet To Budget Configuration" down to "Timesheet"; fixed pluralization producing nonsense like "enableds"/"closeds"; fixed several typos in Procore's own OAS text.
  • Coherence: tool name collisions now resolve with meaning-bearing suffixes (scope, API version, distinguishing path segment, HTTP method) before falling back to opaque numbers — 217 tools renamed to something an agent can actually disambiguate by.
  • Added PROCORE_TOOL_MODE=meta to serve just the 7 discovery tools for context-constrained clients; the full API stays reachable through procore_api_call.
  • Added scripts/verify-manifest.ts (npm test), wired into CI, to catch regressions in these invariants on future spec refreshes.

Breaking change: ~217 tool names changed to resolve collisions more meaningfully (e.g. check_pdf_generation_status_project_v2_0_2check_pdf_generation_status_prime_change_order_batches). Update any saved prompts that reference the old names.

v1.2.0 — 2026-08-04 API spec + tool description rewrite

Choose a tag to compare

@TylerIlunga TylerIlunga released this 05 Aug 06:24
f7420de

Highlights

Refreshed to the 2026-08-04 Procore API spec

The bundled spec was four months stale (2026-03-26). Rebuilding against the current one adds 519 net operations and repairs a surface that had drifted out of sync with live Procore.

v1.1.0 v1.2.0
Operations in catalog 2,636 3,155
Registered tools 2,489 2,936 (2,929 generated + 7 meta)
Deprecated, flagged in-description 0 166 (92 with sunset dates)
Dead tools that would 404 26 0
  • Removed 26 tools whose endpoints no longer exist and returned 404 against live Procore — the entire Payments sub-surface (disbursements, beneficiaries, early pay programs, payment project configs), app_installations writes, and equipment_register project writes.
  • New modules registered: Assets, Materials Management, Estimating, Document Management, Document Markup.
  • Taxonomy corrections: Equipment and Telematics moved CoreResource Management; Direct Costs → Project Level Direct Costs. These feed both discovery and description text, so stale tags meant wrong routing.
  • Deprecated endpoints stay registered but now carry their sunset date in the description and a (Deprecated) title — nothing breaks before Procore's own removal dates.
  • The interactive /oauth/* endpoints are no longer registered as tools (npm run auth owns that flow) but remain reachable via procore_api_call.

Tool Definition Quality rewrite

Glama scored the server C on Tool Definition Quality. The score is 60% mean + 40% minimum, so the single worst-described tool carried 40% of the weight. Defect counts across all 2,929 generated tools:

Defect Before After
Ungrammatical <Module> records ~1,144 0
False "paginated JSON array" claims 165 0
DELETE repeating "cannot be undone" 325 0
Duplicate parameter keys 33 0
POST update_* claiming "Creates a new" 12 0
version: "unknown" 4 0
  • Descriptions name the real resource. They previously used the OAS category, so show_rounding_configuration read "a specific Field Productivity records" and delete_incident_alert_recipient claimed to delete "Incidents". The resource is now derived from the operation summary.
  • Pagination follows the response schema. The old heuristic matched any path ending in a lowercase segment, so 165 singleton GETs advertised a paginated array. returnsCollection is now computed from the OAS 2xx schema and gates both the description and the page/per_page input schema — the two can no longer disagree.
  • Every sentence has a distinct job — purpose, deprecation, usage and prerequisites, return shape and failure modes, required params, scope — with no restatement. Descriptions now name which parent ids to resolve first and which default from procore_set_config.
  • Synthesized behavior text stays neutral when Procore's own prose already documents status codes, so generated text cannot contradict the documented contract.

Bug fixes

  • 33 tools declared the same key twice (path + body, e.g. company_id on create_permission_template). The body field silently overwrote the path parameter in the generated Zod shape, so agents saw the wrong description for a required path param. Parameters are now deduped with path precedence plus an alsoBody flag that still sends the value in the payload.
  • Appending a disambiguating suffix before truncating could discard the suffix and reintroduce the very name collision it was meant to break.
  • PATCH is now marked idempotent — a partial update converges on the same state.

Internal

description-builder.ts was split into resource-label.ts, behavior-builder.ts and param-descriptions.ts to stay under the repo's 300-line file limit.

Tool count: 2,482 → 2,929 (plus 7 meta-tools)

Verification

  • npm run build and npm run validate pass; TypeScript compiles clean.
  • Server boots over real MCP with 2,936 tools: zero duplicate names, zero missing annotations or titles, zero names over 64 chars, zero descriptions under 150 chars.

Commits

  • f7420de feat: refresh to 2026-08-04 OAS and rebuild tool descriptions (#2)
  • be847c6 Updated Glama card badge

Full changelog: v1.1.0...v1.2.0

v1.1.0 — Cross-platform auth + tool surface cleanup

Choose a tag to compare

@TylerIlunga TylerIlunga released this 08 May 17:09

Highlights

Cross-platform OAuth flow

npm run auth now opens the browser correctly on Windows and Linux, not just macOS. Fixes a silent 5-minute timeout that affected every non-macOS user.
Thanks to @aprotteau-dac for the contribution (#1).

Tool Definition Quality lift

Every one of the 2,482 tools now registers through the SDK's registerTool() API with:

  • title — Title-Case display name (e.g. "Add Tag Instance to Person")
  • annotationsreadOnlyHint, destructiveHint, idempotentHint, openWorldHint derived from HTTP method + name patterns
  • Multi-section description (purpose, when-to-use, behavioral context, required params, category/module, endpoint)
  • Source-prefixed parameter docs ("URL path parameter — …", "Query string parameter — …", "JSON request body field — …")

Surface coherence cleanup

Dropped 154 deprecated older-version duplicate tools. Manifest generation now groups endpoints by (method, path with version segment normalized) and keeps only the highest version, so e.g. create_company_user_v1_0 / _v1_1 / _v1_2 collapse to a single create_company_user (v1.3). Genuinely distinct endpoints with overlapping summaries are preserved untouched. Removed endpoints remain reachable via procore_api_call.

Tool count: 2,636 → 2,482

Commits

  • eed7a84 fix(coherence): drop deprecated older-version duplicate tools
  • 9b1d389 docs: remove Glama card badge from README
  • 2eab7dc fix(tdqs): switch all tools to registerTool with title and annotations
  • 07efc94 fix(auth): open browser cross-platform on Windows and Linux (#1)

Full changelog: v1.0.0...v1.1.0

v1.0.0

Choose a tag to compare

@TylerIlunga TylerIlunga released this 13 Apr 20:03

Initial release of Procore MCP Server.

MCP server exposing the full Procore REST API (2,636 endpoints) for Claude Desktop, Claude Code, and MCP-compatible clients.

Features

  • 7 meta-tools for endpoint discovery and API execution
  • Build-time OpenAPI spec parser generating compact catalog
  • Single-user OAuth with auto-refresh
  • Rate limiting, retries, and pagination handling