Server Specifications and Registered Servers¶
To run tests you tell FHIR Frog which server to test. For one-off runs that is just a URL. For anything you repeat, you register the server once under a name, optionally tag it with a server specification (what kind of server it is meant to be), and refer to it by name afterwards. This page covers both files, the tools that manage them and how a run picks its target.
Two files live in the FHIR Frog configuration directory (~/.fhir-frog/, or the directory in FROG_CONFIG_DIR):
| File | Holds | Written by |
|---|---|---|
backends.yaml |
Your registered servers (backends): name, URL, spec, auth | frog_server_register, or by hand |
server-specs.yaml |
Your own server specifications (optional) | by hand |
Registering a server¶
The first call returns the plan; repeat it with confirm: true to write the file. The result in backends.yaml:
Fields of a backend:
| Field | Meaning |
|---|---|
name |
Unique name used everywhere else (server: "qld-ereferral") |
url |
FHIR base URL |
spec |
Id of the server specification this server is meant to satisfy |
conformsTo |
IG canonical URL; filled from the spec when you give a spec |
managed |
true for servers the MCP starts and owns (the local frog-sut); runs against managed servers need no confirmation |
allowWrites |
Allow write operations although the spec is read-only |
auth |
How to authenticate (below) |
Authentication¶
Credentials are always references to environment variables, never values. A client-credentials backend:
frog_server_register(name: "secure-server", url: "https://example.org/fhir", authType: "client-credentials", tokenUrl: "https://auth.example.org/token", clientId: "frog", clientSecret: "${FROG_SECRET}", scope: "system/*.read")
auth:
type: client-credentials
tokenUrl: https://auth.example.org/token
clientId: frog
clientSecret: ${FROG_SECRET}
Set FROG_SECRET in the environment that starts the MCP. A literal secret is refused (secret_not_allowed). For a static bearer token use authType: "bearer" with clientSecret: "${TOKEN_VAR}". Basic authentication is not supported in v0.1.
Server specifications¶
A specification names a class of server: "an AU Core server", "an AU eRequesting server". It lets you say what a server is meant to be without listing every server, and lets tests find an appropriate server.
List them with frog_server_spec_list. Three are built in:
| Id | Title | Canonical | Writes |
|---|---|---|---|
au-core |
AU Core | http://hl7.org.au/fhir/core |
read-only |
au-ps |
AU Patient Summary | http://hl7.org.au/fhir/ps |
read-only; extends au-core |
au-erequesting |
AU eRequesting | http://hl7.org.au/fhir/ereq |
write-capable |
Add your own in server-specs.yaml. Entries with the same id replace built-ins:
specs:
- id: qld-referral
title: "QLD eReferral server"
conformsTo:
- http://example.org/fhir/qld-referral
fhirVersion: R4
readOnly: false
capabilities:
write: true
resources: [ServiceRequest, Patient]
extends: [au-core]
quirks:
maxPageSize: "50"
| Field | Meaning |
|---|---|
id, title |
Identifier and display name |
conformsTo |
IG canonicals the spec covers; the first is the primary |
fhirVersion |
R4, R4B, R5 |
readOnly |
A read-only spec marks servers not to be used for write-heavy fixtures |
capabilities.write, capabilities.resources |
What the server supports and what the tests exercise |
extends |
Parent specs; a server of a child spec also satisfies the parent's canonicals |
quirks |
Free-form known deviations, shown by frog_server_describe, not enforced |
v0.1 specs are descriptive. They classify and document servers; the MCP does not yet refuse a run because a server does not meet its spec. frog_server_check verifies reachability and reports the FHIR version and software, nothing more.
Looking at what you have¶
frog_server_list()
frog_server_list(spec: "au-core")
frog_server_describe(name: "qld-ereferral")
frog_server_check(name: "qld-ereferral")
frog_server_check fetches /metadata; a redirect or a refused connection is reported as reachable: false with the reason. Secret values never appear in any of these.
How a run chooses its server¶
frog_run_local and frog_run_remote pick the target in this order and stop at the first that applies:
serverUrl: used as given, with no registry metadata.server: the backend with that name.spec: the first registered backend whosespecequals that id.- The test package's canonical: a backend whose spec or
conformsTocovers it. - If exactly one backend is registered, that one.
If none applies you get not_found rather than a guess. Non-loopback targets that are not managed or allowWrites need confirm: true because tests can write to them.
frog_run_remote(testPackage: "fhirfrog.au-core-tests#0.1.0", server: "qld-ereferral", confirm: true)
The local test server¶
frog_server_start_local registers the container it starts as the managed backend frog-sut. Select it with server: "frog-sut": the MCP uses the host address (http://127.0.0.1:8081/fhir) for local runs and the Docker network name (http://frog-sut:8080/fhir) for the runner container, so you do not choose. See Local test server.
What is not covered yet¶
- Executing a
resetPolicybetween runs. - Refusing runs on specification violations (planned, v0.2).
- Vendor or product classes beyond IG-based specs.
- Multi-server matrix runs (planned, v0.3).