← MeasureGPT · On-prem deployment

Systems · Deployment

Architecture

The service is one Node process with a verified corpus and an MCP contract. SHC can run it behind CHOIR and the institutional firewall. The same host also runs the R and Python analysis workers.

HTTP MCP · R and Python workers · no PHI store

Language models invent cutoffs and PMIDs. MeasureGPT operates behind CHOIR and the approved internal AI workflows. It calculates scores deterministically from a corpus that humans verified. You can check its calculations and its citations. In an institutional deployment, MeasureGPT is not a public internet service. CHOIR and the other approved SHC projects call its internal MCP endpoint from inside the firewall. For the hospital Docker package, the auth modes, and the CHOIR configuration, see On-prem deployment.

System map

What runs in one process

One server.ts process holds five parts: the Mastra MCP server, the optional psychometrist agent, the deterministic interpretation engine, the host for the R and Python analysis, and the Next.js web UI. The UI and the deterministic /api routes call /mcp through the loopback interface. Analysis jobs enter through the Mastra MCP tools. They do not enter through a separate Next.js route.

MeasureGPT architecture: one Node process with shared MCP tools, optional agent, deterministic engine over a verified corpus, Next.js UI calling MCP over loopback, external clients via HTTP /mcp, and asynchronous R and Python analysis backends
The MeasureGPT architecture. It is one Node.js process (server.ts). The full detail is in ARCHITECTURE.md at the root of the repository.

Structure

The structure in short

A single Node process runs one Mastra instance. The instance gives four psychometric tools. It also gives the additional profile tools and analysis tools. It gives these tools through a streamable HTTP MCP server and an optional chat agent. A Next.js application in the same process calls that MCP server through the loopback interface. Thus the demo uses the same contract as an external client. You submit a multivariate recipe through the Mastra analysis tools. The recipe then runs as an asynchronous Python or R worker job on the same host.

Tools defined one timeThe MCP clients and the agent use the same tools: list_measures, get_measure, interpret_score, get_validation_studies, the profile tools, and the analysis jobs.
Verified corpusThe facts are in typed measure files. Each fact has cited<T> provenance. The facts are not in the weights of a model.
Asynchronous analysislist_analysis_recipes, submit_analysis, and get_analysis_job send the job to src/analysis/host. The host validates the inputs. It then starts the Python or R worker.
Complete round tripThe web /api routes use an MCP client to call /mcp through the loopback interface. They do not use a shortcut inside the process.
Operation without a model keyThe core service operates with no model key. Chat is optional. Without a key, chat stays inactive.

Institutional deployment

Behind the firewall

Usually, a hospital or a health system cannot send a clinical workflow to a public SaaS MCP server. Thus MeasureGPT is designed to run inside the SHC perimeter, behind CHOIR. It uses public psychometric facts only. It does not store patient data. It does not use an external database. The Node hosting can move to a different platform. The service has no public internet access.

Institutional network diagram showing Internet connected to CHOIR, CHOIR connected to private MeasureGPT, and no direct MeasureGPT internet communication
The institutional placement. Public traffic goes to CHOIR. CHOIR and the approved SHC systems can call MeasureGPT inside the firewall. MeasureGPT does not communicate directly with the internet.

What stays local

What can leave the perimeter

The hospital package contains the Docker image, the MCP_AUTH_MODE setting, the CHOIR environment examples, and the installation checks. See On-prem deployment →

Runbook

How to install and start the service

These six steps go from an empty host to institutional clients. If the operators must not use the full monorepo, use the Docker package in On-prem deployment. These details agree with README.md, ARCHITECTURE.md, and docs/INSTALL-HOSPITAL.md.

  1. Provision a host on the trusted network

    Use a virtual machine, a bare-metal node, or a container on your institutional network. The service is a plain Node process. It does not use APIs that are specific to Vercel or to one cloud platform. Use Node 24 or later, because the service uses native TypeScript type stripping. The default listen port is 3583. To change the port, set PORT.
  2. Install, build, and start

    If the operators must not use the full monorepo, use the hospital Docker profile:
    # Use the offline image bundle, or run this command:
    docker compose -f docker-compose.hospital.yml --env-file .env.hospital up --build -d
    # The service is then at http://localhost:3583
    # The MCP server is at /mcp
    # For authentication, set MCP_AUTH_MODE=token or MCP_AUTH_MODE=network
    # For the detail, see docs/INSTALL-HOSPITAL.md
    If you use a full clone, use these commands. The clone has the public demo defaults. Clerk is optional on a local host.
    npm install
    npm run build
    npm start
    # The service is then at http://localhost:3583
    # The MCP server is at /mcp
    server.ts is the production entry point. It sends /mcp to the Mastra MCP server. It sends all other requests to Next.js. Warning: do not use next start alone. next start cannot serve the streamable HTTP MCP transport.
  3. Put CHOIR and institutional controls in front

    Install MeasureGPT on a private interface. Put CHOIR and the institutional edge in front of it. Terminate HTTPS on your reverse proxy. nginx, HAProxy, and F5 are examples. Then send only private traffic to the Node process. The service should not be accessible from the internet. CHOIR and the existing SHC controls select the users and the internal systems that can use MeasureGPT.
  4. Keep the MCP endpoint internal-only

    Inbound traffic: the proxy must accept only traffic from CHOIR, an SHC application, a VPN, or a trusted subnet. The proxy sends this traffic to Node for the web UI, /api/*, and /mcp. Do not publish /mcp or the web UI to the public internet. A health check can call GET /api/health from inside the trusted network.
    Local runtime: if you enable the multivariate analysis recipes, install Python 3 and R. The MCP analysis tools start these workers on the same host.
    Outbound traffic (optional): the host needs outbound traffic only if you enable natural-language chat. The host then needs a connection to your model provider. Anthropic is an example. The deterministic core does not connect to the internet. The catalog, the bands, the cutoffs, and the citations are local files in the process.
  5. Point CHOIR and internal clients at /mcp

    Inside the firewall, configure CHOIR and the approved SHC projects with your internal base URL. An example is https://measuregpt.your-hospital.internal/mcp. In token mode, set MEASUREGPT_MCP_URL=…/mcp and MEASUREGPT_MCP_AUTHORIZATION="Bearer …". In network mode, set the URL only. The full examples are in docs/INSTALL-HOSPITAL.md. The endpoint has the same psychometric tools and analysis tools as the MeasureGPT web UI. Use the endpoint for CHOIR and approved SHC systems only.
  6. Decide if you enable chat (optional)

    For a facts-only service, do not set OPENROUTER_API_KEY. The form, the REST routes, and the MCP server then operate fully. The on-page assistant stays inactive. If your policy permits outbound model traffic, set the key. You can also set PSYCHOMETRIST_MODEL. Chat is an addition. Interpretation never depends on it.

Environment

VariableRequired?Role
PORTNoThe listen port. The default is 3583.
NODE_ENVNonpm start sets this variable to production.
OPENROUTER_API_KEYNoThis key enables the natural-language chat through OpenRouter. For a deterministic service only, do not set it.
PSYCHOMETRIST_MODELNoThis variable selects a different model. The default is openrouter/anthropic/claude-sonnet-4.6.
ANALYSIS_ENABLEDNoAnalysis is on by default. To disable the R and Python worker recipes, set 0.
REDIS_URLNoThis optional URL gives durable job records. You can use it when more than one instance polls for analysis results.
MCP_AUTH_MODENoThe default is oauth for the public demo. For a hospital, use token or network. See docs/INSTALL-HOSPITAL.md.
MCP_SERVICE_TOKENYes, in hospital token modeThe bearer secret for an external /mcp client. It applies when MCP_AUTH_MODE=token.

Reverse-proxy example

# Terminate TLS at the edge. Send the traffic to the Node process on the private network.
# This example uses nginx syntax. Change it for your platform.
#
# location / {
#   proxy_pass http://127.0.0.1:3583;
#   proxy_http_version 1.1;
#   proxy_set_header Host $host;
#   proxy_set_header X-Forwarded-Proto https;
# }
# # /mcp uses streamable HTTP. Do not buffer the body. Permit long streams.
# location /mcp {
#   proxy_pass http://127.0.0.1:3583;
#   proxy_buffering off;
#   proxy_read_timeout 3600s;
# }

HTTP surface

Routes to expose internally

PathPurposeFirewall note
GET /The web UI with the form and the cardsFor internal browsers and the VPN
ALL /mcpThe streamable HTTP MCP server with the psychometric tools, the profile tools, and the analysis toolsFor internal CHOIR and approved SHC systems only. Never put it on the public internet.
GET /api/measuresLists the catalog through the MCP loopback interfaceOptional. It gives the same facts as the tools.
POST /api/interpretConverts { measure, score } to an interpretationAn optional REST route for CHOIR or another internal application
POST /api/copilotkitThe chat agent (AG-UI)Available only if you set a model key. The agent can call the analysis tools after it removes the ambiguity in the request.
GET /api/healthGives the readiness state and the chat stateFor a load balancer or a Kubernetes probe
GET /architectureThis pageDocumentation for the persons who install the service
GET /on-prem-deploymentThe hospital Docker package, the auth modes, and the CHOIR configurationThe institutional handover (open)

Checks after installation

curl -sS https://measuregpt.your-hospital.internal/api/health
curl -sS https://measuregpt.your-hospital.internal/api/measures | head
curl -sS -X POST https://measuregpt.your-hospital.internal/api/interpret \
  -H 'content-type: application/json' \
  -d '{"measure":"PHQ-9","score":18}'

Why this structure

Patterns you can use again (from ARCHITECTURE.md)

  1. The MCP server is internal only. MeasureGPT operates behind CHOIR and the SHC firewall. /mcp supports CHOIR and the approved internal projects. It does not support public clients.
  2. There is one MCP contract. Streamable HTTP at /mcp gives the psychometric tools, the profile tools, and the analysis tools to trusted internal clients.
  3. The tools are defined one time. The agent and the MCP server use the same createTool sets, which include the analysis tools. Thus the contracts cannot become different.
  4. The service uses its own contract. The web application is a true MCP client that calls the loopback interface. Thus a demo that operates correctly shows that the external contract also operates correctly.
  5. A verified corpus is behind the model. Generative language is optional. The facts and the calculations are deterministic and have provenance.
  6. The payloads are identical. The UI cards show the same tool JSON that an external client receives.
  7. The calculation stays on the same host. The analysis tools submit asynchronous jobs to the local host. The host validates the inputs. It then starts the Python or R recipe worker.
  8. The AI layer is optional. Without a model key, the core service still operates fully.
  9. Tests protect the boundary. Pinned MCP schema snapshots and drift tests protect the consumers and the offline benchmark.
  10. The evaluation uses the source of truth. The benchmark keys come from the corpus.
  11. The deployment can move platform. The service is plain Node. It runs in the cloud today. It can run in a datacenter later without a rewrite.

More design notes are in ARCHITECTURE.md, docs/corpus-curation.md, and docs/service-contract-benchmark.md.