Skip to main content
Glama

eutils-mcp-server

中文 · English

standard-readme compliant CI LICENSE MIT POWERED BY DEEPSEEK powered by dsh

MCP server exposing the nine NCBI Entrez E-utilities as eleven read-only tools.

It gives a language model the E-utilities directly, so it can search biomedical literature, fetch sequences, and follow links between Entrez databases without a browser and without scraping. The repository folder is named E-utilities after the API it wraps. The package, the server name, and the GitHub repository are all eutils-mcp-server.

Use it when you want an answer, not a dataset. A question such as "find papers about CRISPR delivery in 2024 and show me the abstracts" is the intended shape. Do not use it for bulk download: NCBI asks that bulk data mining use the local PubMed copy instead, and this server obeys NCBI's rate limit, so a large job takes days. Do not use it to change anything, because it is read-only and NCBI exposes no write path through these utilities.

Table of Contents

Related MCP server: PubMed MCP Server

Background

The Entrez Programming Utilities are a set of nine server-side programs at the National Center for Biotechnology Information. They share one URL syntax and cover 38 databases, including PubMed, PMC, Protein, Nucleotide, Gene, SNP, Structure, and Taxonomy. NCBI documents them in the E-utilities manual.

That interface is stable but awkward for a model to drive directly. Every request needs the same credentials, the same encoding, and the same knowledge of which endpoints accept which output formats. Batch retrieval needs the History server, which carries state across calls. NCBI blocks an IP that exceeds its rate limit.

This server puts those details in code. One client builds every URL, paces every request, follows redirects within an allowlist, caps response size, and redacts the API key. Each tool then maps one operation to one E-utilities call and returns a result the model can read.

Two upstream facts shaped the design. EGQuery is unreachable from the public internet, and the ESummary JSON limit is 500 records rather than the 10,000 the manual states. Both are recorded, with evidence, in docs/upstream-issues.md.

Install

git clone https://github.com/iwinoid/eutils-mcp-server.git
cd eutils-mcp-server
npm install
npm run build

Dependencies

Node.js 22 or newer. The version is pinned in .nvmrc.

The server has three runtime dependencies: @modelcontextprotocol/server, fast-xml-parser, and zod. The lockfile is committed. There is no installer script and no native build step.

Usage

Register the server with your MCP host. Add this to the host configuration, for example claude_desktop_config.json:

{
  "mcpServers": {
    "eutils": {
      "command": "node",
      "args": ["/absolute/path/to/E-utilities/dist/index.js"],
      "env": {
        "NCBI_API_KEY": "your-key",
        "NCBI_EMAIL": "you@example.com",
        "NCBI_TOOL": "eutils-mcp-server"
      }
    }
  }
}

To keep the key out of the host configuration, read it from .env instead:

{
  "mcpServers": {
    "eutils": {
      "command": "node",
      "args": [
        "--env-file-if-exists=/absolute/path/to/E-utilities/.env",
        "/absolute/path/to/E-utilities/dist/index.js"
      ]
    }
  }
}

Then ask the model to search. You can also call a tool directly:

npm run call eutils_esearch '{"db":"pubmed","term":"CRISPR delivery AND 2024[pdat]","retmax":3}'

The server answers with a count, a UID list, the translated query, and a History handle:

# ESearch: `CRISPR delivery AND 2024[pdat]`

Database **pubmed** matched **412** records. Showing 3 starting at 0.

## UIDs

40123456, 40123457, 40123458

## History handle

{"db":"pubmed","web_env":"MCID_6aa2...","query_key":"1"}

The count changes as PubMed grows. Confirm that you see a count and three UIDs.

Configuration

Every variable is optional. NCBI asks automated clients to identify themselves, and an API key raises the rate limit.

Variable

Default

Purpose

NCBI_API_KEY

unset

Raises the ceiling from 3 to 10 requests per second. Get one from the Settings page of your NCBI account.

NCBI_EMAIL

unset

Contact address sent with every request. NCBI uses it to warn you before an IP block.

NCBI_TOOL

eutils-mcp-server

Name that identifies this software in the NCBI logs.

Supply the values in the env block of your host configuration, or keep them in a .env file at the project root and launch the server with --env-file-if-exists. npm start and npm run dev pass that flag for you. When the file is absent, Node prints not found. Continuing without it. and the launch continues, so a missing .env cannot break startup. The path resolves against the working directory. Give an absolute path when your host launches the server from elsewhere.

.gitignore excludes .env. It does not exclude a host configuration file. Check that file before you commit it.

Set NCBI_EMAIL and NCBI_TOOL, then register both with NCBI by mail to eutilities@ncbi.nlm.nih.gov. A request that carries the values without prior registration does not satisfy the NCBI usage policy.

Subscribe to the Entrez Utilities announcement list at the same address. It is the only NCBI channel that reports known bugs. The NCBI Insights blog reports planned changes only, and the release notes inside the E-utilities manual stop at 2015.

Rate limits

NCBI blocks an IP that exceeds its limit. All requests, including internal batches, pass through one token bucket.

  • 3 requests per second without an API key

  • 10 requests per second with one

NCBI asks that large jobs run at a weekend. On a weekday, run them between 21:00 and 05:00 US Eastern time.

Limits

  • Entrez only. The server reads what Entrez indexes. Data that lives outside Entrez is not reachable.

  • retmax ceilings. eutils_esearch accepts up to 10,000. eutils_esummary and eutils_efetch accept up to 500 per call. A larger UID list is split into batches of 500, and the response reports batches.

  • PubMed and PMC caps. ESearch reaches only the first 10,000 records of a PubMed or PMC result set. Add date filters to segment a larger set.

  • Truncation. The server cuts a response over 25,000 characters. The message says how to page or narrow the query.

  • Response ceiling. The client abandons a response body over 5 MB.

  • stdio only. No HTTP transport. To add one, bind 127.0.0.1 and validate the Origin and Host headers.

  • EGQuery coverage. EGQuery itself is unreachable, so eutils_egquery covers 12 databases instead of 38. See below.

Known upstream issue: EGQuery

NCBI's egquery.fcgi answers with an HTTP 301 to ext-http-eutils.linkerd.ncbi.nlm.nih.gov. That host is not published in public DNS.

Two independent DNSSEC-validating resolvers, Cloudflare and Google, both return NXDOMAIN for the name. A control query for eutils.ncbi.nlm.nih.gov resolves normally.

Every parameter combination tried redirects: GET and POST, with and without retmode, retmax, tool, email, a browser User-Agent, and HTTP/1.0.

An API key does not help. With a valid key, esearch returns 200 while egquery still returns 301 in the same session. A syntactically invalid key makes egquery return 400 API key invalid instead. That result shows NCBI validates the key before it routes the request, so the redirect is not a credentials or rate-limit decision.

Run npm run doctor to reproduce the finding on your own network. The full evidence chain, and the other upstream defects found while building this server, are in docs/upstream-issues.md.

eutils_egquery tries the real EGQuery first. Only a network failure starts the fallback, and then the server counts matches with ESearch over 12 commonly used databases. The result carries degraded: true, a reason, and a note. Read that marker as "this covers a subset, not all 38 databases". A validation error never starts the fallback, so a bad query cannot cost 12 extra requests.

The fallback is lazy. If NCBI repairs the endpoint, the real EGQuery returns and no code changes.

Security

The server is read-only and holds no listener. It never writes to disk. There is no port for an attacker to connect to: the only network traffic is outbound HTTPS from the server to NCBI.

Threat

Control

Prompt injection carried by record text

The server fences NCBI record text between <<<EXTERNAL_NCBI_DATA markers and labels it as data. It strips fence markers from the content, so the content cannot close the fence early. The server never writes, so it cannot become a deputy for a destructive action.

Parameter injection

The server validates db against a character-class guard and a 38-database allowlist. It validates UIDs, search terms, and History fields before use. It encodes every value with URLSearchParams and never builds a URL by concatenation.

API key leakage

The server masks api_key in every log line, error message, and response. It never echoes the constructed URL to the model. stdio logging goes to stderr only.

SSRF

The base URL is a constant, not an environment setting. The client follows redirects manually, at most three hops, and every hop must end with .ncbi.nlm.nih.gov.

Resource exhaustion

A token bucket, per-endpoint retmax ceilings, a 5 MB response ceiling, a request timeout, and bounded retries with backoff.

Malicious XML

Entity processing is off. The client strips DOCTYPE declarations and caps the body size before parsing.

Supply chain

Three runtime dependencies. The lockfile is committed.

Report a vulnerability through the issue tracker.

API

Eleven tools. Every tool accepts response_format of "markdown" or "json", and defaults to markdown. Every tool reports readOnlyHint: true and destructiveHint: false, and declares an outputSchema that its own result satisfies.

Tool

Purpose

eutils_einfo

List databases, or describe one database: searchable fields, links, record count

eutils_esearch

Search a database. Returns UIDs and a History handle

eutils_epost

Upload a UID list to the NCBI History server

eutils_esummary

Compact summaries for a UID set: title, authors, journal, date

eutils_efetch

Full records: PubMed abstracts, FASTA sequences, other formats

eutils_elink

Follow links between databases, for example pubmed to pmc, or gene to protein

eutils_egquery

Count matches across many databases at once

eutils_espell

Spelling suggestion for a query

eutils_ecitmatch

Resolve formatted citations to PMIDs

eutils_search_then_fetch

Search and download in one call

eutils_link_then_fetch

Follow links and download the target records in one call

Each tool takes one of the nine E-utilities as its subject. The tool name carries the E-utilities name after the eutils_ prefix, so eutils_esearch calls esearch.fcgi. Parameter names follow the API, so the manual applies directly.

Working with large result sets

The server keeps no state. The History handle travels as an ordinary value, so you pass it back unchanged.

eutils_esearch(db="pubmed", term="...", retmax=0, usehistory=true)
  -> { total: 16896, history: { db, web_env, query_key } }

eutils_efetch(history={...}, retstart=0,   retmax=500)
eutils_efetch(history={...}, retstart=500, retmax=500)

Run the inspector to read the full input and output schema of every tool:

npm run build
npx @modelcontextprotocol/inspector node dist/index.js

Maintainers

@iwinoid

Contributing

Ask questions in the issue tracker. Pull requests are accepted.

Read CONTRIBUTING.md before you open one. It states the development commands, the requirements a pull request must meet, and how to read the coverage number.

This project follows the Contributor Covenant, version 2.1.

License

MIT © iwinoid

NCBI supplies the data. If you redistribute this software or its output, NCBI's Disclaimer and Copyright notice must be evident to users. PubMed abstracts can be protected by copyright. Redistribution beyond fair use needs the permission of the copyright holder.

Available Tools

11 tools
eutils_ecitmatchBatch Citation to PMID LookupA
Read-onlyIdempotent

Resolve formatted citation strings to PubMed IDs.

Use this when you have a reference list but no PMIDs. It is far more reliable than free-text searching for a specific article.

Args:

  • citations (string[]): each string formatted as journal_title|year|volume|first_page|author_name|your_key| A trailing pipe is optional and is added for you.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { submitted, matched, records: [{ input, journal, year, volume, first_page, author, key, pmid, matched }] }

Examples:

  • Use when: "find the PMID for Mann BJ, Proc Natl Acad Sci USA 1991;88:3248" -> citations=["proc natl acad sci u s a|1991|88|3248|mann bj|Art1|"]

  • Use when: converting a bibliography into PMIDs before fetching abstracts

  • Don't use when: you are searching by topic (use eutils_esearch)

Error Handling:

  • Rejects a citation string with fewer than six pipe-separated fields

  • Reports matched=false per citation when NCBI finds no corresponding record

ParametersJSON Schema
NameRequiredDescriptionDefault
citationsYesCitation strings, each formatted as journal_title|year|volume|first_page|author_name|your_key|. Example: "science|1987|235|182|palmenberg ac|Art2|".
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
matchedYes
recordsYes
submittedYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/openWorld/idempotent/destructive=false, so safety is handled. The description adds real value beyond them: validation behavior (rejects strings with fewer than six fields) and per-citation matched=false semantics when NCBI finds no record. This is meaningful error/edge-case disclosure not present in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose sentence, then cleanly sectioned Args/Returns/Examples/Error Handling. Slightly verbose with both Returns and a detailed Examples block, but each section carries distinct information and no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists, the description restates the return shape and adds the matched-flag semantics that help the agent interpret partial matches. Validation rules, format spec, alternatives, and examples are all present for a 2-param tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds the pipe-delimited field semantics, the note that the trailing pipe is optional and auto-added, and a worked example mapping a human citation to the array form. That exceeds what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Resolve') and resource ('formatted citation strings to PubMed IDs'), and immediately frames the scope against free-text searching. An agent can distinguish this from eutils_esearch without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('when you have a reference list but no PMIDs', converting a bibliography), explicit when-not ('searching by topic - use eutils_esearch'), and names the alternative sibling. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_efetchEntrez Full RecordsA
Read-onlyIdempotent

Download full records in a chosen format.

Defaults are chosen for readability: PubMed returns plain-text abstracts, and sequence databases return FASTA. Returned record text is external data and is fenced with an explicit marker.

Args:

  • db (string, optional): database, for example "pubmed". Required unless history is given.

  • uids (string[] | string, optional): UIDs or accession.version identifiers.

  • history (object, optional): handle from eutils_esearch, eutils_epost, or eutils_elink.

  • rettype (string, optional): "abstract" (pubmed default), "fasta" (sequence default), "gb", "docsum", "medline", ...

  • retmode ('text' | 'xml', optional): default "text".

  • retstart (number, optional): first record index, for history sets.

  • retmax (number, optional): records to return for a history set. Default 20, max 500.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Supply either uids or history, never both.

Returns: { database, rettype, retmode, record_count?, batches?, text }

Examples:

  • Use when: "give me the abstract for PMID 31452104" -> db="pubmed", uids=["31452104"]

  • Use when: "fetch the protein sequence" -> db="protein", uids=["NP_005537.3"], rettype="fasta"

  • Use when: downloading a large set -> pass history and page with retstart/retmax

  • Don't use when: you only need titles and dates (use eutils_esummary, which is far cheaper)

Error Handling:

  • Asks for an explicit rettype when the database has no default

  • Detects an error message returned as record text and reports it as a tool error

  • Refuses retmax above 500; larger sets are batched internally

ParametersJSON Schema
NameRequiredDescriptionDefault
dbNoEntrez database, for example "pubmed". May be omitted when history is given.
uidsNoUIDs or accession.version identifiers, as an array or a comma-separated string. Example: ["31452104", "31452105"].
retmaxNoMaximum records to return when using history (default 20, max 500).
historyNoPointer to a UID set stored on the NCBI History server. Pass back the object returned by a previous call, unchanged.
retmodeNoResponse encoding. Default "text", which is what you want for abstracts and FASTA.
rettypeNoRecord format. Defaults to "abstract" for pubmed and "fasta" for sequence databases. Other databases need an explicit value, for example "gb" or "docsum".
retstartNoIndex of the first record to return. Use with history.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
textYesRaw record text. The markdown rendering fences it as external data.
batchesNo
retmodeYes
rettypeYes
databaseYes
record_countNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open-world), and the description adds genuinely new behavior: DB-specific defaults, external-data fencing, retmax>500 refusal with internal batching, error-text detection, and explicit rettype prompting. This goes well beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose followed by cleanly labeled Args/Returns/Examples/Error Handling sections. The Args block partially duplicates schema descriptions, but for an 8-parameter tool with several behaviors the length is justified, not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists and annotations carry the safety profile, the description still supplies everything an agent needs: format defaults, source selection rules, paging limits, and error behavior. No material gap remains for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, but the description adds meaning the schema lacks: the mutual-exclusivity rule ('supply either uids or history, never both'), per-database rettype default semantics, and the purpose of retstart/retmax as history-only paging controls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Download full records') and immediately clarifies the format behavior. It differentiates itself from siblings, notably by naming eutils_esummary as the cheaper tool for titles/dates, so an agent can distinguish it within the E-utilities family without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use when' examples (abstract fetch, sequence fetch, large-set download) plus a 'Don't use when' exclusion routing to eutils_esummary. It also states the history-vs-uids selection rule and the paging strategy with retstart/retmax.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_egqueryGlobal Entrez QueryA
Read-onlyIdempotent

Search every Entrez database at once and report how many records each one matches.

Use this to find which database holds data for a topic before committing to a search. It returns counts only, never records.

Args:

  • term (string): Entrez text query, for example "CRISPR base editing".

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { term, databases_searched, databases_with_hits, hits: [{ db, menu, count, status }] (sorted by count, descending), empty_databases: string[] }

Examples:

  • Use when: "which database has information about BRCA1 variants?" -> term="BRCA1 variants"

  • Don't use when: you already know the database (use eutils_esearch instead)

Error Handling:

  • Returns "The search term was empty" when term is blank

  • NCBI EGQuery redirects to an internal host that is not published in public DNS, for every client including ones with a valid API key. When the real EGQuery is unreachable this tool falls back to per-database ESearch counts over 12 commonly used databases, and says so in a "degraded" field. Counts are then a subset, not all 38.

  • The fallback triggers only on a network failure, never on a validation error.

ParametersJSON Schema
NameRequiredDescriptionDefault
termYesEntrez text query to run against every database at once.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
hitsYes
termYes
degradedNoTrue when the fallback produced this result.
degraded_reasonNo
empty_databasesYes
databases_searchedYes
databases_with_hitsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, open-world safety, and the description adds materially more: counts-only output, a degraded-mode fallback limited to 12 of 38 databases, the DNS/redirect cause, the exact fallback trigger condition (network failure, never validation error), and the blank-term error string. This is unusually rich disclosure for a read tool with full annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then cleanly sectioned into Args, Returns, Examples, and Error Handling. Despite its length, every section carries non-redundant operational information, particularly the degraded-mode caveat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists, the description spells out the full return shape including the degraded field, sorting order, and empty_databases, plus failure modes. Nothing an agent needs to interpret a result or handle a fallback is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented, and the description largely restates them. The example query 'CRISPR base editing' adds a small amount of concreteness about term format, but no syntax, limits, or field-qualifier guidance beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search every Entrez database at once') plus the exact output contract ('report how many records each one matches'). The 'Don't use when' line explicitly separates it from eutils_esearch, so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides both a positive trigger ('find which database holds data for a topic before committing to a search') and an explicit exclusion with the named alternative ('you already know the database (use eutils_esearch instead)'). The worked example ('which database has information about BRCA1 variants?') makes the intent unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_einfoEntrez Database InfoA
Read-onlyIdempotent

List Entrez databases, or describe one database's searchable fields and links.

Call with no arguments to list all Entrez databases. Call with db to get that database's record count, last update time, searchable field names, and the links available to other databases.

Args:

  • db (string, optional): database to describe, for example "pubmed". Omit to list all.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: Without db: { count, databases: string[] } With db: { database, menu_name, description, record_count, last_update, build, field_count, fields: [{ name, fullname, description, termcount? }], link_count, links: [{ name, dbto, menu }] }

Examples:

  • Use when: "what fields can I search in PubMed?" -> db="pubmed"

  • Use when: "which Entrez databases exist?" -> no arguments

  • Use when: "what databases link from a gene record?" -> db="gene"

  • Don't use when: you want record counts for a query (use eutils_egquery instead)

Error Handling:

  • Rejects a database name that is not one of the known Entrez databases, and lists samples

  • Returns a parse error if NCBI changes the response shape

ParametersJSON Schema
NameRequiredDescriptionDefault
dbNoEntrez database to describe, for example "pubmed" or "protein". Omit to list all databases.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
countNoNumber of Entrez databases, when no db was given.
linksNo
fieldsNo
databaseNoDatabase name, when db was given.
databasesNoDatabase names, when no db was given.
link_countNo
field_countNo
record_countNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so safety is covered. The description goes further by disclosing error behavior (unknown db names are rejected with samples; parse errors if NCBI changes the response shape) and by enumerating exactly what data each mode returns, including last_update and record_count.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core behavior is front-loaded in the first paragraph, followed by clearly labeled Args, Returns, Examples, and Error Handling sections. The Returns block partly duplicates the output schema, but the Examples and Error Handling sections earn their space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter, zero-required tool with a full output schema and rich annotations, the description covers both modes, the argument semantics, worked examples, sibling routing, and failure modes. An agent has everything needed to select and invoke it correctly; return-value detail is a bonus given the output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds genuine meaning beyond the schema by explaining the consequence of each choice: omitting db yields the full list, supplying db yields record count, last update, searchable fields, and outbound links. The response_format enum is already fully documented in the schema and is merely restated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb (List / describe) applied to a precise resource (Entrez databases and their searchable fields and links). It cleanly separates the two operating modes (no args = list, db = describe), which lets an agent pick the right call without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete when-to-use examples mapped to inputs ("what fields can I search in PubMed?" -> db="pubmed") and an explicit don't-use case that names the alternative sibling (eutils_egquery) for record counts on a query. The choice between this tool and its closest sibling is fully resolved.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_epostUpload UIDs to Entrez HistoryA
Read-only

Upload a list of UIDs to the NCBI History server and get a reusable handle.

Use this when you already have UIDs from somewhere other than an ESearch, or when you want to combine several sets. Many thousands of UIDs fit in one call.

Args:

  • db (string): database the UIDs belong to, for example "gene".

  • uids (string[] | string): UIDs or accessions, as an array or comma-separated string.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { database, uploaded, history: { db, web_env, query_key } }

Examples:

  • Use when: "fetch these five gene IDs" -> db="gene", uids=["7173","22018","54314"]

  • Use when: combining UID lists from two sources before one download

  • Don't use when: you are about to search; ESearch with usehistory already posts its own results

Error Handling:

  • Rejects UIDs containing URL metacharacters

  • Reports an upstream error if NCBI returns no History handle

ParametersJSON Schema
NameRequiredDescriptionDefault
dbYesEntrez database the UIDs belong to, for example "pubmed".
uidsYesUIDs or accessions to upload, as an array or a comma-separated string.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
historyYes
databaseYes
uploadedYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint/destructiveHint/idempotentHint), it discloses capacity (many thousands of UIDs per call), the validation rule (UIDs with URL metacharacters are rejected), and failure mode (upstream error if NCBI returns no History handle). This explains why idempotentHint is false: each call yields a fresh handle.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well structured and front-loaded: purpose first, then Args/Returns/Examples/Error Handling. The Args section largely restates the schema descriptions, which is mild redundancy, but no sentence is wasted elsewhere.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter tool with an output schema and full annotation coverage, the description supplies everything an agent needs: purpose, routing advice, parameter shapes, return shape, and error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds worked examples with real values (db="gene", uids=["7173","22018","54314"]) and restates the array-or-comma-separated flexibility of uids, which helps an agent choose a form quickly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+outcome: upload UIDs to the NCBI History server and receive a reusable handle. It distinguishes itself from the search-oriented siblings by explaining that this is the entry point when UIDs come from somewhere other than ESearch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names when to use it (UIDs from another source, combining sets), when not to use it (you are about to search; ESearch with usehistory already posts its own results), and gives concrete examples. The alternative is named and the selecting condition is stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_esearchEntrez Text SearchA
Read-only

Search an Entrez database and return matching UIDs.

This is the entry point for a retrieval pipeline. It returns UIDs, never records. By default it also stores the result set on the NCBI History server and returns a history handle, so later calls can page through the whole set without re-searching.

Entrez field tags go in square brackets: gene[tiab], 2008[pdat], mouse[orgn]. Boolean operators AND, OR, NOT must be uppercase.

Args:

  • db (string): database to search, for example "pubmed".

  • term (string): Entrez query, for example "breast cancer AND 2008[pdat]".

  • retmax (number, optional): UIDs to return, 0-10000. Default 20. Use 0 for count only.

  • retstart (number, optional): index of the first UID. Default 0.

  • sort (string, optional): "pub_date", "relevance", "first_author", ...

  • datetype ('pdat' | 'edat' | 'mdat', optional): date field for mindate/maxdate.

  • mindate, maxdate (string, optional): YYYY, YYYY/MM, or YYYY/MM/DD.

  • usehistory (boolean, optional): return a History handle. Default true.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { database, term, total, count, offset, has_more, next_offset, uids: string[], query_translation, term_translations: [{ from, to }], history? }

Examples:

  • Use when: "find papers about CRISPR in Nature" -> db="pubmed", term="CRISPR AND nature[journal]"

  • Use when: "how many records mention this gene?" -> retmax=0

  • Don't use when: you already have UIDs (use eutils_esummary or eutils_efetch)

  • Don't use when: you don't know which database (use eutils_egquery first)

Error Handling:

  • Rejects retmax above 10000 with advice to use the History server

  • Rejects an unknown database and lists valid ones

  • Returns an empty result with spelling advice rather than an error

ParametersJSON Schema
NameRequiredDescriptionDefault
dbYesEntrez database to search, for example "pubmed" or "protein".
sortNoSort order, for example "pub_date", "relevance", or "first_author". Valid values vary by database.
termYesEntrez query. Field tags go in square brackets, for example "breast cancer AND 2008[pdat]" or "mouse[orgn]".
retmaxNoMaximum UIDs to return (default 20). Use 0 to fetch only the count.
maxdateNoEnd date, as YYYY, YYYY/MM, or YYYY/MM/DD. Requires datetype.
mindateNoStart date, as YYYY, YYYY/MM, or YYYY/MM/DD. Requires datetype.
datetypeNoWhich date field mindate/maxdate apply to: pdat (publication), edat (Entrez), mdat (modification).
retstartNoIndex of the first UID to return. Use for paging.
usehistoryNoStore the result set on the NCBI History server and return a history handle (default true). Set false to skip it.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
termYes
uidsYes
countYesRecords returned on this page.
totalYesRecords matching the whole query, not just this page.
offsetYes
historyNoPresent when usehistory is true.
databaseYes
has_moreYes
next_offsetNo
query_translationYesHow Entrez rewrote the query.
term_translationsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld/idempotent annotations, the description discloses a real server-side side effect: the result set is stored on the NCBI History server and a handle returned. It also documents failure modes (retmax>10000 rejection with advice, unknown-database rejection listing valid ones, empty results returned with spelling advice rather than as errors), which an agent cannot infer from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and scoping in the first paragraph, then Args/Returns/Examples/Error Handling sections that are easy to scan. It is somewhat long and the Args block restates fields already 100% covered by the schema, so it loses a point for redundancy rather than for verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter, open-world search tool with an output schema, the description covers the return shape, the history-handle mechanism, syntax rules, and error behavior. Nothing an agent needs to call it correctly is missing, and the output schema carries the response detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so a 3 is the floor. The description adds value the schema does not: the uppercase-only rule for AND/OR/NOT and the YYYY / YYYY/MM / YYYY/MM/DD date formats, plus a consolidated default listing. Much of the Args block duplicates the schema, which caps it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Search an Entrez database and return matching UIDs") and immediately frames it as "the entry point for a retrieval pipeline" that "returns UIDs, never records." The Don't-use-when clauses name eutils_esummary, eutils_efetch, and eutils_egquery, so an agent can distinguish it from siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when/when-not routing with concrete conditionals: don't use it when you already have UIDs (use esummary/efetch), and don't use it when the database is unknown (use egquery first). The Examples block reinforces this with realistic query-to-parameter mappings, including the count-only pattern via retmax=0.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_espellSpelling SuggestionA
Read-onlyIdempotent

Get NCBI's spelling suggestion for a query in one database.

Args:

  • db (string): database to check against, for example "pubmed".

  • term (string): query to check, for example "breast cancr".

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { database, query, corrected_query, changed }

Examples:

  • Use when: a search returned no results and you suspect a typo

  • Use when: "did you mean" for a query -> term="diabetis"

  • Don't use when: the query is a structured field search; ESpell works on plain terms

Error Handling:

  • Reports changed=false when NCBI has no correction, rather than an error

ParametersJSON Schema
NameRequiredDescriptionDefault
dbYesEntrez database to check the spelling against, for example "pubmed".
termYesQuery whose spelling should be checked, for example "breast cancr".
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryYes
changedYes
databaseYes
corrected_queryYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so safety is covered. The description adds genuinely useful context beyond that: the error-handling note that changed=false is reported rather than an error when NCBI has no correction. It stops short of describing rate limits or response latency, but the error semantics are a real value-add.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded with purpose first, then structured Args/Returns/Examples/Error Handling sections. Every section earns its place except the Args block, which duplicates the schema verbatim, making it slightly longer than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists (so return explanation is optional), the description still documents the return shape and even covers the no-correction edge case. For a 3-parameter, fully-annotated tool, an agent has everything needed to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the Args section largely restates what the schema already documents for db, term, and response_format. The only marginal addition is the illustrative example term 'breast cancr', which does not deepen syntactic understanding. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get NCBI's spelling suggestion for a query in one database.' An agent can immediately distinguish this diagnostic spelling tool from search/fetch siblings like eutils_esearch or eutils_efetch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' bullets (no-results search, 'did you mean' scenario) and a 'Don't use when' exclusion for structured field searches. The alternative condition is stated precisely, so nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_esummaryEntrez Document SummariesA
Read-onlyIdempotent

Fetch compact summaries (DocSums) for a set of UIDs.

Use this to screen records by title, authors, journal, and date before paying the cost of downloading full records.

Args:

  • db (string, optional): database, for example "pubmed". Required unless history is given.

  • uids (string[] | string, optional): UIDs or accessions.

  • history (object, optional): handle from eutils_esearch, eutils_epost, or eutils_elink.

  • retstart (number, optional): first record index, for history sets. Default 0.

  • retmax (number, optional): records to return for a history set. Default 20, max 500.

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Supply either uids or history, never both.

Returns: { database, total, count, offset, has_more, next_offset?, batches?, records: [{ uid, title, authors[], journal, source, pubdate, volume, issue, pages, doi?, pmcid?, pubtype[], lang[] }] }

Non-PubMed databases return whichever scalar fields the DocSum carries.

Examples:

  • Use when: "show me the titles of these PMIDs" -> db="pubmed", uids=["31452104"]

  • Use when: screening a large result set -> pass history from eutils_esearch

  • Don't use when: you need the full abstract or sequence (use eutils_efetch)

Error Handling:

  • Refuses more than 500 UIDs per call and batches larger lists internally

  • Refuses to combine uids and history in one call

  • Rejects retmax above 500 rather than silently truncating

ParametersJSON Schema
NameRequiredDescriptionDefault
dbNoEntrez database, for example "pubmed". May be omitted when history is given.
uidsNoUIDs or accession.version identifiers, as an array or a comma-separated string. Example: ["31452104", "31452105"].
retmaxNoMaximum summaries to return when using history (default 20, max 500).
historyNoPointer to a UID set stored on the NCBI History server. Pass back the object returned by a previous call, unchanged.
retstartNoIndex of the first summary to return. Use with history.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYes
totalYes
offsetYes
batchesNoPresent when the UID list needed more than one request.
recordsYes
databaseYes
has_moreYes
next_offsetNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, open-world behavior, so the safety profile is covered. The description adds genuinely useful disclosure beyond that: internal batching above 500 UIDs, refusal to combine uids and history, and rejection of retmax >500 rather than silent truncation. It loses a point for paying output-format detail that the output schema already supplies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose, then cleanly labelled Args/Returns/Examples/Error Handling sections that are easy to scan. The Returns block restates what the output schema already provides and the Args list largely mirrors the schema, so a small amount of redundancy keeps it just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only summarizer with a full output schema and rich annotations, everything an agent needs is present: the either/or parameter rule, defaults, caps, batching behavior, and failure modes. Nothing about correct invocation is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description goes further by stating the cross-parameter constraint ("Supply either uids or history, never both") and the retmax default/max in prose form. That inter-parameter rule is the kind of semantics a schema rarely makes explicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Fetch compact summaries (DocSums) for a set of UIDs") and immediately scopes it against the heavier alternative: "Don't use when: you need the full abstract or sequence (use eutils_efetch)". An agent can distinguish this from eutils_efetch and eutils_esearch without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit "Use when" scenarios (screening titles by PMID, screening a large result set via history) and a "Don't use when" routing to eutils_efetch. It also names the sibling tools that produce the history handle, closing the loop on the prescreen-then-fetch workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eutils_search_then_fetchSearch and FetchA
Read-onlyIdempotent

Search a database and download the matching records in one call.

This is the shortcut for the common "find me the papers about X" request. It runs ESearch with a History handle, then EFetch, saving a round trip. Use the individual tools when you want to screen titles before downloading.

Args:

  • db (string): database to search, for example "pubmed".

  • term (string): Entrez query.

  • retmax (number, optional): records to download. Default 20, max 500.

  • rettype (string, optional): "abstract" (pubmed default), "fasta" (sequence default), ...

  • retmode ('text' | 'xml', optional): default "text".

  • response_format ('markdown' | 'json'): output format. Default 'markdown'.

Returns: { database, term, total, retrieved, rettype, retmode, history, text }

Examples:

  • Use when: "summarize recent papers on CRISPR delivery" -> db="pubmed", term="CRISPR delivery AND 2024[pdat]"

  • Use when: "get the sequences for these gene records" -> db="nuccore", term="..."

  • Don't use when: you want to inspect titles first (use eutils_esearch then eutils_esummary)

  • Don't use when: the result set is huge; search with retmax=0 first to see the count

Error Handling:

  • Returns a friendly empty result, with spelling advice, when nothing matches

  • Refuses retmax above 500

  • Reports the ESearch count so you can judge whether to page

ParametersJSON Schema
NameRequiredDescriptionDefault
dbYesEntrez database to search, for example "pubmed".
termYesEntrez query, for example "CRISPR AND 2024[pdat]".
retmaxNoRecords to download (default 20, max 500).
retmodeNoResponse encoding. Default "text".
rettypeNoRecord format. Defaults to "abstract" for pubmed, "fasta" for sequences.
response_formatNoOutput format: 'markdown' for human-readable text, or 'json' for machine-readable data. Default: 'markdown'.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
termYes
textYes
totalYes
historyYes
retmodeNo
rettypeNo
databaseYes
retrievedYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive, so the safety profile is covered. The description adds value beyond that: it explains the ESearch History handle mechanism, the round-trip saving, the retmax>500 refusal, and the friendly-empty-result behavior with spelling advice.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose, then organizes Args, Returns, Examples, and Error Handling. Despite covering a lot, every section earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a compound search+fetch tool, the description covers purpose, alternatives, parameters, return shape, examples, and error handling. With an output schema also present, nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes slightly beyond by noting db-specific rettype defaults ('abstract' for pubmed, 'fasta' for sequences) and restating the retmax cap, adding useful semantics not fully captured by the schema's brief descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific compound verb+resource: 'Search a database and download the matching records in one call.' It explicitly frames itself as the shortcut vs the individual tools, so an agent can distinguish it from eutils_esearch and eutils_efetch without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use when' and 'Don't use when' examples naming the alternative tools (eutils_esearch then eutils_esummary), plus guidance to search with retmax=0 when the result set is huge. This is textbook when/when-not/alternatives coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv0.1.0
    • First observedeutils_ecitmatch
    • First observedeutils_efetch
    • First observedeutils_egquery
    • First observedeutils_einfo
    • First observedeutils_elink
    • First observedeutils_epost
    • First observedeutils_esearch
    • First observedeutils_espell
    • First observedeutils_esummary
    • First observedeutils_link_then_fetch
    • First observedeutils_search_then_fetch

TDQS

A4.7/5.0

Scored across 11 tools

Disambiguation5/5

Each tool maps to a distinct E-utilities operation (search, fetch, summary, link, post, spell, cite-match, database listing, cross-db counts), and descriptions include explicit 'Don't use when' cross-references. The two composite tools (search_then_fetch, link_then_fetch) could overlap with manual chains, but the descriptions clearly state when to prefer each, e.g. use esummary first to screen titles.

Naming Consistency4/5

All tools share the eutils_ prefix and mostly follow the NCBI API names (esearch, efetch, elink), giving a predictable pattern. The two convenience tools use snake_case (search_then_fetch, link_then_fetch), which is readable but a slight deviation from the concatenated style.

Tool Count5/5

11 tools is well-scoped, essentially covering the standard NCBI E-utilities suite plus two pragmatic shortcuts. Each tool earns its place with no redundant entries.

Completeness5/5

The surface covers the full E-utilities lifecycle: discovery (einfo, egquery), searching (esearch), history management (epost), retrieval (esummary, efetch), linking (elink), and utilities (espell, ecitmatch), plus end-to-end combos. No obvious dead ends for the domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers