search_materials tool
Finds materials from a plain-language description of the properties and composition you want. Returns up to 50 matching rows, the constraints we understood, how many materials were eliminated, and a result_set_id that the other tools use to page, refine, rank and export the full match.
| Tool | search_materials |
|---|---|
| Title | Search materials |
| Group | Find materials |
| Needs one of | professional_database or trial_database |
| Charged | Yes, against the daily allowance |
| Read-only | Yes |
| Parameters | 3, of which 1 required |
| Data as of | 2026-10-04 |
| Server release | 1.5.0, read from the live server on 2026-10-04 |
What parameters does search_materials take?
| Parameter | Type | Required | Default | What it does |
|---|---|---|---|---|
query | string | Yes | none | Plain-language description of what you want, for example "semiconductors with a band gap between 1.1 and 1.6 eV and bulk modulus above 100 GPa". It can combine property limits, element filters, a compound class, a sort such as "lowest density" and the name of a database. A language model turns it into constraints, returned in constraints. Give each value in the property's canonical unit (the unit on result rows): other units are converted only for the few properties whose vocabulary lists them, and are otherwise not converted. A constraint on water inertness or Pourbaix decomposition energy is evaluated against live Materials Project data and also needs the materials_project_data grant; without it the reply is a clarification question, not a silent skip. A query too vague to run returns clarification_needed instead of guessing. |
max_results | integer | No | 20 | How many rows to return in this response. Values above 50 are lowered to 50 and values below 1 are raised to 1; limit_requested, limit_applied and notice show what happened. This does not limit the search: total_survivors is the full match count and get_result_set pages through the stored matches. |
source_id | string or null | No | not set | Dataset to search, an id from list_material_sources. Null (the default) uses the dataset the query text names, if it names one clearly (that is not guaranteed; pass the id to be sure), and otherwise the server's default dataset. In that case an account without the professional_database grant is narrowed to the trial subset. An id that is not in the catalogue is not rejected: it falls back to the registry default, the trial subset. Asking by id for a restricted dataset your account cannot reach is refused with an error that names the missing grant. |
Which grants does search_materials need, and is it charged?
- Grants:
professional_databaseortrial_database. One of them is enough. - Charged: yes, each call uses one unit of the daily allowance (as of 2026-10-04).
Grants and the allowance are explained in Access, grants and limits.
| Annotation | Value | Meaning |
|---|---|---|
destructiveHint | false | If true, the tool may make destructive updates. It matters only when the tool is not read-only. |
idempotentHint | true | If true, calling the tool again with the same arguments has no additional effect. |
openWorldHint | false | If true, the tool may interact with an open world of external entities. |
readOnlyHint | true | If true, the tool does not modify its environment. |
What does a call to search_materials look like?
A two-property search that returns ten rows.
{
"query": "semiconductors with a band gap between 1.1 and 1.6 eV and bulk modulus above 100 GPa",
"max_results": 10
}These arguments validate against the tool's input schema, checked when the snapshot was taken on 2026-10-04. They show the shape of a call; they are not a recorded response. Examples says where worked examples stand.
How should I read search_materials results?
- Convention. There are three different counts.
total_survivorsis the exact number of matches.resultsholds at most 50 of them, andtruncatedis true when it holds fewer than the total. Up to 5000 matches are stored for get_result_set; rows beyond that were counted but never stored. A query judged to match that many or more, or a scan that runs out of time, is not answered with rows: the reply isclarification_neededwith a size estimate and ways to narrow it, and the call is refunded. - Trap. Check
sourcein every response. A source_id that is misspelt or not in the catalogue raises no error: it resolves to the registry default, the small trial subset, andrequested_sourcethen names that default too, so only a comparison with the id you sent shows the swap. A restricted dataset that was inferred from the query text, or taken as the server default, is narrowed to the trial subset without an error when your account lacks the professional_database grant; thererequested_sourcediffers fromsource. - Gap. A search can answer only part of a question without saying so. A condition the parser cannot map to a property it knows (for example coercivity) is dropped: it is not in the parsed
constraints, it has noconstraint_ledgerentry, and the matches reflect only the other conditions. Its only trace is a sentence inconstraints.open_questions, andclarification_neededandnoticestay empty. Compare the parsed constraints with what you asked. A ledger entry with state not_supported is the intended signal for a condition that is parsed but cannot be checked; extending it to dropped conditions is a planned fix, not current behaviour. Today it appears only for a parsed constraint whose property is outside the vocabulary or whose kind this server does not enforce (such as a cost ceiling or a material class); it never carries a count. Entries with state no_data count materials left out only because they have no measurement of that property.
A Convention is a field or behaviour whose meaning is not obvious, a Trap looks right and is not, and a Gap is something we do not hold or do not check. Reading results explains the classes.
How does the server describe search_materials?
This is the server's own description, which a client passes to the model, lightly normalised for display.
Search Chemia's materials corpus with a natural-language constraint query, for example "semiconductors with a band gap between 1.1 and 1.6 eV and bulk modulus above 100 GPa".
Returns the matching materials, the constraints parsed from the query, elimination counts, and a result_set_id that get_result_set can page through. If the query is too ambiguous to run, returns clarification_needed instead of guessing.
If a property named in the query has zero or below-threshold corpus coverage, the response carries property_offer instead: its note is prose written to be shown as is, naming the proxy routes that reach the property and their caveats (or, with no usable route, the irreducible verdict and what extraction would take). A ranking by such a property still returns its matches, with a property_offer saying they are not ordered by it, and ordering reads "cursor".
A property value carrying suspect is physically impossible for that property (a negative shear modulus, a density of 1,248 g/cm3): a data error in the corpus, kept with its number so it can be pointed out, and not a measurement. Real extremes (osmium's density, diamond's stiffness) are not flagged.
Every constraint is applied together in one query. eliminations holds that query's totals: matched is the number of materials meeting every constraint (equal to total_survivors) and eliminated the rest of the dataset. How many each constraint removed is in constraint_ledger.
Ranking by how much of an element a material contains works directly: "rank Sc compounds by Sc content" returns the highest atomic fraction first (weight fraction if the query says by weight), ranked across the whole match, with the value in each row's metadata element_fraction.
Rows come most stable first (lowest energy above hull, entries without one last) unless the query asks for a sort; ordering says which. That is an order, not a ranking; score_results ranks.
source_id picks a dataset from list_material_sources ("trial", "production") explicitly; a database named only in the query text is not guaranteed to be selected.
Compound classes are exact: "nitrides", "oxides", "sulfides", "halides" and the like mean compounds of two or more elements in which that element is the anion. So "nitrides" excludes N2 and nitrates, and "sulfides" excludes sulfates. Say "contains N" in the query to mean mere presence instead.
Searches cover real solids by default: frozen gases (N2, O2, He) and compounds of nonmetals alone (NH3, CO, H2O, organic crystals) are left out, and a real_solids entry in constraint_ledger says so. Say "including molecular solids" in the query to keep them.
constraint_ledger covers every constraint that is not a plain property threshold (cost ceiling, material class, operating conditions, form factor, composition, a "top N" sort). Each entry's state is applied (enforced; count is how many candidates it eliminated), not_supported (a parsed constraint that this server does not check, so no count is given: it means "not tracked", not "none match"; a condition the parser cannot map at all is dropped and shows only in constraints.open_questions), or no_data (candidates excluded from a real property check only for lacking that measurement: not a constraint failure, and not part of a same-property applied count). Plain thresholds are counted in eliminations.
max_results is capped at 50 per response; limit_applied and notice say when fewer came back than were asked for, and get_result_set pages through the rest.
Which tools are related to search_materials?
search_materials is in the group "Find materials". The other tools in it:
count_materials: Returns one exact number: how many materials meet some criteria, or how many the dataset holds when no criteria are given. Use it instead of a search whenever the question is "how many".
The Tool reference lists every tool.