← 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 storeLanguage 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.

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.
list_measures, get_measure, interpret_score, get_validation_studies, the profile tools, and the analysis jobs.cited<T> provenance. The facts are not in the weights of a model.list_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./api routes use an MCP client to call /mcp through the loopback interface. They do not use a shortcut inside the process.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.

What stays local
- All score calculations and cutoffs. The code in
src/engine/interpret.tscalculates them from the supplied corpus. - The citations and the source locators. The tools return them as structured JSON for an audit.
- The analysis. After
submit_analysis, a pain-cluster recipe runs as a Python or R worker on the same host. Redis is an optional shared job record only. - The request path. A single-score request contains one measure and one number. The service is educational. It does not store patient records.
What can leave the perimeter
- Nothing is necessary. The MCP tools, the REST interpret route, and the form UI need no outbound traffic.
- There is no public endpoint. An institutional deployment keeps MeasureGPT behind CHOIR and the firewall. The MCP function is for CHOIR and approved SHC projects only.
- Model traffic is optional. It occurs only if you set a provider key for the CopilotKit chat. The chat uses the same tools. It adds a generative language layer only. Many sites keep the chat off.
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.
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 is3583. To change the port, setPORT.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.tsis the production entry point. It sends/mcpto the Mastra MCP server. It sends all other requests to Next.js. Warning: do not usenext startalone.next startcannot serve the streamable HTTP MCP transport.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.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/mcpor the web UI to the public internet. A health check can callGET /api/healthfrom 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.Point CHOIR and internal clients at /mcp
Inside the firewall, configure CHOIR and the approved SHC projects with your internal base URL. An example ishttps://measuregpt.your-hospital.internal/mcp. In token mode, setMEASUREGPT_MCP_URL=…/mcpandMEASUREGPT_MCP_AUTHORIZATION="Bearer …". In network mode, set the URL only. The full examples are indocs/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.Decide if you enable chat (optional)
For a facts-only service, do not setOPENROUTER_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 setPSYCHOMETRIST_MODEL. Chat is an addition. Interpretation never depends on it.
Environment
| Variable | Required? | Role |
|---|---|---|
PORT | No | The listen port. The default is 3583. |
NODE_ENV | No | npm start sets this variable to production. |
OPENROUTER_API_KEY | No | This key enables the natural-language chat through OpenRouter. For a deterministic service only, do not set it. |
PSYCHOMETRIST_MODEL | No | This variable selects a different model. The default is openrouter/anthropic/claude-sonnet-4.6. |
ANALYSIS_ENABLED | No | Analysis is on by default. To disable the R and Python worker recipes, set 0. |
REDIS_URL | No | This optional URL gives durable job records. You can use it when more than one instance polls for analysis results. |
MCP_AUTH_MODE | No | The default is oauth for the public demo. For a hospital, use token or network. See docs/INSTALL-HOSPITAL.md. |
MCP_SERVICE_TOKEN | Yes, in hospital token mode | The 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
| Path | Purpose | Firewall note |
|---|---|---|
GET / | The web UI with the form and the cards | For internal browsers and the VPN |
ALL /mcp | The streamable HTTP MCP server with the psychometric tools, the profile tools, and the analysis tools | For internal CHOIR and approved SHC systems only. Never put it on the public internet. |
GET /api/measures | Lists the catalog through the MCP loopback interface | Optional. It gives the same facts as the tools. |
POST /api/interpret | Converts { measure, score } to an interpretation | An optional REST route for CHOIR or another internal application |
POST /api/copilotkit | The 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/health | Gives the readiness state and the chat state | For a load balancer or a Kubernetes probe |
GET /architecture | This page | Documentation for the persons who install the service |
GET /on-prem-deployment | The hospital Docker package, the auth modes, and the CHOIR configuration | The 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)
- The MCP server is internal only. MeasureGPT operates behind CHOIR and the SHC firewall.
/mcpsupports CHOIR and the approved internal projects. It does not support public clients. - There is one MCP contract. Streamable HTTP at
/mcpgives the psychometric tools, the profile tools, and the analysis tools to trusted internal clients. - The tools are defined one time. The agent and the MCP server use the same
createToolsets, which include the analysis tools. Thus the contracts cannot become different. - 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.
- A verified corpus is behind the model. Generative language is optional. The facts and the calculations are deterministic and have provenance.
- The payloads are identical. The UI cards show the same tool JSON that an external client receives.
- 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.
- The AI layer is optional. Without a model key, the core service still operates fully.
- Tests protect the boundary. Pinned MCP schema snapshots and drift tests protect the consumers and the offline benchmark.
- The evaluation uses the source of truth. The benchmark keys come from the corpus.
- 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.