Created by Vladimir Kamenev · for demonstration purposes View the codebase on GitHub →
● LEGAL-DOCS MCP Model Context Protocol · deployed on Cloudflare

Legal documents, synced between Procore and Salesforce.

Conduit is an agent-native MCP server that mirrors every contract, insurance certificate, lien waiver and compliance record from Procore into Salesforce — and keeps projects, financials and contacts in bidirectional sync too. One secure connection; your AI agent acts across both systems.

187 tests
99% line coverage
<5s
webhook ACK
OAuth 2.1
PKCE · S256
2 systems
1 protocol
// live data bridge
PROCORE
legal docs · financials
projects · RFIs
MCP
CONDUIT
broker
dedup · map · upsert
SALESFORCE
accounts · opps
contacts · custom
// interactive · runs in your browser

See the whole system working — live.

Click any scenario. Watch the broker fetch, deduplicate, field-map and upsert across both systems, step by step. Health and OAuth checks hit the real deployed Worker; sync scenarios animate the exact logic that ships in the codebase. The Advanced row walks through the full MCP protocol surface — prompts & autocomplete, elicitation, sampling, tasks, and SSE streaming — each labeled with its spec method and revision.

conduit · live test console idle
Legal documents — the headline capability
Core sync & live checks
Advanced MCP capabilities — the full protocol surface
› Select a scenario above to begin. Output streams here in real time.
Procore
webhook
dedup
map
Salesforce
Pipeline steps will appear here.
RESULT
Awaiting run…
// architecture in one idea

Two planes. One server.

MCP tool calls are instant and agent-driven; durable sync needs a queue, dedup and a scheduler. Conduit splits cleanly so each does what it's best at — a design grounded in primary-source research of the MCP spec and Procore's webhook contract.

Agent plane

Tools an AI calls on demand

  • sync_procore_project_to_salesforcefetch → map → upsert
  • run_reconciliationdelta sweep
  • create_procore_webhooktwo-tier hook+trigger
  • Resources — read-only object context (config://mappings)
  • Prompts — guided workflows (audit_unmapped_records)
Sync plane

Durable background reconciliation

  • Inbound webhooksACK <5s, process async
  • Idempotencydedup by event id (ULID)
  • Field mappingbidirectional registry
  • Upsert by External IDsafe replays
  • Cron backstop*/30 reconcile sweep
// engineering you can trust

Built for the parts that actually break.

Dual-provider OAuth, at-least-once webhooks, governor limits, conflict resolution — the hard problems are solved up front, not patched in production.

Dual-token OAuth broker

The server issues its own bound MCP token, then brokers and refreshes both Procore and Salesforce tokens per tenant via a token-exchange callback — no API keys ever shared with the agent.

OAuth 2.1PKCE / S256per-tenant

Webhook-grade reliability

Procore delivers at-least-once with a 5-second timeout. Conduit ACKs instantly, deduplicates by event id, and reconciles out of band — so replay storms become no-ops, never duplicates.

at-least-oncededupidempotent

Rate-limit aware

Every outbound call honors Retry-After with exponential backoff, respecting Procore's hourly limits and Salesforce's daily governor limits under load.

backoff429-safeBulk API 2.0

Conflict resolution

When both sides edit the same record, a pluggable policy decides — last-write-wins, source-of-truth-per-field, or escalate for human review. Your ownership model, your rules.

configurableno silent loss

Edge-native

Runs on Cloudflare Workers with a Durable Object per session for stateful, multi-tenant sync, KV-backed token + dedup storage, and a cron-driven reconciliation backstop.

WorkersDurable ObjectsKV

Verifiably correct

187 unit + integration tests at ~99% line coverage, including a real MCP client driving the server end-to-end and a webhook replay-storm test. The build is green before it ships.

Vitest85% gateCI-ready
// the canonical map

Every object, mapped both ways.

Legal documents lead the model — contracts, insurance certificates, lien waivers and compliance records sync bidirectionally: Procore is the document system of record, while legal/CRM edits in Salesforce (status, approval outcomes) flow back to Procore. Master data also syncs both ways; financials and PM records flow into the CRM for reporting. Each mapping is anchored by a Salesforce External ID for idempotent upserts.

ProcoreDirectionSalesforceMatch key
Company / Vendor⇄ biAccountProcore_Company_Id__c
Project⇄ biProcore_Project__cProcore_Project_Id__c
Directory Contact / User⇄ biContactProcore_Contact_Id__c
★ Legal documents — featured · bidirectional
Contract Document⇄ biProcore_Contract_Document__cProcore_Id__c
Insurance Certificate⇄ biProcore_Insurance_Certificate__cProcore_Id__c
Lien Waiver⇄ biProcore_Lien_Waiver__cProcore_Id__c
Compliance Document⇄ biProcore_Compliance_Document__cProcore_Id__c
Financial documents
Prime Contract→ to SFProcore_Prime_Contract__cProcore_Id__c
Commitment / Change Order→ to SFProcore_Commitment__cProcore_Id__c
RFI→ to SFProcore_RFI__cProcore_Id__c
Submittal→ to SFProcore_Submittal__cProcore_Id__c
// why teams choose conduit

The integration that pays for itself.

Legal docs, always in the CRM

Every executed contract, insurance certificate, lien waiver and compliance record is mirrored into Salesforce — your legal and sales teams query one source of truth.

Agent-ready today

Any MCP client — Claude included — connects with one OAuth flow and can read and act across both platforms safely.

Audit-friendly

Soft-deletes preserve CRM history, idempotent writes prevent duplicates, and every sync is traceable by external id.

Yours to own

Self-hostable on your Cloudflare account, no per-seat SaaS tax, and the mapping + conflict policy are fully configurable.

// connect in minutes

Get started.

Conduit is a standards-compliant remote MCP server. Point any MCP client at the endpoint and complete the OAuth handshake — discovery is automatic.

GET/healthzliveness
POST/mcpStreamable HTTP · OAuth-gated
POST/webhooks/procoreinbound events
GET/.well-known/oauth-authorization-serverdiscovery
Live at procore.degenito.ai
# 1 · Add Conduit to your MCP client config { "mcpServers": { "conduit": { "url": "https://procore.degenito.ai/mcp", "transport": "streamable-http" } } } # 2 · The client discovers OAuth & runs the PKCE flow # 3 · Conduit brokers Procore + Salesforce tokens for you # 4 · Tools are now callable by your agent ✓
// how to use it

Connect a real agent, then put it to work.

Conduit isn't a closed app — it's an endpoint your own AI client connects to. Add it once, approve the secure login, and your agent instantly gains eighteen Procore ⇄ Salesforce capabilities. Here's the whole flow, end to end.

Step by step Add Conduit to Claude Desktop

  1. 1Open Claude Desktop → Settings → Connectors.Any MCP-capable client works the same way — Claude Code, Cursor, or an IDE extension. The connector model is identical.
  2. 2Choose Add custom connector and paste the Conduit endpoint: https://procore.degenito.ai/mcp This is the live, deployed Worker — the exact server backing this page.
  3. 3Approve the secure sign-in when the client opens it.Conduit runs a standards-compliant OAuth 2.1 + PKCE handshake — the real /authorize/token flow. Your agent receives a scoped, bound token; raw credentials are never exposed to it.
  4. 4Your agent discovers all eighteen tools automatically.Ask it to “list your available tools” and it will enumerate the catalog on the right — no manual configuration.
What's live right now Verified

The endpoint is deployed and healthy. The connection, OAuth handshake, and tool discovery are fully real — connect a client during your demo and the eighteen tools appear, proving Conduit is a genuine, standards-compliant MCP server.

GET /healthz → 200  ·  POST /mcp → 401 until you sign in

For the demo conversation Good to know

Wiring each customer's own Procore & Salesforce OAuth apps is the next phase, so when presenting:

  • Do show the connect flow, the OAuth sign-in, and the agent listing all eighteen tools.
  • Do walk the live Health and OAuth discovery scenarios in the console above.
  • Hold on triggering a live data pull — narrate the tool surface instead of fetching real records until the customer's org is connected.

The eighteen tools your agent gets

§Legal document operationsSalesforce-native6 tools · api scope
  • upload_contract_fileUpload a signed document (PDF/DOCX) into Salesforce Files and attach it to a Contract or synced record — REST multipart; practical ~20 MB (buffered in the Worker).
  • get_contractRead a Salesforce Contract record by id.
  • list_contracts_by_statusQuery Contracts by Status (Draft, Activated, InApproval…) via SOQL.
  • submit_for_approvalRoute a record into its native Salesforce approval process.
  • list_approval_processesList the org's approval processes, keyed by object.
  • check_signature_statusRead DocuSign envelope status from the eSignature managed package (degrades gracefully if not installed).

All six run on the api OAuth scope Conduit already uses — no add-on required. Grounded in primary Salesforce docs (ContentVersion multipart, Process Approvals REST, Contract SOQL).

Read & look up2 tools
  • list_procore_projectsList the customer's Procore projects.
  • summarize_projectA natural-language summary of a project's status.
Synccore value4 tools
  • sync_procore_project_to_salesforcePush a project into Salesforce as an opportunity / account.
  • sync_salesforce_to_procoreThe reverse direction — Salesforce changes flow back to Procore.
  • sync_procore_financialsKeep budget and cost figures aligned across both systems.
  • run_reconciliationThe “catch-up sweep” that fixes any drift between the two systems.
Workflow automation4 tools
  • create_salesforce_case_from_rfiTurn a Procore RFI into a Salesforce support case.
  • dedupe_contactsFind & merge duplicate people across both systems.
  • create_procore_webhookWire up the automatic, real-time sync.
  • resolve_sync_conflictHandle “both sides edited the same record” cleanly.
Setup1 tool
  • authorize_salesforceConnect the customer's Salesforce org.

Tip: a one-time setup step the customer runs first — after that, the read, sync and workflow tools act on their behalf.

// where this stands · v0.7.0

What's real, what's best-effort, what's next.

Straight talk so you can trust the demo. The server is built, deployed and heavily tested; a few things are deliberately tuned per-org or staged for a later phase. Nothing here is hidden.

Live & real today

  • 18 MCP tools, auto-discovered over one OAuth 2.1 + PKCE connection
  • Bidirectional sync engine — Procore ⇄ Salesforce, idempotent upsert-by-External-Id
  • Legal documents featured + Salesforce-native ops (file upload, contracts, approvals, e-sign status)
  • Strongly-consistent dedup + link via a Durable Object (serialized RMW; no KV race)
  • Reverse-create write-back stamps the new Procore id onto Salesforce → idempotent, no duplicates
  • 187 tests · ~99% line / 85%+ branch coverage · typecheck + lint clean
  • Deployed on Cloudflare Workers; webhook fails closed without a signing secret

Best-effort — tune for your org

  • Reverse (SF→Procore) writes are last-write-wins; conflict.ts is a configurable seam, not yet enforced
  • Echo suppression is heuristic — Salesforce CDC sends partial payloads; production uses changeOrigin
  • DELETE is never propagated SF→Procore (Procore is the system of record)
  • File upload practical limit ~20 MB (buffered in the Worker)

Hardening priorities are research-backed (bidirectional-sync conflict strategies, Salesforce CDC delivery semantics, Cloudflare KV vs Durable Object consistency) and tracked in SPEC §8a and the CHANGELOG.

// deployed on cloudflare's edge

Runs on Workers. Stateful where it matters.

Conduit ships as a single Worker that combines an OAuth 2.1 authorization server, a per-session Durable Object for stateful sync, KV storage for tokens and dedup, a cron reconciliation trigger, and static assets — all behind one global edge URL with sub-100ms cold starts.

Workers runtime

V8 isolates at the edge, nodejs_compat enabled. Observed ~65ms startup, 324 KB gzip bundle. Observability (Workers Logs) turned on.

compatibility_date 2025-05-01edge

Durable Object per session

The McpAgent binds to a SQLite-backed Durable Object (ProcoreSalesforceMCP, migration tag v1) — one instance per MCP session for isolated, multi-tenant sync state.

McpAgentSQLite DO

KV storage

OAUTH_KV holds grants & brokered provider tokens; DEDUP_KV holds webhook event ids with a TTL so replays are no-ops across the fleet.

OAUTH_KVDEDUP_KV
🔐

OAuth provider

@cloudflare/workers-oauth-provider fronts the Worker: OAuth 2.1 + PKCE (S256), /authorize · /token · /register, RFC-8414 discovery, and a token-exchange callback that brokers both upstream providers.

PKCE S256RFC 8414

Cron reconciliation

A scheduled trigger (*/30 * * * *) runs a delta sweep as a backstop — catching any webhook drops, since at-least-once delivery is not exactly-once.

Cron Triggersself-healing

Secrets & assets

Client secrets and the AES-256-GCM token key are set via wrangler secret put (never committed). The GUI you're reading is served from the Worker [assets] binding.

wrangler secret[assets]
# wrangler.toml — the deployment topology name = "procore-salesforce-mcp" main = "src/worker/index.ts" compatibility_flags = ["nodejs_compat"] [[durable_objects.bindings]] # per-session state name = "MCP_OBJECT" class_name = "ProcoreSalesforceMCP" [[kv_namespaces]] binding="OAUTH_KV" # grants+tokens [[kv_namespaces]] binding="DEDUP_KV" # idempotency [triggers] crons = ["*/30 * * * *"] # backstop [assets] directory = "./public" # this GUI
# Provision once, then ship $ wrangler login # vlad@degenito.ai $ wrangler kv namespace create OAUTH_KV $ wrangler kv namespace create DEDUP_KV # Secrets (never in git) $ wrangler secret put PROCORE_CLIENT_SECRET $ wrangler secret put SF_CLIENT_SECRET $ wrangler secret put SF_JWT_PRIVATE_KEY $ wrangler secret put RS_TOKENS_ENC_KEY # AES-256-GCM # Validate the bundle, then deploy globally $ wrangler deploy --dry-run --outdir /tmp/build $ npm run worker:deploy → procore.degenito.ai ✓
// for developers

Connect it. Call it. Extend it.

Conduit is a standards-compliant remote MCP server, so any MCP-capable client or agent framework works out of the box. Reads are Resources, actions are Tools, and the whole thing is open to extension in a few lines.

① Call a tool from an agent

After the OAuth handshake, any MCP client lists and invokes tools. Conduit brokers the Procore + Salesforce calls for you.

// MCP client (TypeScript SDK) const res = await client.callTool({ name: "sync_procore_project_to_salesforce", arguments: { projectId: 4821 } }) // → { status: "synced", detail: "Projects#4821" } await client.callTool({ name: "run_reconciliation", arguments: { scope: "projects" } })

② Run it locally

Two entrypoints share one codebase — develop on Node, deploy to Workers. Both speak Streamable HTTP.

$ npm install $ npm run dev # Node server :8788 $ npm run worker:dev # Workers (wrangler) $ npm run typecheck # node + worker targets $ npm test # 187 tests $ npm run test:coverage # enforced gates

Add a mapping

Append one object to the MAPPINGS registry — resource name, SF object, External-ID field, direction, fields. The sync engine and tools pick it up automatically.

Add a tool

Register a new MCP tool in mcp/server.ts with a Zod input schema; it's instantly callable by every connected agent, with validation handled for you.

Own the conflict policy

Implement resolveConflict() in sync/conflict.ts to match your data-ownership model — last-write-wins, field-level source-of-truth, or human review.

// what was built

From research to a live, tested deployment.

This wasn't vibe-coded. It started with a multi-source, adversarially fact-checked research pass on the MCP spec, Procore's webhook contract, and Cloudflare's hosting stack — then a written spec, a layered implementation, a full test suite, and a global deploy.

Process

How it came together

  • Deep research24 verified claims, primary sources
  • Spec — architecture, mapping, auth, roadmap (SPEC.md)
  • Phase 0 build — clients, mapping, sync engine, MCP surface
  • Tests187 passing · ~99% lines
  • Deploy — Cloudflare Workers + this GUI, verified live
Codebase

Module map

  • config.tsvalidated env (Zod)
  • clients/Procore + Salesforce + retry/backoff HTTP
  • mapping/bidirectional field registry
  • sync/engine · dedup · conflict
  • mcp/ + worker/ + node/MCP surface + dual targets
// technology stack

What it's built with.

A modern, type-safe, edge-native stack — every layer chosen for correctness, security, and operability. Nothing exotic, nothing legacy.

Language & runtime

  • TypeScript — strict mode, end-to-end type safety
  • Node.js 20+ — local dev & self-host target
  • Cloudflare Workers — V8 isolates at the edge
  • Streamable HTTP — the MCP remote transport

Protocol & SDKs

  • Model Context Protocol@modelcontextprotocol/sdk
  • Cloudflare Agents SDKMcpAgent
  • Hono — HTTP routing (Node + Workers)
  • Zod — schema validation

Cloudflare platform

  • Durable Objects — SQLite-backed, per-session state
  • Workers KV — token + dedup storage
  • Cron Triggers — scheduled reconciliation
  • Static Assets — serves this site
🔐

Auth & security

  • workers-oauth-provider — OAuth 2.1 + PKCE
  • AES-256-GCM — token encryption at rest
  • RFC 8414 / 9728 / 7591 — OAuth discovery & DCR

Tooling & build

  • Wrangler — Workers build & deploy
  • tsx — fast TS execution in dev
  • npm — package & script management

Quality & testing

  • Vitest + @vitest/coverage-v8 — 187 tests
  • ESLint + typescript-eslint — linting
  • eslint-plugin-security + Semgrep — SAST
  • npm audit — SCA (0 vulns)

Front-end of this page: hand-written HTML/CSS/JS (no framework), typeset in Bricolage Grotesque, Hanken Grotesk & IBM Plex Mono. Integrates the Procore REST & Webhooks APIs and Salesforce REST / Bulk API 2.0 / Change Data Capture.

// engineering best practices

The standards baked in.

Every decision favored correctness, security, and operability over shortcuts. Here's what's enforced in the code, not just promised.

Idempotent by design

Upsert-by-External-ID + event dedup mean every write is replay-safe. No duplicates, ever.

OAuth 2.1 + PKCE

The server issues its own bound token and brokers provider tokens — agents never touch raw API keys.

Fail-fast config

Zod validates all env at boot, so a misconfigured deploy errors loudly instead of throwing opaque 401s later.

Strict TypeScript

noUncheckedIndexedAccess & friends — the compiler catches the bugs before runtime does.

Backoff & rate-limit aware

All outbound calls honor Retry-After with exponential backoff for 429s and 5xx.

No silent data loss

Conflicts resolve via explicit policy; deletes soft-delete to preserve CRM history.

Tested to ~99%

Unit + real MCP client integration + webhook replay-storm tests, with coverage gates in CI.

Secure transport

Origin validation & DNS-rebinding protection on the MCP endpoint, per the spec's MUST.

Separation of concerns

Agent plane vs sync plane; client / mapping / engine layers — each independently testable.

Secrets at rest

Provider tokens encrypted with AES-256-GCM; credentials live in Wrangler secrets, never in git.

One codebase, two runtimes

Shared logic targets both Node and Workers — no fork, no drift.

Verifiable claims

API contracts tagged for live verification; the design traces to primary-source docs.

// project documentation

Documented to the lowest level.

Every layer is written down — from system design to a file-by-file API reference. Browse it in the repository; each document and its purpose is below.

Understand it

  • ARCHITECTURE.md — system design, the two-plane model, request/data-flow diagrams
  • DATA_MAPPING.md — object/field maps, direction, idempotency, conflict & delete handling
  • SYNC_ENGINE.md — webhook ingestion, dedup, reconciliation, sequence flows
  • SPEC.md — the original research-grounded build spec & roadmap

Use it

  • FOR_AI_AGENTS.mdfor AI agents: what Conduit is, capabilities, how to call tools, behavior guidance
  • API.md — HTTP endpoints + every MCP tool, resource & prompt (schemas, examples)
  • AUTHENTICATION.md — the three OAuth relationships, dual-token brokering, PKCE, JWT
  • CONFIGURATION.md — every environment variable, secret & binding

Run & operate it

  • DEPLOYMENT.md — Cloudflare deploy: Workers, Durable Objects, KV, Cron, secrets, verify & rollback
  • SECURITY.md — threat model, SAST/SCA/lint posture, secrets, best practices
  • TESTING.md — test strategy, the 187-test suite, coverage gates, helpers

Build on it

Browse all docs on GitHub →
// documentation sources

Built on primary documentation.

The design traces to official specs and developer docs — each surfaced by a multi-source research pass and adversarially fact-checked. VERIFIED marks sources confirmed primary during research; Procore & Salesforce data-layer contracts are tagged for live re-verification before production.

Research method: 5 search angles → 22 sources fetched → 48 claims extracted → 25 adversarially verified (24 confirmed). Sources marked VERIFIED were confirmed as primary during that pass; remaining Procore/Salesforce contracts are authoritative docs to confirm against the live versions before production cutover.

Ready to connect your jobsite to your pipeline?

Conduit is deployed, tested, and waiting. Run the live demo above, or talk to us about wiring it to your Procore and Salesforce instances.

▶ Run the live demo