Pure instruction-pack skill wrapping Ai2's Asta MCP server (Semantic Scholar). Intent-to-tool routing, safe defaults, multi-agent.
SaferSkills independently audited asta-skill (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Asta is Ai2's Scientific Corpus Tool, exposing the Semantic Scholar academic graph over MCP (streamable HTTP transport). This skill tells agents which Asta tool to call for which intent, and how to compose them into useful workflows.
https://asta-tools.allen.ai/mcp/v1x-api-key header (request key at https://share.hsforms.com/1L4hUh20oT3mu8iXJQMV77w3ioxm)Before invoking any tool, verify the Asta MCP server is registered in the host agent. Tool names will be prefixed by the MCP server name chosen at install time (commonly asta__<tool> or mcp__asta__<tool>).
If no Asta tools are visible, do not make raw HTTP calls or invent results. Tell the user to register https://asta-tools.allen.ai/mcp/v1 as a streamable HTTP MCP server with an x-api-key header, then restart/reload the host. Minimal setup hints:
[mcp_servers.asta] url = "https://asta-tools.allen.ai/mcp/v1" and env_http_headers = { "x-api-key" = "ASTA_API_KEY" } to ~/.codex/config.toml.claude mcp add -t http -s user asta https://asta-tools.allen.ai/mcp/v1 -H "x-api-key: $ASTA_API_KEY".https://asta-tools.allen.ai/mcp/v1 with header { "x-api-key": "<YOUR_API_KEY>" }.| User intent | Asta tool | Notes |
|---|---|---|
| Broad topic search | search_papers_by_relevance | Supports venue + date filters |
| Known paper title | search_paper_by_title | Optional venues + publication_date_range filters |
| Known DOI / arXiv / PMID / CorpusId / MAG / ACL / SHA / URL | get_paper | Single-paper lookup |
| Multiple known IDs at once | get_paper_batch | Batch lookup — pass ids as a JSON array (not a comma-separated string, unlike snippet_search's paper_ids); prefer over N sequential get_paper calls; unresolvable IDs are silently dropped (no null/error), so reconcile returned paperIds against your input |
| Who cited paper X | get_citations | Forward citations, paginated; accepts publication_date_range but not venues; limit defaults to 100 |
| Find author by name | search_authors_by_name | Default fields="name" returns only name + authorId — explicitly request affiliations,paperCount,citationCount,hIndex,externalIds to get anything rankable; externalIds carries ORCID/DBLP |
| An author's publications | get_author_papers | Pass author id; field param is `paper_fields` (not fields); limit defaults to 1000 — set it explicitly |
| Find passages mentioning X | snippet_search | ~500-word excerpts (title/abstract/body, excludes captions & bibliography); see snippet-specific params below |
Most search/citation tools accept `publication_date_range` (format YYYY-MM-DD:YYYY-MM-DD; year shorthand like "2021:", ":2015-01", "2015:2020" is also accepted), `venues`, and `fields` for field selection — pass them whenever the user's intent constrains scope (e.g., "recent", "since 2022", "at NeurIPS"). venues matches Semantic Scholar's exact venue strings (comma-separated, e.g. "Nature,N. Engl. J. Med."); a casual name like "NeurIPS" may not match, so fall back to a date/keyword filter when a venue lookup returns empty.
Per-tool parameter exceptions (verified against the live server — getting these wrong yields a malformed or silently-ignored argument):
get_author_papers names its field-selection param `paper_fields`, not fields (passing fields= is silently ignored — you get titles only), and accepts no venues filter, so narrow its results by topic/venue client-side.get_citations accepts publication_date_range but not venues.snippet_search accepts neither fields nor publication_date_range. Instead it has: `inserted_before` (date filter, YYYY-MM-DD/YYYY-MM/YYYY), `paper_ids` (comma-separated list of ≤100 IDs to restrict snippets to specific papers), and venues.fields parameter — avoid context blowupsget_paper / get_paper_batch accept a fields string. Never request `citations` or `references` via fields — a single highly-cited paper (e.g. Attention Is All You Need) returns 200k+ characters and will overflow the agent's context window. Use the dedicated get_citations tool for forward citations (it paginates). Asta does not provide a dedicated get_references tool — to retrieve a paper's reference list, use get_paper with fields=references only for papers you know have a small reference list (typically < 100).
Watch row counts too, not just per-row size: default limits are large — get_author_papers returns up to 1000, get_citations 100, search_papers_by_relevance 50, and snippet_search 20 (each snippet is ~500 words, making it the heaviest tool per row). Pass an explicit small limit — e.g. 20–50 for paper/citation lists, ~5–10 for snippets — unless the user asked for the full list.
Use task-specific field presets:
Metadata lookup:
title,year,authors,venue,tldr,url,abstractSearch/ranking/results tables:
title,year,authors,venue,tldr,url,abstract,citationCount,influentialCitationCountDOI/export handoff:
title,year,authors,venue,tldr,url,externalIdsAdd journal, publicationDate, fieldsOfStudy, isOpenAccess only when needed. If pass-through fields such as citationCount are absent in a future response, degrade gracefully: sort by relevance/recency and omit citation-based claims.
Example call (topic search, ranked by citations, DOI exposed for downstream fetch):
search_papers_by_relevance(
keyword="mixture of experts routing",
publication_date_range="2023:",
fields="title,year,authors,venue,tldr,url,externalIds,citationCount",
limit=20,
)Asta's official fields list does not include externalIds, but the field is transparently passed through to the underlying Semantic Scholar API and works in practice. Add externalIds to fields to retrieve DOI, PubMed, PubMedCentral, ArXiv, MAG, DBLP, CorpusId. The same pass-through applies to `citationCount` and `influentialCitationCount` (also absent from the official list but verified to return) — request them when ranking results by citations. Caveats:
ArXiv + CorpusId.get_paper("DOI:...") lookup is not 100% reliable; some valid DOIs return not found. Prefer searching by title first, then reading externalIds off the result.search_papers_by_relevance(keyword, publication_date_range="<current_year-5>:", venues=?, fields="title,year,authors,venue,tldr,url,abstract,citationCount,influentialCitationCount", limit=20) → initial hits (compute the lower bound from today's date — e.g., in 2026 pass publication_date_range="2021:"; adjust or drop the filter if the user asks for older work)get_citations on the most influential, or snippet_search for specific claimsget_paper(DOI|arXiv|...) → verify seedget_citations(paperId) → forward expansionsearch_papers_by_relevance with seed title terms for sideways discoverysearch_authors_by_name(name, fields="name,affiliations,paperCount,citationCount,hIndex,externalIds") → pick correct profile. You must request these fields — the default fields="name" returns only name + authorId, leaving nothing to rank on. Disambiguate by externalIds.ORCID when present (strongest signal), then paperCount/citationCount/hIndex; affiliations is often empty even when requested, so use it only as a tiebreakerget_author_papers(authorId, limit=50, paper_fields="title,year,authors,venue,tldr,url,abstract,citationCount") → a bounded first page; expand only if the user asks for the full listsnippet_search(claim_query) → find passages making/supporting a claimpaper_ids="<id1>,<id2>,…" (≤100) so snippets are drawn only from that setget_paper(id) for full metadatasearch_paper_by_title before get_paper.abstract or venue, say so rather than inventing.| Situation | What to do |
|---|---|
Empty abstract | Not all corpus papers have full text — use snippet_search, or fall back to title + TLDR |
| Author disambiguation uncertain | Request the ranking fields up front (see Pattern 3 — they are not returned by default); prefer externalIds.ORCID, then paperCount/citationCount/hIndex, with affiliations only as a tiebreaker |
| Date-filtered results | A publication_date_range filter can return records whose publicationDate is null (only year is guaranteed), and papers with unknown dates are treated as published Jan 1 of their year — so boundary-year filtering is approximate |
429 Too Many Requests | Back off; batch with get_paper_batch instead of sequential get_paper calls |
| Need DOI / PubMed ID / arXiv ID | Add externalIds to fields (see "Retrieving DOI" above); fall back to ArXiv ID when DOI is absent |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.