Documentation · Integration

How other systems talk to CLAiRE.

The primary application API is GraphQL. A small set of HTTP/REST endpoints handle health checks, the Model Context Protocol transport, and SAML/SSO callbacks. Both surfaces are served by the same Express application.

Overview

CLAiRE exposes two API surfaces from the same process:

  • GraphQL at /graphql — the primary application API. Records, flows, agents, audit logs, and tenant administration all live here.
  • REST — a deliberately small surface for endpoints that don't fit GraphQL: liveness, SAML/SSO callbacks, MCP transport.

CSRF protection is applied to all API calls (except when running under Cypress). All endpoints that read or mutate tenant data require an authenticated session established via SSO.

REST API (OpenAPI 3.1.0)

The complete machine-readable specification is at the bottom of this page. The table below is a hand-curated index of every REST route, grouped by tag.

Health

MethodPathSummarySource
GET/api/healthLiveness probe — returns 200 with body "success".app/modules/core/server-ts/app.ts

MCP

MethodPathSummarySource
POST/mcpInitialize MCP session or invoke a tool on an existing session.app/modules/mcp/server-ts/index.ts
GET/mcpOpen the server-to-client SSE stream for an MCP session.app/modules/mcp/server-ts/index.ts
DELETE/mcpTerminate an MCP session.app/modules/mcp/server-ts/index.ts

SSO

MethodPathSummarySource
GET/login/ssoBegin SAML SSO — redirects browser to the IdP AuthnRequest.app/modules/auth/server-ts/sub-modules/sso/index.ts
GET/esign/ssoSAML step-up for an electronic signature (forces re-auth).app/modules/auth/server-ts/sub-modules/sso/index.ts
POST/login/callbackSAML Assertion Consumer Service — validates IdP response.app/modules/auth/server-ts/sub-modules/sso/index.ts
GET/logout/sloBegin SAML Single Logout — destroys session, redirects to IdP.app/modules/auth/server-ts/sub-modules/sso/index.ts
POST/logout/callbackSAML SLO callback (HTTP-POST binding).app/modules/auth/server-ts/sub-modules/sso/index.ts
GET/logout/callbackSLO callback for IdPs that use HTTP-Redirect (e.g. Azure).app/modules/auth/server-ts/sub-modules/sso/index.ts
GET/azureb2c/callbackAzure B2C OIDC callback — returns an HTML completion shim.app/modules/auth/server-ts/sub-modules/sso/index.ts

SSO Hooks

MethodPathSummarySource
GET/okta/hooksOkta inline-hook verification challenge.app/modules/auth/server-ts/sub-modules/sso/index.ts
POST/okta/hooksReceive an Okta inline-hook event.app/modules/auth/server-ts/sub-modules/sso/index.ts

GraphQL endpoint

Almost everything other than the routes above is GraphQL. The endpoint is mounted at /graphql by Apollo Server and accepts both queries and mutations. File uploads use the graphql-upload multipart spec.

  • Authentication — session cookie (sessionId), established via SAML SSO. CSRF token required for mutations.
  • Authorization — per-operation, attribute-based. Resolvers check the caller's role, the record's classification tier, and the caller's clearance.
  • Rate limiting — the website rate-limiter applies; sustained abuse returns HTTP 429.
  • GraphiQL — the interactive explorer is exposed at /graphiql in development builds only.
The GraphQL schema is generated at build time from the modules under app/modules/…/server-ts/graphql/. Run the dev server and open /graphiql for a complete, always-current reference.

Model Context Protocol

CLAiRE speaks the Model Context Protocol over a Streamable-HTTP transport at /mcp. A client opens a session with a POST (no mcp-session-id header), the server returns a session id, and subsequent JSON-RPC calls echo that id. Long-running calls are delivered as server-sent events.

Lifecycle:

  • POST /mcp without mcp-session-id — creates a session.
  • POST /mcp with mcp-session-id — sends a JSON-RPC request on that session.
  • GET /mcp with mcp-session-id — opens the server-to-client SSE stream.
  • DELETE /mcp with mcp-session-id — terminates the session.

Raw OpenAPI YAML

Paste this into any OpenAPI-compatible tool (Swagger UI, Redoc, Postman, Stoplight) for an interactive reference. The spec is also available as a download in the sidebar.

openapi.yaml · OpenAPI 3.1.0
openapi: 3.1.0
info:
  title: CLAiRE Platform REST API
  version: 4.0.0
  summary: HTTP/REST endpoints exposed by CLAiRE V4.
  description: |
    CLAiRE's primary application API is GraphQL (served at `/graphql`).
    This document covers only the small set of true HTTP/REST endpoints:
    health, the Model Context Protocol (MCP) transport, and the SAML / SSO
    callback surface. GraphQL operations are not described here.

    All endpoints are served from the same Express application defined in
    `app/modules/core/server-ts/app.ts`. The SSO endpoints are only mounted
    when `settings.sso.enabled` is true.
  contact:
    name: ComplianceG Labs
    url: https://www.complianceg.com/get-in-touch/

servers:
  - url: https://{host}
    description: Tenant deployment (cloud or on-prem)
    variables:
      host:
        default: app.example.com
        description: Hostname of the CLAiRE deployment.

tags:
  - name: Health
    description: Liveness probes for orchestrators and uptime monitors.
  - name: MCP
    description: Model Context Protocol transport endpoints.
  - name: SSO
    description: SAML 2.0 single sign-on and single logout endpoints.
  - name: SSO Hooks
    description: Inline hooks invoked by identity providers (e.g. Okta).

paths:
  /api/health:
    get:
      tags: [Health]
      summary: Liveness probe.
      description: |
        Returns 200 OK with the literal body `success` when the application
        process is reachable. Does NOT verify database, session-store, or
        downstream connectivity — it is purely a liveness signal for Azure
        and similar orchestrators.
      operationId: getHealth
      responses:
        '200':
          description: Application process is alive.
          content:
            text/plain:
              schema:
                type: string
                example: success

  /mcp:
    post:
      tags: [MCP]
      summary: Initialize an MCP session or invoke a tool on an existing session.
      description: |
        Streamable-HTTP transport for the Model Context Protocol. The first
        request omits the `mcp-session-id` header; the server creates a new
        session and returns its id in the response headers. Subsequent
        requests on the same session must echo that id.
      operationId: mcpInvoke
      parameters:
        - $ref: '#/components/parameters/McpSessionId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JsonRpcRequest'
      responses:
        '200':
          description: JSON-RPC response or streamed server message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonRpcResponse'
            text/event-stream:
              schema:
                type: string
                description: Server-sent events stream for long-running calls.
        '404':
          description: `mcp-session-id` was supplied but no such session exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      tags: [MCP]
      summary: Open the server-to-client SSE stream for an existing MCP session.
      operationId: mcpStream
      parameters:
        - $ref: '#/components/parameters/McpSessionIdRequired'
      responses:
        '200':
          description: Server-sent events stream of MCP messages.
          content:
            text/event-stream:
              schema:
                type: string
        '400':
          description: Missing or unknown `mcp-session-id` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
    delete:
      tags: [MCP]
      summary: Terminate an MCP session.
      operationId: mcpClose
      parameters:
        - $ref: '#/components/parameters/McpSessionId'
      responses:
        '200':
          description: Session terminated (or no-op if no matching session).
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: true

  /login/sso:
    get:
      tags: [SSO]
      summary: Begin SAML SSO authentication.
      description: |
        Validates the SSO request, then redirects the browser to the tenant's
        configured Identity Provider AuthnRequest endpoint. Mounted only when
        `settings.sso.enabled` is true.
      operationId: ssoLogin
      parameters:
        - $ref: '#/components/parameters/TenantCode'
        - $ref: '#/components/parameters/EmailHint'
      responses:
        '302':
          description: Redirect to the IdP AuthnRequest URL.
          headers:
            Location:
              schema: { type: string, format: uri }

  /esign/sso:
    get:
      tags: [SSO]
      summary: Begin SAML step-up authentication for an electronic signature.
      description: |
        Same as `/login/sso` but flags the request as an e-sign step-up.
        Forces re-authentication regardless of existing session.
      operationId: esignSso
      parameters:
        - $ref: '#/components/parameters/TenantCode'
      responses:
        '302':
          description: Redirect to the IdP AuthnRequest URL.
          headers:
            Location:
              schema: { type: string, format: uri }

  /login/callback:
    post:
      tags: [SSO]
      summary: SAML Assertion Consumer Service (SSO callback).
      description: |
        Receives the SAMLResponse from the IdP, validates it, establishes the
        session, and writes audit logs. Body is x-www-form-urlencoded as per
        SAML HTTP-POST binding.
      operationId: ssoCallback
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [SAMLResponse]
              properties:
                SAMLResponse:
                  type: string
                  description: Base64-encoded SAMLResponse XML.
                RelayState:
                  type: string
                  description: Opaque IdP relay state echoed back.
      responses:
        '302':
          description: Redirect to the post-login destination on success.
          headers:
            Location:
              schema: { type: string, format: uri }

  /logout/slo:
    get:
      tags: [SSO]
      summary: Begin SAML Single Logout.
      description: |
        Writes a logout audit entry, asks the SAML strategy for the IdP
        logout URL, destroys the local session, clears the sessionId cookie,
        and redirects to the IdP.
      operationId: ssoLogout
      responses:
        '302':
          description: Redirect to the IdP logout URL.
          headers:
            Location:
              schema: { type: string, format: uri }
        '500':
          description: SAML logout failed (handler returned an error).

  /logout/callback:
    post:
      tags: [SSO]
      summary: SAML SLO assertion consumer (POST binding).
      operationId: sloCallbackPost
      responses:
        '302':
          description: Redirect to IdP entryPoint or `/`.
    get:
      tags: [SSO]
      summary: SLO callback for IdPs using HTTP-Redirect binding (e.g. Azure).
      operationId: sloCallbackGet
      responses:
        '302':
          description: Redirect to IdP entryPoint or `/`.

  /azureb2c/callback:
    get:
      tags: [SSO]
      summary: Azure B2C OIDC callback.
      description: |
        Returns a small HTML page that completes the Azure B2C flow client
        side (token handling happens in the page).
      operationId: azureB2cCallback
      responses:
        '200':
          description: HTML callback shim.
          content:
            text/html:
              schema:
                type: string

  /okta/hooks:
    get:
      tags: [SSO Hooks]
      summary: Okta inline-hook verification challenge.
      description: |
        Echoes the value of the `x-okta-verification-challenge` header back
        in JSON, satisfying Okta's one-time hook verification handshake.
      operationId: oktaHookVerify
      parameters:
        - in: header
          name: x-okta-verification-challenge
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Verification response.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verification: { type: string }
    post:
      tags: [SSO Hooks]
      summary: Receive an Okta inline-hook event.
      operationId: oktaHookEvent
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Okta inline hook payload (see Okta docs).
              additionalProperties: true
      responses:
        '200':
          description: Hook acknowledged.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message: { type: string, const: 'Hook received' }

components:
  parameters:
    McpSessionId:
      in: header
      name: mcp-session-id
      required: false
      description: Existing MCP session identifier. Omit on the very first call.
      schema: { type: string, format: uuid }
    McpSessionIdRequired:
      in: header
      name: mcp-session-id
      required: true
      schema: { type: string, format: uuid }
    TenantCode:
      in: query
      name: tenantCode
      required: true
      description: Short code identifying the tenant whose SSO config to use.
      schema: { type: string }
    EmailHint:
      in: query
      name: email
      required: false
      description: |
        Optional user email hint. If different from the current session user,
        the SAML strategy will force re-authentication.
      schema: { type: string, format: email }

  schemas:
    JsonRpcRequest:
      type: object
      required: [jsonrpc, method]
      properties:
        jsonrpc: { type: string, const: '2.0' }
        id:
          oneOf:
            - { type: string }
            - { type: integer }
        method: { type: string }
        params: { type: object, additionalProperties: true }
    JsonRpcResponse:
      type: object
      required: [jsonrpc]
      properties:
        jsonrpc: { type: string, const: '2.0' }
        id:
          oneOf:
            - { type: string }
            - { type: integer }
            - { type: 'null' }
        result: {}
        error:
          type: object
          properties:
            code: { type: integer }
            message: { type: string }
            data: {}
    ErrorEnvelope:
      type: object
      properties:
        error: { type: string }

  responses:
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'

We use cookies to help give you the best experience on our site. By continuing you agree to our use of cookies.