A hosted test harness for exercising AI agents. It exposes the same set of capabilities over two faces from one shared registry, so they never drift:
Model Context Protocol over Streamable HTTP. One tool per capability. Point an agent / AgentCore remote MCP server at it.
A standards-shaped REST API (GET resources, query filters,
201 on create) over the same data, with its own OpenAPI at
/api/v1/openapi.json.
A capability is a single tool/operation (e.g.
insurance_get_policy), exposed identically on MCP and REST. The
four domains below (insurance, financial, healthcare,
retail/CPG) are industry areas that group related capabilities.
member · policy · claim · quote · coverage
Lookups, search, claims aggregation, and a file-claim write stub. VIN-bearing auto quotes.
account · transaction · balance · statement
Account/balance/statement lookups, transaction search, spending summary, transfer write stub. IBAN-bearing accounts.
patient · encounter · provider · appointment · prescription
Patient/provider/prescription lookups, encounter & appointment search/aggregation, schedule write stub. NPI-bearing providers.
product · customer · store · supplier · inventory · order
Product/customer/store/supplier/order lookups, order & inventory search, per-channel sales summary, place-order write stub. GTIN-bearing products.
~51 capabilities total across the four domains, plus a
cross-domain session_reset. Each domain includes read tools and a
non-persisting write stub.
| Surface | URL |
|---|---|
| MCP (Streamable HTTP) | https://harness.dataio.dev/mcp |
| REST API (v1) | https://harness.dataio.dev/api/v1 · idiomatic GET resources |
| REST API — interactive docs | https://harness.dataio.dev/api/v1/docs |
| REST API — OpenAPI 3.1 | https://harness.dataio.dev/api/v1/openapi.json |
| Health (health check) | https://harness.dataio.dev/healthz |
Auth posture: open no token required TLS at the edge
Tool names use underscores: insurance_get_policy,
financial_get_account, healthcare_get_patient.
Entities are addressed as {domain}/{type}/{ordinal} (slashes),
e.g. insurance/policy/0, financial/account/0.
Ordinals start at 0 and a handful always exist; use a
search_* / list_* tool to discover valid ids.
| Pattern | Example |
|---|---|
| Collection (filters + pagination) | GET /api/v1/financial/accounts?account_type=savings&limit=10 |
| One record by id (ordinal) | GET /api/v1/financial/accounts/0 |
| Sub-resource | GET /api/v1/financial/accounts/0/balance |
| Create (POST → 201, not persisted) | POST /api/v1/insurance/claims |
Path ids are the bare ordinal (e.g. /0); a
missing record returns 404. Pin data with ?seed= or
the X-Seed header.
# Insurance — search policies, fetch one, then its coverages
curl -s 'https://harness.dataio.dev/api/v1/insurance/policies?limit=2&seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/insurance/policies/0?seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/insurance/policies/0/coverages?seed=demo-123'
# Financial — list accounts, fetch one, read its balance
curl -s 'https://harness.dataio.dev/api/v1/financial/accounts?account_type=savings&limit=2&seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/financial/accounts/0?seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/financial/accounts/0/balance?seed=demo-123'
# Healthcare — list providers, fetch a patient, schedule an appointment (201)
curl -s 'https://harness.dataio.dev/api/v1/healthcare/providers?limit=2&seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/healthcare/patients/0?seed=demo-123'
curl -s -X POST https://harness.dataio.dev/api/v1/healthcare/appointments \
-H 'Content-Type: application/json' \
-d '{"patient_id":"healthcare/patient/0","provider_id":"healthcare/provider/0","requested_date":"2026-07-01"}'
# Retail / CPG — list products, fetch one, place an order (201)
curl -s 'https://harness.dataio.dev/api/v1/retail/products?category=beverages&limit=2&seed=demo-123'
curl -s 'https://harness.dataio.dev/api/v1/retail/products/0?seed=demo-123'
curl -s -X POST https://harness.dataio.dev/api/v1/retail/orders \
-H 'Content-Type: application/json' \
-d '{"customer_id":"retail/customer/0","store_id":"retail/store/0","lines":[{"product_id":"retail/product/0","quantity":2}]}'
The full resource map (browse and try it at
/api/v1/docs). {id} is the bare
ordinal (e.g. 0); trailing comments list the available query
filters.
# Insurance
GET /api/v1/insurance/policies # member_id, status, limit, offset
GET /api/v1/insurance/policies/{id}
GET /api/v1/insurance/policies/{id}/coverages
GET /api/v1/insurance/members/{id}
GET /api/v1/insurance/claims # policy_id, status, filed_from, filed_to, limit, offset
GET /api/v1/insurance/claims/{id}
GET /api/v1/insurance/claims/summary # member_id, policy_id
POST /api/v1/insurance/claims # file a claim (201, not persisted)
GET /api/v1/insurance/quotes/{id}
GET /api/v1/insurance/products/{id}
GET /api/v1/insurance/documents/{id}
GET /api/v1/insurance/assessors/{id}
GET /api/v1/insurance/reserves/{id}
GET /api/v1/insurance/claim-assessments/{id}
GET /api/v1/insurance/claim-events/{id}
GET /api/v1/insurance/decisions/{id}
# Financial
GET /api/v1/financial/accounts # status, account_type, limit, offset
GET /api/v1/financial/accounts/{id}
GET /api/v1/financial/accounts/{id}/balance
GET /api/v1/financial/accounts/{id}/statements
GET /api/v1/financial/accounts/{id}/transactions # type, category, posted_from, posted_to, limit, offset
GET /api/v1/financial/accounts/{id}/spending-summary # type
GET /api/v1/financial/statements/{id}
GET /api/v1/financial/transactions # account_id, type, category, posted_from, posted_to, limit, offset
POST /api/v1/financial/transfers # transfer funds (201, not persisted)
# Healthcare
GET /api/v1/healthcare/providers # specialty, limit, offset
GET /api/v1/healthcare/providers/{id}
GET /api/v1/healthcare/patients/{id}
GET /api/v1/healthcare/patients/{id}/prescriptions
GET /api/v1/healthcare/prescriptions/{id}
GET /api/v1/healthcare/encounters # patient_id, provider_id, type, date_from, date_to, limit, offset
GET /api/v1/healthcare/appointments # patient_id, provider_id, status, date_from, date_to, limit, offset
GET /api/v1/healthcare/appointments/summary # patient_id, provider_id
POST /api/v1/healthcare/appointments # schedule (201, not persisted)
# Retail / CPG
GET /api/v1/retail/products # category, brand, status, limit, offset
GET /api/v1/retail/products/{id}
GET /api/v1/retail/products/{id}/inventory # stock across stores
GET /api/v1/retail/customers # tier, status, limit, offset
GET /api/v1/retail/customers/{id}
GET /api/v1/retail/customers/{id}/orders # status, placed_from, placed_to, limit, offset
GET /api/v1/retail/stores # region, type, status, limit, offset
GET /api/v1/retail/stores/{id}
GET /api/v1/retail/stores/{id}/inventory
GET /api/v1/retail/suppliers # status, limit, offset
GET /api/v1/retail/suppliers/{id}
GET /api/v1/retail/orders # customer_id, store_id, status, placed_from/to, limit, offset
GET /api/v1/retail/orders/{id}
GET /api/v1/retail/orders/{id}/lines
GET /api/v1/retail/orders/summary # store_id, status (per-channel sales rollup)
GET /api/v1/retail/inventory # product_id, store_id, limit, offset
POST /api/v1/retail/orders # place order (201, not persisted)
The MCP face (and the OpenAPI tool-mirror gateways ingest) expose these
tools — the REST API above serves the same data as resource paths. Each
domain also has a <domain>_list_capabilities tool that
returns this list, with descriptions and scopes, at runtime.
Get: insurance_get_member, insurance_get_policy, insurance_get_product, insurance_get_quote, insurance_get_reserve, insurance_get_assessor, insurance_get_document, insurance_get_claim, insurance_get_claim_assessment, insurance_get_claim_event, insurance_get_decision
List / search: insurance_list_coverages, insurance_search_policies, insurance_search_claims, insurance_list_capabilities
Aggregate: insurance_claims_summary
Write (stub): insurance_file_claim
Get: financial_get_account, financial_get_balance, financial_get_statement
List / search: financial_list_accounts, financial_list_statements, financial_search_transactions, financial_list_capabilities
Aggregate: financial_spending_summary
Write (stub): financial_transfer_funds
Get: healthcare_get_patient, healthcare_get_provider, healthcare_get_prescription
List / search: healthcare_list_providers, healthcare_list_patient_prescriptions, healthcare_search_appointments, healthcare_search_encounters, healthcare_list_capabilities
Aggregate: healthcare_appointments_summary
Write (stub): healthcare_schedule_appointment
Get: retail_get_product, retail_get_customer, retail_get_store, retail_get_supplier, retail_get_order
List / search: retail_list_products, retail_list_customers, retail_list_stores, retail_list_suppliers, retail_list_order_lines, retail_search_orders, retail_list_inventory, retail_list_capabilities
Aggregate: retail_sales_summary
Write (stub): retail_place_order
Plus a cross-domain session_reset.
All data is a pure function of an opaque seed string — the same seed always yields the same universe, regardless of call order. This is what makes test runs reproducible. There is no database; nothing is stored.
| Where | How to set the seed |
|---|---|
| Any client / agent — per call | "seed": "my-seed" in the tool arguments / JSON body (works everywhere, incl. clients that can't set headers and through gateways) |
| REST — session | X-Seed: my-seed request header (header-capable clients / curl) |
| MCP — connection | X-Seed: my-seed header on the connection (header-capable clients only) |
| If omitted | a seed is auto-generated and echoed back (X-Seed response header + seed in the body) so you can replay it |
The seed argument is the universal way to pin a run: an agent
simply passes seed in each tool call, so it works in every
client (including ones whose UI can't set custom headers). The
X-Seed header is a set-and-forget alternative for
header-capable clients and curl.
# Pin a seed so results are identical every time (header or ?seed=):
curl -s https://harness.dataio.dev/api/v1/insurance/policies/0 -H 'X-Seed: demo-123'
curl -s 'https://harness.dataio.dev/api/v1/insurance/policies/0?seed=demo-123'
For most uses, just pin the seed per call (the ?seed=
query param or the X-Seed header on the REST API) — that fixes
the data deterministically with no session state. MCP clients that hold a
session can also call the cross-domain session_reset tool, which
installs a new seed (or auto-generates one) and clears any session overlay;
it does not persist server-side in v1.
# Same seed -> identical universe every time:
curl -s 'https://harness.dataio.dev/api/v1/financial/accounts?seed=demo-123'
# Omit the seed and one is auto-generated and echoed in the X-Seed header:
curl -si 'https://harness.dataio.dev/api/v1/financial/accounts' | grep -i x-seed
The write tools (insurance_file_claim,
financial_transfer_funds,
healthcare_schedule_appointment) validate input and return a
realistic, seed-derived success response marked
_mock: "not_persisted" — but they do not store
anything. "Write then read it back" is intentionally inconsistent in this
version.