Skip to content
Get Started

③ Answers

Built-in Tools

The four MCP tools the engine ships — terminology, health records and genetics — plus what DeepAgent gets from its harness.

Every tool below is an ordinary Python method that runtime discovery picked up. Nothing here is special-cased by the engine, and nothing here is compiled in: the same rules that find these would find yours.

The MCP surface is small on purpose. Four tools ship, and the authoritative list is whatever your own server reports — ask it:

Terminal window
curl -X POST http://localhost:18080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The four tools come in three groups: terminology resolution (resolve_indicator, normalize_unit), health-record reads (query_health_indicators) and genetic-data reads (get_genetic_data). Two of the four need nothing — no account, no network, no key — and two are bound to the caller’s own records:

ToolWhat it doesNeeds
resolve_indicatorany-language indicator name → canonical LOINCnothing — offline, no user data
normalize_unitfree-text unit → canonical UCUM + comparability familynothing — offline, no user data
query_health_indicatorsthe caller’s own records: search, read and aggregate in one callthe account
get_genetic_datathe caller’s variants by rsIDthe account

Terminology — the ② Standardize surface

Section titled “Terminology — the ② Standardize surface”

These two tools give the model a way to put a name on the same footing as a code. “LDL cholesterol”, “低密度脂蛋白胆固醇” and “LDL-C” are three strings for one measurement; both tools turn any of them into the same canonical identity. Neither reads user data, so they work for an anonymous caller and disclose nothing.

Resolution runs against the bundles shipped inside the package. A client can be air-gapped and these still answer, which is exactly the property health data deserves.

names string[] required

Names exactly as printed. Pass the whole batch in one call.

Returns one result per input, in order: name unchanged, resolved, loinc (e.g. 718-7, empty when unresolved), canonical (the LOINC long common name) and candidates — how many corpus rows matched. A large candidates count means genuine ambiguity, and one sensible default was chosen; surface that when precision matters.

Three properties the model is told about explicitly, because they change how an answer should be written:

  • Unresolved is an honest “no”. Report the name as unmatched; never invent a code.
  • Panel names deliberately do not resolve. blood pressure and 血圧 name a panel, not an observation — the right response is to ask which measurement (systolic or diastolic).
  • The same code from two names means the same test. That, not string equality, decides whether two readings are comparable.

units string[] required

Unit strings as printed, e.g. ["mg/dL", "毫摩尔每升", "次/分"]. Up to 200 per call.

Returns unit unchanged, ucum (canonical form; empty means unrecognized) and family — the LOINC PROPERTY, e.g. SCnc.

"MG/DL"
ucum "mg/dL" · family "MCnc"
"毫摩尔每升"
ucum "mmol/L" · family "SCnc"

The family is the point: units in the same family are convertible, and converting across families is a category error, not arithmetic.

This single tool combines search, read and aggregate in one call, and every result carries its canonical identity.

keywords string[]

Fuzzy terms, any language. For shorthand, include both forms — ["MCHC", "Mean Corpuscular Hemoglobin Concentration"].

indicators string[]

Exact names from a previous call. Use instead of keywords, not alongside guesses.

start_time string

Inclusive start date, YYYY-MM-DD.

end_time string

Inclusive end date, YYYY-MM-DD.

aggregate string default: none

One of none, stats, day, week, month — declared as an enum in the schema, so an invalid value is rejected before any engine code runs. stats returns count/min/max/avg/first/last/change per indicator; a bucket returns one point per bucket. Trend questions should use one of those rather than pulling raw readings.

limit integer default: 50

Maximum readings per indicator when aggregate is none. Bounded at 500 in the schema itself.

The response is shaped so the model can keep going without guessing:

FieldWhat it is
indicatorsPer match: indicator (the exact name, reusable as indicators), system / code (the canonical identity — same code means the same test, whatever the names), count, and rows as a pipe-delimited table. A leading (constants: k=v) line carries columns identical on every row, typically the unit.
catalogReturned instead of indicators when no filter was given, and also when nothing matched — it lists what this user actually has, so the model picks from reality rather than re-guessing keywords.
truncatedIndicator → total available, when a series was cut by limit. The fix is a narrower window or an aggregate, not a bigger limit.

rsid string | string[] required

dbSNP identifiers — "rs4988235" or ["rs1801133", "rs429358"]. A comma-separated string also works.

limit integer default: 100

Maximum variants returned.

include_nearby boolean default: true

Also return variants within nearby_range of each hit, capped at 20 per hit. Set false for exact lookups only.

nearby_range integer default: 1000000

Half-window in base pairs.

This reads the user’s own uploaded genotype file, not a reference database. Consumer arrays type a small fraction of the genome, so absent ≠ negative: an rsID missing from the result was not typed, and says nothing about the allele.

Additional tools from the DeepAgent harness

Section titled “Additional tools from the DeepAgent harness”

Two tools on the list above are not the whole story for DeepAgent: its deepagents harness contributes more, and those extras are not MCP tools — an outside MCP client does not see them.

From the harnessWhat it is
ls · read_file · write_file · edit_file · glob · grepThe native file tools, operating on the PostgreSQL-backed virtual filesystem. read_file on an uploaded PDF hands the model the original document, multimodally, instead of a lossy extraction.
evalA persistent, in-process JavaScript REPL from langchain-quickjs — how the model does real computation over data it fetched.
Agent SkillsNot tools: SKILL.md procedures injected as frontmatter and read in full only when a task calls for it. See Agent Skills.

delete is excluded by name because the PostgreSQL filesystem backend does not implement it. There is no task subagent and no write_todos.