Skip to main content
Glama

Inciteful

Query a citation graph with SQL

query_citation_graph
Read-onlyIdempotent

Run your own read-only SQLite query on the citation graph Inciteful builds around 1–500 seed papers (depth 2). It queries the Inciteful citation graph API; schema: https://incitefulmed.com/academic/help/power-users#database-schema Rules: a single SELECT statement. Rows returned: the limit argument if given, else the query's trailing LIMIT, else 100; at most 500. OFFSET (and LIMIT a, b) is rejected; page with a narrower WHERE or an ORDER BY instead.

Schema:

  • papers(paper_id TEXT: OpenAlex ID (W…); doi TEXT without the https://doi.org/ prefix; authors TEXT: JSON array of {author_id, name, sequence, position, institution {id, name, ror}}; num_authors INTEGER; title TEXT; published_year INTEGER; journal TEXT; num_citing INTEGER; num_cited_by INTEGER; distance INTEGER; page_rank REAL; adamic_adar REAL; cocite REAL). num_citing and num_cited_by are in-graph counts (citations between papers in this graph), not global citation counts.

  • authors(author_id TEXT: OpenAlex author ID without the A prefix; paper_id TEXT; name TEXT; sequence INTEGER, from 0; affiliation TEXT; affiliation_id TEXT: OpenAlex institution ID without the I prefix; ror TEXT: ROR URL; published_year INTEGER; partial_page_rank REAL: the author's share of the paper's page_rank)

  • metadata(name TEXT, value TEXT): one row each for graph_depth, graph_snapshot, prune_threshold, highly_cited_not_expanded, seeds_not_expanded, paper_count, citation_count. value is TEXT; use CAST(value AS INTEGER) to compare numbers.

  • title_search(paper_id, search_text): an FTS5 index of the titles with Porter stemming; search_text holds the titles (paper IDs are indexed too). Query it as a table function, starting the match text with the column filter: SELECT paper_id FROM title_search('search_text: vagus AND nerve'). AND, OR, NOT and parentheses work; bm25(title_search) ranks matches, smaller is better.

  • title_terms(term, doc_count): the stemmed title terms and the number of papers each appears in, leaving out a few common words.

  • The Research Organization Registry (active organizations), attached as ror; join on authors.ror = ror.organizations.ror_url: organizations(ror_id, ror_url, display_name, status, established, types, country_code, country_name, city, latitude, longitude), names(ror_id, name, name_types, language), external_ids(ror_id, id_type, preferred_id, external_id), relationships(ror_id, related_ror_id, related_name, relationship_type).

What the schema cannot tell you:

  • There is no edge table, so SQL cannot tell which papers cite which.

  • Papers with no citation inside the graph have NULL num_citing, num_cited_by, distance, page_rank, adamic_adar and cocite.

  • With one seed, the seed is at distance 0, its citing and cited papers at 1 and their neighbours at 2, so distance > 0 leaves the seed out. With several seeds a synthetic paper W0 ("Temp Paper", year 1900) cites every seed: W0 is at distance 0, the seeds at 1 and their neighbours at 2, so distance > 1 leaves out W0 and the seeds; otherwise add paper_id <> 'W0'. Then cocite is NULL in every row (nothing cites W0) and adamic_adar is measured against W0.

Examples:

  1. One seed: the highest-PageRank papers since 2020 with "stimulation" in the title: SELECT paper_id, title, published_year, page_rank FROM papers WHERE distance > 0 AND published_year >= 2020 AND paper_id IN (SELECT paper_id FROM title_search('search_text: stimulation')) ORDER BY page_rank DESC LIMIT 20

  2. Authors ranked by their share of PageRank: SELECT author_id, name, COUNT(*) AS papers, SUM(partial_page_rank) AS influence FROM authors GROUP BY author_id, name ORDER BY influence DESC LIMIT 20

Input Schema

NameRequiredDescriptionDefault
sqlYesA single SQLite SELECT statement.
limitNoRows to return, at most 500. Default: the query's trailing LIMIT (capped at 500), else 100.
seedsYes1–500 seed papers: DOIs, OpenAlex IDs (W…) or PMIDs. Duplicates count once.

Output Schema

NameRequiredDescriptionDefault
rowsYes
truncatedYes
provenanceYes
diagnosticsNo
inciteful_urlYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, it discloses row-return precedence and the 500 cap, the absence of an edge table (so no paper-to-paper citation edges), NULL semantics for isolated papers, and the subtle synthetic W0 behavior with multiple seeds that silently breaks cocite and shifts adamic_adar. These are exactly the traps that produce wrong results silently, and they are stated up front.

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?

It is long, but it is clearly sectioned into purpose, rules, schema, caveats, and examples, and the single most important constraint is front-loaded in the first sentence. A few schema lines are dense but none are filler given that this is a general-purpose SQL surface.

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 free-form SQL tool the description carries the full burden of the queryable schema, and it delivers that plus documented gotchas and runnable examples. An output schema exists, so the absence of return-value prose is not a gap.

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 real meaning: it explains what seeds actually do (they determine the graph that is materialized, depth 2) and clarifies the limit resolution chain. The examples also demonstrate the sql parameter's practical shape beyond 'a single SELECT statement'.

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?

It names a specific verb and resource — 'Run your own read-only SQLite query on the citation graph' — and immediately bounds scope to a graph built around 1–500 seed papers at depth 2. That framing makes it distinguishable from siblings like explore_citation_network or search_literature 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 Guidelines4/5

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

It gives concrete operating rules (single SELECT only, OFFSET and LIMIT a,b rejected, page with narrower WHERE or ORDER BY) and two worked examples that show intended use. What's missing is an explicit routing statement such as 'prefer get_papers/explore_citation_network for simple lookups; use this only for aggregation the other tools can't express'.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.