Skip to main content

PMS Sync — Architecture and MCP Surface

Governed integration bridge from on-premises Aderant Expert into Clio Operate and Sharedo. Four discrete subsystems, two streamable Model Context Protocol services, and a unified write gate.

Start here

Architecture overview

YES
This app uses MCP. It runs two Model Context Protocol services: one hosted on the Proxy (:3050) and one on the SQL API (:4102). Both endpoints require Keystone OAuth 2.1 authentication, support RFC 9728 discovery, and speak Streamable-HTTP. The Portal (:3060) provides the human interface and contains no MCP server by design.

System purpose

Extracts matters, clients, and parties from on-premises Aderant Expert and instantiates governed work items in Sharedo / Clio Operate.

Access modes

Runs as a standalone web portal (:3060) and as an embedded Sharedo widget using single sign-on via URL fragment tokens.

AI automation

Agents and background workflows discover tools via RFC 9728 to search, preview transforms, validate participant role cardinality, and execute imports under strict write-gate governance.

Point-in-time health capture from 2026-06-14 is provided in the operational reference section below.

1System context

End-to-end integration topology across user entry points, Alterspective core service tiers, on-premises bridge, and external systems.

CLIENTS & AGENTS ALTERSPECTIVE CORE & ON-PREM BRIDGE DEPENDENCIES & TARGETS Staff Browser Standalone portal login HTTPS · Keystone OIDC Sharedo User Portal embedded in Sharedo SSO JWT · #fragment AI Agent / Workflow Calls streamable /mcp tools Keystone OAuth 2.1 RFC 9728 discovery AderantImportPortal Next.js 15 · React 19 · :3060 Human UI, previews, role cardinality UI Signs x-org-assertion (HMAC) ShareDoAderantAPIProxy Express 4 · :3050 · Clean Architecture src/{domain, application, infrastructure, presentation} Write Gate (runAderantWriteGate) · Single Writer Participant capacity guard · Streamable /mcp (7 tools) Keystone OAuth 2.1 scopes: :read / :write AderantSQLAPITypeScript Express 5 · :4102 · Read Engine (On-Prem) Whitelisted, parameterised SQL reads only Streamable /mcp (5 read tools) Scope: pms-sql-api:read pms-sync-embed widget Foundry SDK ^0.6 · runs in Sharedo IDE Iframes Portal with signed SSO handoff Keystone Identity OIDC + OAuth 2.1 · JWKS Supabase aderant_org_configs (tenant secrets) aderant_write_audit (fail-closed 503) Sharedo / Clio Operate API ODS parties, work items, key dates WorkTypeParticipantRole cardinality Aderant Expert SQL Server On-premises source of truth TDS / port 1433 (no cloud inbound) Synapse AI Gateway synapse-api.alterspective.com.au GitHub Packages @alterspective-engine/foundry iframes via #fragment SSO MCP :3050 MCP :4102 x-org-assertion (HMAC) Azure Relay (TLS 443 outbound) Governed writes Local TDS 🔒 Production On-Prem Transport: Azure Relay Hybrid Connection (Outbound TLS 443, SAS tokens, zero inbound ports)
Portal (:3060 UI) Proxy (:3050 Clean Arch & Write Gate) SQL API (:4102 Read Engine) Sharedo Widget External / Target Azure Relay & Write Security
System context and network boundaries. Green = governed write and internal API path. Amber = on-premises read bridge via Azure Relay Hybrid Connection. Grey = platform dependencies.

2Architecture building blocks

Four discrete services divide responsibility across presentation, orchestration, on-premises data extraction, and tenant embedding.

Portal AderantImportPortal

Next.js 15 · React 19 Port 3060 pms-sync.alterspective.com.au

Presentation tier for matter lookup, transform previews, participant role validation, and execution history. Mints HMAC-SHA256 signed x-org-assertion headers to verify tenant identity on every proxy call. Holds no database credentials or tenant API keys. Exposes no MCP endpoints by design.

Proxy ShareDoAderantAPIProxy

Express 4 Port 3050 aderant-proxy.alterspective.com.au

Central application and orchestration core organized under Clean Architecture (domain, application, infrastructure, presentation). Sole component authorized to write into Sharedo and Clio Operate. Implements the unified runAderantWriteGate, validates participant role cardinality (WorkTypeParticipantRole.canBeAssignedMultiple), writes durable pre-execution audits to Supabase (aderant_write_audit), and exposes streamable /mcp (7 tools) under Keystone OAuth 2.1 scopes.

SQL API AderantSQLAPITypeScript

Express 5 Port 4102 Azure Relay Hybrid Connection

Dedicated on-premises data reader deployed alongside the enterprise Aderant Expert SQL Server. Executes only parameterised, column-whitelisted queries with zero arbitrary SQL capabilities. Connects out to Azure Relay over TLS 443 with SAS token authorization, requiring zero inbound firewall ports. Exposes a read-only streamable /mcp endpoint (5 tools) scoped to pms-sql-api:read.

Widget pms-sync-embed

Foundry SDK ^0.6 Runs in Sharedo IDE Foundry CLI deployment

Contextual embedding widget deployed into the enterprise Sharedo environment. Frames the Portal inside an iframe using a signed JWT single sign-on handoff delivered via URL #fragment, ensuring authentication tokens never leak into HTTP referrer headers or server access logs.

Architectural boundary principle The Portal manages user interaction without holding system credentials. The on-premises SQL API is strictly read-only and cannot alter source financial records. The API Proxy functions as the single governed write gateway, ensuring every mutation is validated, role-checked, rate-limited, and durably audited before reaching upstream systems.

3Import lifecycle and execution sequence

End-to-end transaction sequence from user selection through role introspection, the unified write gate, and upstream Sharedo creation.

User / Widget Sharedo UI Portal :3060 Next.js API Proxy :3050 Core SQL API Agent :4102 On-Prem Sharedo API Cloud Target Supabase Audit Store 1. Search matter / client 2. POST /api/import/matter/{uno}/preview (with x-org-assertion) 3. Query matter + parties (Azure Relay TLS 443) SQL rows returned 4. Map & introspect role cardinality WorkTypeParticipantRole.canBeAssignedMultiple Preview JSON + previewHash nonce + [Single]/[Multi] flags 5. Render preview, badges, conflict warnings 6. User confirms import (confirm: true) 7. POST /api/import/matter/{uno} (confirm: true, previewHash) runAderantWriteGate Verify aderant_write_enabled + nonce 8. Insert pre-execution audit (aderant_write_audit) — fail-closed 503 9. Create ODS parties, work item, key dates (capacity guarded) workItemId + reference Update audit status: success 10. Import complete (workItemId returned to UI)
Governed import execution path. Azure Relay handles on-premises SQL extraction. The Proxy enforces the unified write gate, role cardinality rules, and fail-closed durable audit logging in Supabase.

Unified Aderant Write Gate (runAderantWriteGate)

Guards every non-GET operation into upstream systems. In enforce mode, requests execute only when the organisation's aderant_write_enabled flag is active in Supabase and the caller supplies both confirm: true and a valid, server-minted, single-use previewHash nonce. Missing or stale nonces are rejected as preview-only responses.

Fail-Closed Durable Audit (aderant_write_audit)

Before any upstream call is dispatched to Sharedo or Aderant, an audit attempt row is committed to Supabase. If this database write fails or times out, the gate immediately fails closed with HTTP 503, preventing untracked data modification. Execution outcome and timing are written upon completion.

Participant Role Cardinality Guard

Introspects Sharedo work type schemas via WorkTypeParticipantRole.canBeAssignedMultiple. Roles marked single-capacity (or maxParticipants: 1 / isPrimaryOwner: true) are flagged in the UI with [Single] badges and pre-flight conflict warnings. During write execution, excess duplicate participants are substituted or skipped to prevent upstream 400/500 errors.

HMAC Assertions & Network Transport

Requests between the Portal and Proxy are authenticated using HMAC-SHA256 x-org-assertion headers that bind tenant, environment, and user identity. Communication with the on-premises SQL API is bridged via Azure Relay Hybrid Connection over outbound TLS 443 with SAS token authorization, leaving zero open inbound ports.

4Does it use an MCP service? — Yes, two of them

Your direct question, answered with the code. Verified against source — not just the docs.

Proxy /mcp ✅

server.ts:217 · SDK ^1.29.0
  • Streamable-HTTP transport
  • 7 tools (read + write)
  • Scopes: aderant-api-proxy:read / :write
  • Resolves tenant from token, then loads org secrets server-side

SQL API /mcp ✅

index.ts:82 · SDK ^1.29.0
  • Streamable-HTTP transport
  • 5 tools (read-only)
  • Scope: pms-sql-api:read
  • Column-whitelisted, parameterised queries

Portal /mcp ❌

none — by design
  • No @modelcontextprotocol/sdk dependency
  • It's the human UI shell
  • Its capabilities are already exposed by the two backends — a 3rd MCP would just duplicate them
What "MCP" buys us here MCP turns the app's capabilities into tools an AI agent can call — the same search / preview / import operations a human does in the Portal, but available to a Sharedo workflow, an automation, or a Claude agent. This is the "Build-for-AI" surface. The actual data work is still done by the services' own HTTP APIs; MCP is a thin, authenticated, AI-shaped doorway over them.

5MCP request authorization and execution lifecycle

Every MCP session verifies Keystone OAuth 2.1 tokens, scopes access to verified tenant claims, and enforces the write gate before dispatching tool operations.

AI Agent / Client Discovers via RFC 9728 Bearer Token Keystone Identity OAuth 2.1 Provider /.well-known/jwks.json mcpAuthenticate Verifies JWT via remote JWKS Validates issuer & audience Extracts granted scopes Extracts org claim Ephemeral Server Constructed per request Scoped to caller's tenant Loads secrets server-side In-process API execution 1. Request token 2. POST /mcp (Bearer + RFC 9728) 3. Init runAderantWriteGate Validation Pipeline Write tools (e.g. import_matter) must satisfy four security controls: ① Granted scope: aderant-api-proxy:write ② Supabase flag: import_write_enabled / aderant_write_enabled = true ③ Caller payload: confirm: true + server-issued single-use previewHash ④ Pre-execution audit row committed to Supabase (fails closed with HTTP 503) 4. Gated write dispatch
MCP request authorization and execution pipeline. Ephemeral server instances are bound exclusively to cryptographically verified tenant claims from Keystone tokens.
Aspect Proxy /mcp (:3050) SQL API /mcp (:4102)
Mount point app.all('/mcp') app.all('/mcp')
Discovery protocol RFC 9728 (/.well-known/oauth-protected-resource)
Transport protocol Streamable-HTTP (@modelcontextprotocol/sdk ^1.29.0)
Token verification jose.jwtVerify against Keystone JWKS; validates iss and aud
Expected audience aderant-api-proxy pms-sql-api
Keystone OAuth 2.1 scopes aderant-api-proxy:read, aderant-api-proxy:write pms-sql-api:read, pms-sql-api:write
Tenant context resolution Extracted from Keystone token claim → Supabase aderant_org_configs On-premises single tenant (stateless read engine)
Write enforcement runAderantWriteGate with fail-closed Supabase audit (HTTP 503) Read-only column-whitelisted query engine

6Registered MCP tool catalog

Complete specification of tools registered across the Proxy (:3050) and SQL API (:4102) streamable endpoints.

Proxy Tools (:3050)

Tool Keystone Scope Description & Governance
get_status public Health, uptime, version, and active configuration mode of the API Proxy.
list_work_types aderant-api-proxy:read Sharedo work types configured in the caller's verified tenant environment.
search_matters aderant-api-proxy:read Searches on-premises Aderant matters by matter number, description, or client code.
list_client_matters aderant-api-proxy:read Retrieves active and closed matters associated with a specific client code.
preview_matter aderant-api-proxy:read Executes dry-run transform. Evaluates WorkTypeParticipantRole.canBeAssignedMultiple, identifies participant role conflicts, and mints a single-use previewHash nonce.
import_matter aderant-api-proxy:write Executes upstream import. Gated by runAderantWriteGate: requires confirm: true, active aderant_write_enabled, valid previewHash, and fail-closed pre-audit commit in Supabase.
reconcile_closures read / write Audits matter closure drift between Aderant and Sharedo. With apply: false, returns report; with apply: true, closes drifted matters under write-gate governance.

SQL API Tools (:4102)

Tool Keystone Scope Description & Governance
get_status public Database connectivity, pool metrics, and Azure Relay listener status.
list_tables pms-sql-api:read Enumerates whitelisted Aderant database tables and views with schema metadata.
query_table pms-sql-api:read Extracts paginated records using strict column whitelisting and parameterised predicates. Supports structured filters (e.g. CLIENT_CODE=ABC;OPEN_DATE>2024-01-01).
search_clients pms-sql-api:read Parameterised search against Aderant client master records by name or code.
search_matters pms-sql-api:read Parameterised search against Aderant matter master records by number, description, or client.
SQL Injection Prevention & Query Whitelisting The SQL API agent provides no arbitrary SQL execution tool. Every database operation executes through predefined, parameterised query builders against an explicit column and table whitelist, protecting on-premises SQL Server integrity.

7Authentication and security architecture

All user and programmatic access is anchored in Keystone identity, enforced by HMAC assertions, single-use nonces, and fail-closed audit logging.

Standalone portal user

Keystone OIDCPort 3060

User authenticates via Keystone OIDC. The callback receives a signed handoff JWT validated against KEYSTONE_HANDOFF_SECRET, generating an encrypted iron-session cookie containing verified organisation memberships and roles.

Embedded Sharedo user

Signed JWT HandoffURL #fragment

The Sharedo widget requests a short-lived signed JWT from the Proxy's /api/embed/handoff endpoint. The token is appended as an iframe URL #fragment to prevent leakage into HTTP referrer headers or server logs. The Portal exchanges this token for an isolated session restricted to roles: ['embedded'].

AI agent / automation

Keystone OAuth 2.1RFC 9728

Automations supply a Keystone Bearer token to streamable /mcp endpoints. Middleware verifies signatures against remote JWKS, validates audience and issuer, extracts granted scopes (e.g. aderant-api-proxy:write), and scopes execution to the verified tenant claim.

HMAC-Signed x-org-assertion

Internal communication between the Portal (:3060) and API Proxy (:3050) uses cryptographically signed HMAC-SHA256 assertions (ORG_ASSERTION_SECRET). Each assertion binds the tenant organisation slug, environment, and user identifier with a 60-second validity window and server-side replay cache. Proxy middleware (orgIdentityMiddleware) verifies the assertion and strips raw unverified x-org-* headers, preventing tenant spoofing.

Unified Aderant Write Gate (runAderantWriteGate)

All mutations pass through the centralized write gate. In enforce mode, the write executes only when the tenant's aderant_write_enabled flag is active in Supabase and the request includes both confirm: true and a valid single-use previewHash nonce. Writes immediately fail closed with HTTP 503 if the pre-execution audit row cannot be committed to Supabase (aderant_write_audit).

Governance & framing controls 1. Tenant write toggle: The aderant_write_enabled (or import_write_enabled) setting in Supabase controls write permissions per organisation and environment. When false, UI and MCP write operations return HTTP 403.
2. CSP iframe restriction: Content-Security-Policy: frame-ancestors is dynamically enforced via EMBED_ALLOWED_HOSTS to restrict embedding strictly to authorized customer Sharedo tenant domains.

8Software architecture and dependency matrix

Core libraries and runtime frameworks organized by subsystem responsibility.

Subsystem Responsibility Portal (:3060) Proxy (:3050) SQL API (:4102)
Internal Architecture Next.js App Router (UI) Clean Architecture (domain, application, infrastructure, presentation) Layered Service / Controller
Framework & Runtime Next.js 15.5 · React 19 · Node 20 Express 4.18 · Node 20 Express 5.1 · Node 20
Model Context Protocol (MCP) — (UI shell) @modelcontextprotocol/sdk ^1.29.0 @modelcontextprotocol/sdk ^1.29.0
Authentication & Crypto jose 5 · iron-session 8 · HMAC-SHA256 jose 6 · HMAC-SHA256 assertion validator · crypto nonces jose 6 (JWKS verification)
Production Transport & Tunnel — Azure Relay SAS client signer hyco-https (Azure Relay Hybrid Connection listener)
Database & Audit Store @supabase/supabase-js 2 @supabase/supabase-js 2 (audit & configs) · mssql 12 mssql 10 (read-only pool)
Transform Sandbox — quickjs-emscripten (sandboxed JS transforms) —
HTTP & Proxy Clients axios 1.9 axios 1.16 · http-proxy-middleware Native Node fetch
Structured Logging pino 9 pino 10 (redacting audit fields) Structured JSONL
Security Middleware Next.js dynamic CSP & framing headers helmet · cors · express-rate-limit helmet · cors
Schema Validation zod 4 zod (MCP tools & write gate schema) zod (parameter validation)
Observability & API Docs langfuse 3 · @sentry/nextjs swagger-jsdoc · swagger-ui swagger-jsdoc · swagger-ui

Embed Widget (pms-sync-embed): Built on @alterspective-engine/foundry ^0.6 and foundry-cli, bundled with tsup, distributed via GitHub Packages registry.

9Platform dependencies and failure modes

System boundary dependencies, failure modes, and degradation behaviors across the integration topology.

External System Consuming Components Functional Role Failure Impact & Degradation Behavior
Keystone Identity
identity.alterspective.com.au
Portal, Proxy, SQL API, Widget OIDC user authentication, remote JWKS token signing, and OAuth 2.1 scope validation. Authentication fails closed. Unauthenticated users cannot access portal; MCP endpoints reject incoming requests with HTTP 401.
Supabase Database Portal, Proxy Stores tenant credentials in aderant_org_configs and durable records in aderant_write_audit. Tenant configuration becomes unresolvable. runAderantWriteGate fails closed with HTTP 503, preventing any un-audited mutation from executing.
Sharedo / Clio Operate API
Per-tenant cloud instance
Proxy, Widget Target cloud workspace for work items, ODS parties, participant role assignments, and key dates. Import mutations fail at the execution step; errors are recorded in audit logs and surfaced to user. Read-only search remains operational.
Aderant Expert SQL Server
On-premises enterprise host
SQL API Agent (:4102) Source of truth for matters, clients, and practice management parties. Matter lookups and preview generation return empty or timeout errors. Portal surfaces database connectivity alerts.
Azure Relay Hybrid Connection
Production Transport (Port 443)
Proxy (:3050), SQL API (:4102) Outbound-only TLS connection with SAS token authorization; bridges cloud proxy to on-premises SQL agent with zero inbound firewall ports. Cloud proxy cannot reach on-premises agent. Requests fail fast with 502/504 gateway errors. Local development environments can use ngrok as a fallback.
Synapse AI Gateway
synapse-api.alterspective.com.au
Portal (:3060) AI-assisted transform generation for work-type and field mappings. Automated mapping suggestions become unavailable; manual configuration and existing transforms continue to function without interruption.
GitHub Packages Widget build pipeline Distributes @alterspective-engine/foundry packages. Build-time dependency only; runtime operation of existing widget deployments is unaffected.
Availability considerations The connection between the cloud API Proxy and the on-premises SQL agent relies on the Azure Relay Hybrid Connection and local SQL host availability. If the relay tunnel is interrupted or the local database is offline, read queries fail cleanly without endangering data integrity. If Supabase becomes unavailable, the write gate enforces a strict fail-closed posture (HTTP 503), preventing any modification to upstream systems without an immutable audit trail.

10Operational health verification

Point-in-time health capture from 2026-06-14 across all system tiers. This is a point-in-time snapshot.

Service Tier Diagnostic Endpoint Verification Metrics & Expected Response
Portal (:3060) GET /api/health 🟢 HTTP 200 · status: "ok" · Session store and Next.js runtime ready.
Proxy (:3050) GET /health 🟢 HTTP 200 · status: "ok" · Express router and process liveness active.
Proxy (:3050) GET /health/deep 🟢 HTTP 200 · Reports runAderantWriteGate mode (enforce / shadow), Supabase connection, and tenant repository latency.
SQL API (:4102) GET /api/health/ready 🟢 HTTP 200 · status: "ready" · On-premises SQL connection pool active (e.g. 19ms latency), table catalog discovered.
End-to-End Chain GET /health/ready on Proxy 🟢 HTTP 200 · Full round-trip validation: Azure Relay tunnel pass, Sharedo API pass, Keystone identity pass.
Relay health semantics In local development environments using an ngrok tunnel instead of Azure Relay, the SQL API liveness check reports relay: warn while readiness remains green. Production environments require a connected Azure Relay listener with valid SAS token authorization.

11Architecture and operational reference

Core architectural specifications, security controls, port assignments, and MCP interfaces at a glance.

Core architecture & ports

  • Bridge purpose: Governed sync from on-premises Aderant Expert to cloud Sharedo / Clio Operate.
  • AderantImportPortal: Port 3060 (Next.js 15 UI, issues HMAC-signed x-org-assertion).
  • ShareDoAderantAPIProxy: Port 3050 (Express Clean Architecture: domain, application, infrastructure, presentation; sole writer).
  • AderantSQLAPITypeScript: Port 4102 (Express read engine, on-premises SQL reader).
  • Production transport: Azure Relay Hybrid Connection (outbound TLS 443, SAS token auth, zero inbound firewall ports).
  • Identity: Keystone OIDC for human users, Keystone OAuth 2.1 for MCP automations.

Security gates & governance

  • Unified write gate: runAderantWriteGate enforces server-side aderant_write_enabled, confirm: true, and single-use previewHash nonce.
  • Fail-closed audit: Pre-execution row inserted in Supabase (aderant_write_audit); fails closed with HTTP 503 if audit fails.
  • Role cardinality protection: Introspects WorkTypeParticipantRole.canBeAssignedMultiple to prevent duplicate single-role allocations.
  • Trust assertions: HMAC-SHA256 signed x-org-assertion headers bind tenant identity and user context between Portal and Proxy.
  • Iframe security: Signed JWT handoff delivered via URL #fragment, scoped to roles: ['embedded'], and bounded by CSP frame-ancestors.

Production endpoints & topology

  • Portal: pms-sync.alterspective.com.au (Port 3060)
  • Proxy: aderant-proxy.alterspective.com.au (Port 3050)
  • SQL API: On-premises listener connected via Azure Relay Hybrid Connection
  • Identity provider: identity.alterspective.com.au
  • Deployment automation: Core services deployed via Coolify; widget deployed into Sharedo via Foundry CLI.

Model Context Protocol (MCP) surface

  • Streamable endpoints: Mounted at /mcp on ports 3050 and 4102 with RFC 9728 discovery.
  • Keystone scopes: aderant-api-proxy:read, aderant-api-proxy:write, pms-sql-api:read.
  • Proxy tools (7): get_status, list_work_types, search_matters, list_client_matters, preview_matter, import_matter, reconcile_closures.
  • SQL API tools (5): get_status, list_tables, query_table, search_clients, search_matters.
  • Ephemeral isolation: Fresh MCP instance constructed per request; tenant derived strictly from token claims.

Visual documentation for PMS Sync. Innovation Hub reference: Practice Management → PMS Sync.

Knowledge base: Reference/Registries/estate-projects/EP-alterspective-aderant.md and Reference/Alterspective/assets/AA-006-Aderant-OOTB-vs-Alterspective-One-Pager.md in Alterspective-Intelligence.

Architecture references: TECHNICAL_DOCUMENTATION.md, README.md, and AGENTS.md in the repository root.

Operational health metrics reflect point-in-time environment validation. Deployment architecture: Deployment topology.