Search AO3 (Archive of Our Own) and have fanfictions read by a secondary model (Gemini) before they're recommended
ao3-mcp is a specialized single-purpose server with 5 well-motivated tools focused on AO3 searching and reading delegation. Tool names follow verb_noun conventions (search_works, find_tags, get_work, read_works, get_work_text). Descriptions are detailed and rich, contextualizing the READING DELEGATION pattern, the core innovation, within each tool's docstring. Parameters are largely well-typed and described. However, there are measurable gaps: (1) some parameters lack explicit enums where they should have them (e.g., 'rating', 'categories', 'sort_by'), (2) no explicit output schemas are documented, (3) error handling guidance is absent from tool docstrings, (4) the 'query' parameter in search_works is dense and relies heavily on inline documentation rather than structured constraints. The server compensates with domain-specific context (AO3-specific operators, wildcard advice) embedded in descriptions, which aids LLM decision-making. Per-tool average: 62.
Resolve fuzzy wording to canonical AO3 tag names via the live autocomplete endpoint. Helps disambiguate exact tag names when you're unsure of the canonical spelling.
Retrieve full metadata card for one work by numeric AO3 id. Returns title, authors, fandoms, rating, category, word count, chapter count, publication status, kudos, hits, comments, bookmarks, summary, tags, relationships, characters, and update date.
Escape hatch: retrieve raw fanfiction text for one work, bypassing the reader model. Returns the full text of the fic (capped at 100k characters). Use only when you need to read the fic yourself; normal workflow delegates reading to read_works.
Delegate reading 1-20 fanfictions to the Gemini mini reader model. This is the core workflow: after searching and shortlisting, hand promising work ids to read_works and get back structured digests (plot, characters, prose quality, content notes) without the main AI ever reading the full fic text. Supports batching and comparison across multiple fics.
Search AO3 for works. All filters optional; combine freely. Results show numeric work ids, not URLs. Each result shows a kudos-to-hits ratio (k/h) — AO3's most honest quality proxy. Supports AO3's full operator syntax including wildcards.
No output schemas documented for any tool. Each tool description promises specific return values (get_work lists 17 fields, read_works promises 'structured digests', get_work_text promises raw text up to 100k chars), but none are formally specified as JSON Schema or structured type definitions. LLMs cannot reliably extract fields from unstructured prose.
Enum constraints missing for constrained parameters. 'rating' (search_works) accepts a free string but should be an enum: {not rated, general, teen, mature, explicit}. 'categories' should be an enum: {gen, f/m, m/m, other, f/f, multi}. 'sort_by' should be an enum: {relevance, kudos, hits, comments, bookmarks, words, date_updated, date_posted}. 'kind' (find_tags) should be an enum: {tag, fandom, relationship, character}. Free strings invite hallucinated invalid values.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 54 | 2026-07-28+ | v2 |
The 'query' parameter (search_works) documents AO3 operator syntax inline but does not provide a machine-parseable format. The documentation is thorough (e.g., 'words>10000', 'sort:kudos', 'otp: true') but buried in prose. An LLM must parse this text to construct valid queries. Recommend: provide examples as an enum or a linked documentation reference, or extract common operators into separate parameters (e.g., min_word_count, max_word_count, exclude_term) to reduce LLM reasoning burden.
No error handling guidance in tool docstrings. None of the 5 tools document what errors are possible, how to recover, or whether errors are retryable. For example, read_works delegates to Gemini and could timeout, fail due to rate limits, or refuse explicit/extreme content (mentioned in SERVER_INSTRUCTIONS but not in the tool description). Agents need explicit recovery guidance.
Pagination design in search_works is non-standard. 'pages' parameter defaults to 1 and is 'capped at 5 per call', but documentation doesn't clarify whether this is a limit per tool call or a hard server limit. For large result sets, typical pagination uses 'limit' + 'offset' or 'cursor'. The current design (page=1, pages=5) requires the LLM to compute page numbers, which is error-prone.