Architecture overview
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.
2Architecture building blocks
Four discrete services divide responsibility across presentation, orchestration, on-premises data extraction, and tenant embedding.
Portal AderantImportPortal
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
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
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.
pms-sync-embed
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.
3Import lifecycle and execution sequence
End-to-end transaction sequence from user selection through role introspection, the unified write gate, and upstream Sharedo creation.
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 ✅
- 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 ✅
- Streamable-HTTP transport
- 5 tools (read-only)
- Scope:
pms-sql-api:read - Column-whitelisted, parameterised queries
Portal /mcp ❌
- No
@modelcontextprotocol/sdkdependency - It's the human UI shell
- Its capabilities are already exposed by the two backends — a 3rd MCP would just duplicate 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.
| 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. |
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
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
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
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).
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 (): 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. |
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: 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-signedx-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:
runAderantWriteGateenforces server-sideaderant_write_enabled,confirm: true, and single-usepreviewHashnonce. - 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.canBeAssignedMultipleto prevent duplicate single-role allocations. - Trust assertions: HMAC-SHA256 signed
x-org-assertionheaders bind tenant identity and user context between Portal and Proxy. - Iframe security: Signed JWT handoff delivered via URL
#fragment, scoped toroles: ['embedded'], and bounded by CSPframe-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
/mcpon 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.