ao3-mcp
Connect AI agents to Archive of Our Own (AO3) for intelligent fanfiction search, reading, and recommendation, using a secondary AI model (Gemini) to read and analyze full fics, keeping the main agent's context clean.
Search AO3 with rich filters: fandom, ship, character, tags (freeform), rating, word count, completion status, categories (F/F, M/M, etc.), sorting, and free-text queries supporting AO3's search operators and wildcards. Returns up to 20 results per page, up to 5 pages.
Resolve fuzzy tags to canonical AO3 tags via live autocomplete (e.g., "coffee shop" → "Alternate Universe - Coffee Shops & Cafés") for fandoms, relationships, characters, and freeform tags.
Get full metadata for a single work by ID: tags, stats, summary, series.
Read and analyze fics (up to 20 at once, up to 150k words each) using the secondary AI, producing structured reports covering plot, characters, writing style, prose samples, content notes, and a comparative ranking when multiple fics are read together. Recommendations are based on actual content, not just author blurbs.
Retrieve raw fic text as an escape hatch for close reading or quoting (optionally capped).
Cache downloads locally for 24 hours to avoid repeated AO3 requests.
Inspiration engine for writers: get style references and structured reports on how specific tropes, narrative beats, or character voices are handled in existing fics.
Respect AO3's volunteer-run service with throttled, polite requests and Cloudflare bypass.
Search AO3 fanfiction with full filters, resolve fuzzy wording to canonical tags, and get structured reports from reading the actual fic text.
ao3-mcp
An MCP (Model Context Protocol) server that connects AI agents — Claude, Cursor, or any MCP client — to the Archive of Our Own. Search AO3 fanfiction with full filters, resolve fuzzy wording to canonical tags, and get fics actually read before they're recommended.
The trick: your agent never reads fic text. It delegates reading to a cheap secondary model (Gemini), which digests whole fics — even 150k-word novels — and returns structured reports. Your agent's context stays clean; the recommendations are based on the real text, not the blurb.
agent ──MCP──> server.py
├─ ao3.py AO3 scraping (no public API exists) — throttled and polite
└─ reader.py Gemini reads the fics, reports back: plot, style,
prose samples, content notes, a rankingWhy this beats blurb-based recommendations
An AO3 blurb is an ad written by the author. This server's workflow is: search wide (40–60 results), have the reader model read the shortlist — up to 20 full fics in one call — and recommend only what was actually read, with verbatim prose samples so quality is judged from the text itself.
Related MCP server: CodeAlive MCP
Not just for finding your next read
If you write with an AI — fanfic, original fiction, roleplay — this doubles as an inspiration engine. Mid-scene, your agent can pull up how real fic authors handle the exact beat you're on:
Find three highly-kudosed fics where rivals are forced to share a bed, read them,
and tell me how each one builds the tension — pacing, POV, what they leave unsaid.The reader reports back with structure, style notes, and verbatim prose samples, so the model gets grounded in how the trope is actually written — not what it imagines fanfic sounds like. Works the same for roleplay: pull reports on fics that nail a character's voice and feed them in as style reference.
Install
Requires Python 3.10+ and a free Gemini API key:
Go to aistudio.google.com/api-keys, sign in with any Google account, and click "Create API key". The free tier is enough — no billing setup needed.
pip install ao3-mcpAdd to your agent
Point command at ao3-mcp and pass your key with --api-key:
{
"mcpServers": {
"ao3": {
"command": "ao3-mcp",
"args": ["--api-key", "YOUR_GEMINI_KEY"]
}
}
}Prefer to keep the key out of the args list? Drop --api-key and pass it in an env
block instead — the server reads GEMINI_API_KEY from the environment as a fallback:
"env": { "GEMINI_API_KEY": "YOUR_GEMINI_KEY" }claude mcp add ao3 -- ao3-mcp --api-key YOUR_GEMINI_KEYCursor Settings → MCP → New MCP Server, paste the JSON config above.
Add the JSON config above to .gemini/antigravity/mcp_config.json.
code --add-mcp '{"name":"ao3","command":"ao3-mcp","args":["--api-key","YOUR_GEMINI_KEY"]}'Then just ask:
Find me a completed enemies-to-lovers longfic in <fandom>, read the top candidates, and tell me which is best written.Launch params
Param | Env var | Default | What it does |
|
| — | Gemini API key (required). |
|
|
| Model the reader uses. |
|
|
| Fallback model when the main one is throttled. |
|
|
| Minimum seconds between AO3 requests. |
Tools
Tool | What it does |
| Search AO3: fandom, ship, character, tags, rating, word count, completion, sorting. 20 results/page, up to 5 pages per call. The |
| Live autocomplete — fuzzy wording → canonical AO3 tag, fandom, ship, or character names. |
| Full metadata card for one work: tags, stats, summary, series info. |
| Reads 1–20 full fics with the secondary model and returns a structured report per fic — plot, characters, style, verbatim prose samples, content notes — plus a comparison ranking them against your question. |
Fic downloads are cached locally for 24h, so re-reading a fic with a new question costs no AO3 requests.
Good to know
AO3 has no API — this scrapes its (clean) HTML, one request at a time, throttled to one every 0.6s by default (tune with
--min-interval) and honoringRetry-After. AO3 is volunteer-run; the politeness is deliberate.Cloudflare: AO3 blocks plain HTTP clients. This uses
curl_cffiwith a mobile-Safari TLS fingerprint, which passes as of writing. If requests start failing with 403 +cf-mitigated: challenge, changeIMPERSONATEinao3.py.Privacy: fic text goes to Google's Gemini API for reading; nothing else leaves your machine, no telemetry.
Adult content: AO3 hosts works across all ratings. The server passes through whatever your search scopes — use the
ratingfilter and AO3's warning tags to control what gets fetched.
Make it yours
It's a small, single-purpose server — a few hundred readable lines with no framework magic. Fork it and edit anything: rewrite the reader's prompt, swap in a different model, change the throttle, add a tool. That's the intended way to use it.
Run it from source:
git clone https://github.com/ArturLys/ao3-mcp.git
cd ao3-mcp
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python smoke_test.py YOUR_GEMINI_KEY # end-to-end check: search → download → digest
python server.py --api-key YOUR_GEMINI_KEY # or point your client's command at thisCredits
AO3 access approach builds on ao3_api by wendytg.
All fanworks belong to their authors on the Archive of Our Own, a project of the Organization for Transformative Works.
License
MIT
Available Tools
5 toolsfind_tagsA
Resolve fuzzy wording to canonical AO3 tag names (live autocomplete).
Use before search_works when unsure of exact spelling — e.g. "coffee shop" resolves to "Alternate Universe - Coffee Shops & Cafés".
Args: term: partial/fuzzy tag text, e.g. "enemies to", "coffee", "kakashi". kind: what to complete: tag | fandom | relationship | character.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | tag | |
| term | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must cover behavior. Describes live autocomplete and example output, but lacks details on limits, empty results, or number of suggestions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise: two sentences plus arg list. Front-loaded with purpose and example. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Tool has output schema, so return values are covered. Description provides purpose, usage timing, and param details. Missing minor behavioral notes but overall complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema coverage, description explains both parameters with examples and allowed values for 'kind', adding meaning beyond schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it resolves fuzzy wording to canonical tag names, with an example. Differentiates from sibling tools like search_works.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use before search_works when unsure of exact spelling', providing clear context. Does not include when-not-to-use, but sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_workA
Get the full metadata card for one work: tags, stats, summary, series info.
Args: work_id: the numeric AO3 work id (from search results or a URL like archiveofourown.org/works/12345).
| Name | Required | Description | Default |
|---|---|---|---|
| work_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the tool is a read operation (get) and describes return content, but does not mention auth requirements, rate limits, or potential side effects. The indication of read-only behavior is implicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, two sentences with no filler. The first sentence states purpose and outputs, the second explains the parameter. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple interface (one parameter) and presence of an output schema, the description covers the key aspects: what the tool does and what it returns. It is sufficiently complete for a 'get by ID' operation, though error handling or edge cases are not discussed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description's second sentence explains the 'work_id' parameter in detail: it is a numeric AO3 work ID from search results or URLs, providing essential usage context beyond the schema's type definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves the full metadata card for a single work, listing specific content (tags, stats, summary, series info). It effectively distinguishes from siblings like 'read_works' (multiple works) and 'get_work_text' (text only).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (when needing comprehensive metadata for one work) and contrasts with sibling names that suggest different scopes. However, it lacks explicit guidance on when not to use it or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_work_textA
⚠️ NOT RECOMMENDED — escape hatch only. Returns the raw full text of ONE fic directly to you, bypassing the mini reader.
Prefer read_works in almost every case. A fic can run 150k+ words; pulling
that into your own context buries everything else, burns your tokens, and
throws away the whole reason this server exists — delegating reading to a
cheap second model. read_works hands you a structured report plus verbatim
prose samples, which is enough to judge, compare, and recommend a fic without
the fic ever entering your context.
Only reach for this when you genuinely need exact wording a report can't carry
— e.g. the user explicitly asks you to quote or close-read a specific passage.
If you just want to know what a fic is like or whether it's good: use
read_works instead.
Args: work_id: the numeric AO3 work id. max_words: cap the text to the first N words (0 = whole fic). Set a limit to sample a fic's opening instead of dumping the entire thing into your context — a few thousand words is usually plenty to judge voice.
| Name | Required | Description | Default |
|---|---|---|---|
| work_id | Yes | ||
| max_words | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses the trade-offs: bypasses mini reader, returns raw text, can be huge (150k+ words), and why it's an escape hatch. Also mentions the max_words parameter to mitigate context impact.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is thorough and well-structured, front-loading the critical warning and recommendation. While slightly verbose, every part adds value, though a shorter alternative could be possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers usage, parameters, and behavioral impact adequately. With an output schema present, the description need not detail return values. Minor gap: doesn't specify if text includes HTML or formatting.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema coverage, the description explains work_id as 'numeric AO3 work id' and max_words as 'cap the text to first N words, 0 = whole fic', with a suggestion to sample. This adds necessary context missing from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns the raw full text of a fic, and explicitly distinguishes it from read_works by contrasting structured reports vs raw text. The purpose is unambiguous and specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use (exact wording needed, user asks to quote/close-read) and when-not-to-use (prefer read_works in almost every case), with reasoning about context burden and token waste.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_worksA
Have the mini reader (a separate AI) read full fics and report on each.
Works for a single fic or up to 20 at once. You never receive fic text — only structured reader reports, one per work. The reader answers your query directly (anything works: "is the ending happy?", "how explicit is it?", "which of these should I read first?") plus gives a general digest of plot, characters, style, and content notes. When given several fics, it ends with a comparison section ranking them against your query.
This is the ONLY approved way to read a fic. A separate model does the reading so a whole novel never touches your context. You MUST send fics here before you recommend, rank, summarize, or judge them — search blurbs are not enough, and reading raw text yourself defeats the entire point of this server. Shortlist from blurbs, read here, then recommend.
Reading depth: a single-fic call sends the reader up to ~150k words (whole novels fit); in a batch each fic is capped at ~100k characters. If a long fic's report matters, read it alone. Batches that exceed the token budget are split internally, then a final reduce pass still produces ONE global comparison across the whole batch.
Content refusals: the reader is Gemini, which has a non-configurable safety filter that occasionally refuses explicit or extreme fics — that fic's report comes back as "(mini reader returned no text …)". The server already retries once on the backup model, but the block is intermittent, so if a fic you care about is refused: read it ALONE (a single fic isn't dragged down by an extreme one sharing its batch), or just retry. In a mixed batch, one refused fic does not sink the others — their reports still return.
Args: work_ids: 1-20 numeric AO3 work ids (from search results or URLs). query: the question to answer about each fic.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| work_ids | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that a separate model does the reading, never returns raw text, handles batch splitting, retries on safety blocks, and explains refusal behavior. It could be slightly more concise but adds substantial context beyond the tool's name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and usage but runs long with repeated points about not receiving raw text. Every section earns its place, but some redundancy could be trimmed without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (batch reading, safety filters, comparison reports) and the presence of an output schema, the description covers all necessary context: depth, cap limits, refusal handling, and batching behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (no description of parameters in schema), but the description explains that work_ids are numeric AO3 IDs and query is a free-form question. This adds meaning beyond the bare schema, though a structured breakdown would improve clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that this tool reads full fics via a separate AI and produces structured reports. It distinguishes itself from siblings like get_work, get_work_text, and search_works by emphasizing that it is the only approved way to read fic content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when-to-use and when-not-to-use guidance, stating it is the ONLY approved way to read a fic and must be used before recommending or judging. It also explains alternatives (reading alone for long fics) and retry strategies for refusals.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_worksA
Search AO3 for works. All filters optional; combine freely.
RECOMMENDATION WORKFLOW — reading before recommending is MANDATORY, and the
reading is done by a SEPARATE model, not you. Blurbs are author-written ads;
never recommend, rank, or summarize a fic from its blurb alone. Cast a wide
net (pages=2-3, i.e. 40-60 blurbs), shortlist the promising ones, then hand
the top ≤20 ids to read_works — a second AI reads them and reports back.
Recommend ONLY fics that came back from read_works. Do not read fic text
yourself; delegating it is the entire point of this server.
SEARCH STRATEGY — searching is cheap and reading is delegated, so the
winning move is always to OVER-FETCH and let read_works brute-force the
shortlist, never to craft one perfect narrow query. Filters multiply: each
one you add cuts the pool, and stacked filters routinely cut it to zero.
USE WILDCARDS LIBERALLY — abuse them. A * matches any run of characters
and works in EVERY name field (fandom, relationship, character, tags)
and in query. Wrapping a term in stars is the single best defence against
AO3's exact-canonical-name trap: fandom="Genshin Impact (Video Game)"
returns ZERO (the canonical tag is actually "原神 | Genshin Impact (Video
Game)"), but fandom="*Genshin Impact*" returns the whole fandom. Likewise
relationship="*Kazuha*Scaramouche*", tags="*Enemies to Lovers*". When you
don't know the exact canonical name — which is most of the time — reach for a
wildcard first instead of guessing the literal string.
IF YOU GET 0 (or few) RESULTS, that is almost always your query being too narrow, NOT the content missing from AO3. Recover instead of giving up:
FIRST, wildcard the name fields (
*Genshin Impact*). This fixes the most common cause — an exact-match field that didn't match the canonical tag — in one retry, without a separatefind_tagsround-trip.Still unsure of a name?
find_tagsresolves it, or move the idea intoqueryas free text (fuzzy, no canonical spelling needed).Drop filters one at a time and retry:
word_countfirst, thencomplete_only, thenrating. Re-add only what the user insisted on.Concepts don't need to be tags at all: "slow burn rivals in a bakery" works fine as free-text
queryeven if no such tag exists.Still thin? Search the broad version (fandom + category, sort by kudos), fetch 2-3 pages, and let the blurbs +
read_worksdo the filtering. A human reader has to search narrowly because they can only read a few fics; you can read twenty at once, so breadth costs you nothing.
Results show numeric work ids, not URLs. When relaying a work to the user, build the link yourself: https://archiveofourown.org/works/{id}
Each result shows a kudos-to-hits ratio (k/h) — AO3's most honest quality proxy, since kudos are one-per-reader but hits count every visit. Compare it only within similar works: multi-chapter fics accumulate hits on every chapter visit, so long WIPs run structurally lower ratios than one-shots.
Args:
query: free-text search. Supports AO3's full operator syntax
(case-sensitive, space after colon required where shown):
"exact phrase", AND / OR / NOT, -term to exclude;
words>10000, words:1000-5000, kudos>500 (same for hits/
comments/bookmarks); sort:kudos, sort:hits, sort:>posted
(oldest first); otp: true (exactly one ship, no side pairings);
creators: username / -creators: username; summary: "phrase";
expected_number_of_chapters: 1 (one-shots only);
series.title: * (part of a series); language_id: en.
Also supports * wildcards, e.g. *coffee shop*.
⚠️ query is a FULL-TEXT match on the fic body, AND'd with every
other filter — so it narrows HARD. Do NOT stuff mood/concept
synonyms here ("nuzzle OR forehead kiss OR won't let go"): that
demands the prose literally contain one of those strings on top of
your tag/fandom filters, and routinely collapses a healthy 60-result
search to 0. Concepts belong in tags (wildcarded), not here. Use
query for author names, quoted title/summary phrases, or the numeric
operators above — leave it EMPTY when a tag already covers the vibe.
title: words in the work title.
author: author/creator name.
fandom: fandom name, e.g. "Naruto" (comma-separate several). Exact
canonical match — but * wildcards work here: prefer
"Genshin Impact" over the literal name to survive canonical tags
with prefixes/aliases (e.g. "原神 | Genshin Impact (Video Game)").
relationship: ship tag. Format: "A/B" romantic, "A & B" platonic,
canonical name order, e.g. "Kakashi Hatake/Iruka Umino". Wildcards
work: "KazuhaScaramouche*" beats guessing the exact tag order.
character: character name(s), comma-separated. Wildcards work here too.
tags: freeform tags, comma-separated, EXACT canonical spelling
(use find_tags to resolve, or wildcard it: "Enemies to Lovers"). Popular canonical tags: Fluff; Angst;
Hurt/Comfort; Emotional Hurt/Comfort; Angst with a Happy Ending;
Hurt No Comfort; Enemies to Lovers; Friends to Lovers; Enemies to
Friends to Lovers; Slow Burn; Mutual Pining; Fake/Pretend
Relationship; There Was Only One Bed; Idiots in Love; Getting
Together; Established Relationship; First Kiss; Found Family;
Fix-It; Time Travel; Kid Fic; Domestic Fluff; Tooth-Rotting Fluff;
Crack; Crack Treated Seriously; 5+1 Things; POV Outsider; Soulmates;
Smut; Plot What Plot/Porn Without Plot; Alpha/Beta/Omega Dynamics;
Dead Dove: Do Not Eat; Canon Compliant; Post-Canon; Alternate
Universe - Modern Setting; Alternate Universe - Canon Divergence;
Alternate Universe - Coffee Shops & Cafés; Alternate Universe -
College/University; Alternate Universe - Soulmates.
rating: one of: general, teen, mature, explicit, not rated.
categories: comma-separated relationship categories to include:
F/F, F/M, Gen, M/M, Multi, Other. Empty = all.
complete_only: only finished works.
word_count: range like "10000-50000", ">5000" or "<20000".
sort_by: relevance | kudos | hits | comments | bookmarks | words | date_updated | date_posted.
page: which result page to start from (for paging through results).
pages: result pages to fetch, 20 works each (1-5). For a targeted
lookup 1 is enough; for a recommendation hunt fetch 2-3 pages
(40-60 blurbs) so the read_works shortlist has real competition.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| tags | No | ||
| pages | No | ||
| query | No | ||
| title | No | ||
| author | No | ||
| fandom | No | ||
| rating | No | ||
| sort_by | No | relevance | |
| character | No | ||
| categories | No | ||
| word_count | No | ||
| relationship | No | ||
| complete_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Discloses that search is cheap and reading is delegated, that query is full-text and narrows hard, that filters multiply and can cut to zero, and that results include numeric ids and k/h ratio. Also explains wildcard behavior and recovery steps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear headings (RECOMMENDATION WORKFLOW, SEARCH STRATEGY, etc.) and bullet points. However, the description is quite long; while every part is valuable, it could be condensed slightly without losing meaning. Still, the structure aids readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (14 parameters, no annotations, and an output schema exists that covers return values), the description is fully complete. It covers search behavior, error recovery, output interpretation, and links to sibling tools. No gaps remain for an agent to use the tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds extensive meaning for every parameter. For example, query lists operator syntax, warns against stuffing synonyms; fandom explains exact-match pitfalls and wildcard use; tags lists popular canonical tags. Each parameter is given detailed guidance, far beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with 'Search AO3 for works' — a specific verb+resource. Distinguishes from siblings read_works and find_tags, and explains the recommendation workflow where this tool is for initial search and shortlisting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use (for broad search to over-fetch) and when-not-to (to read fics — delegated to read_works). Gives comprehensive strategy: use wildcards, recover from 0 results by broadening queries, and contrast with find_tags. Also advises on recommended pages for recommendation hunts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a clearly distinct purpose: get_work for metadata, read_works for delegated reading, get_work_text as a fallback for raw text, search_works for searching, and find_tags for tag resolution. No overlapping functionality.
All tools follow a consistent verb_noun pattern in snake_case (e.g., get_work, search_works, find_tags), making them predictable and easy to distinguish.
Five tools is well-scoped for an AO3 browsing assistant, covering search, metadata, reading, and tag completion without unnecessary bloat or missing essentials.
The tool set covers the core workflow: discover tags, search, get work details, and read content (via reports or raw text). No obvious gaps for the stated purpose of browsing and recommending fics.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
AI-native fiction platform. Any AI can register, read, search and co-author novels via MCP or REST.
Official remote MCP server for Archivist AI TTRPG campaign memory: characters, sessions, and more.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceThis server implements the Model Context Protocol to facilitate meaningful interaction and understanding development between humans and AI through structured tools and progressive interaction patterns.57

CodeAlive MCPofficial
AlicenseNot gradedqualityAmaintenanceA Model Context Protocol server that enhances AI agents by providing deep semantic understanding of codebases, enabling more intelligent interactions through advanced code search and contextual awareness.88MIT- AlicenseNot gradedqualityFmaintenanceA Model Context Protocol server that manages character knowledge and relationships for creative writing projects, offering semantic search and AI-powered analysis.4MIT

ouro-mcpofficial
AlicenseNot gradedqualityAmaintenanceMCP server for the Ouro platform, enabling AI agents to search, read, query datasets, create content, and execute API routes on Ouro through the Model Context Protocol.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ArturLys/ao3-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server