anilist_genre_list
Retrieve valid AniList genres and content tags grouped by category with descriptions. Use this list to ensure accurate genre names before applying filters.
Instructions
List all valid AniList genres and content tags. Use before genre-filtering tools to ensure valid genre names. Returns genres and content tags grouped by category with descriptions.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| includeAdultTags | No | Include adult/NSFW tags in the list | |
| filter | No | Show only genres, only tags, or both (default all) | all |
| category | No | Filter tags to a specific category (e.g. Theme, Setting, Cast) |
Implementation Reference
- src/tools/discover.ts:180-237 (handler)The execute function that handles the anilist_genre_list tool - queries AniList API for genres and tags, filters based on args, groups tags by category, and returns formatted output.
execute: async (args) => { try { const data = await anilistClient.query<GenreTagCollectionResponse>( GENRE_TAG_COLLECTION_QUERY, {}, { cache: "media" }, ); const lines: string[] = []; // Genres section if (args.filter !== "tags") { lines.push("# AniList Genres", "", data.GenreCollection.join(", ")); } // Tags section if (args.filter !== "genres") { let tags = data.MediaTagCollection; if (!args.includeAdultTags) { tags = tags.filter((t) => !t.isAdult); } // Group tags by category const categories = new Map< string, Array<{ name: string; description: string }> >(); for (const tag of tags) { const cat = tag.category || "Other"; if ( args.category && !cat.toLowerCase().startsWith(args.category.toLowerCase()) ) continue; const list = categories.get(cat); if (list) { list.push(tag); } else { categories.set(cat, [tag]); } } if (lines.length > 0) lines.push(""); lines.push("# Content Tags"); for (const [category, catTags] of categories) { lines.push("", `## ${category}`); for (const tag of catTags) { lines.push(` ${tag.name} - ${tag.description}`); } } } return lines.join("\n"); } catch (error) { return throwToolError(error, "fetching genre list"); } }, }); - src/tools/discover.ts:167-237 (registration)Registration of the anilist_genre_list tool via server.addTool with name, description, parameters, annotations, and execute handler.
server.addTool({ name: "anilist_genre_list", description: "List all valid AniList genres and content tags. " + "Use before genre-filtering tools to ensure valid genre names. " + "Returns genres and content tags grouped by category with descriptions.", parameters: GenreListInputSchema, annotations: { title: "List Genres & Tags", readOnlyHint: true, destructiveHint: false, openWorldHint: true, }, execute: async (args) => { try { const data = await anilistClient.query<GenreTagCollectionResponse>( GENRE_TAG_COLLECTION_QUERY, {}, { cache: "media" }, ); const lines: string[] = []; // Genres section if (args.filter !== "tags") { lines.push("# AniList Genres", "", data.GenreCollection.join(", ")); } // Tags section if (args.filter !== "genres") { let tags = data.MediaTagCollection; if (!args.includeAdultTags) { tags = tags.filter((t) => !t.isAdult); } // Group tags by category const categories = new Map< string, Array<{ name: string; description: string }> >(); for (const tag of tags) { const cat = tag.category || "Other"; if ( args.category && !cat.toLowerCase().startsWith(args.category.toLowerCase()) ) continue; const list = categories.get(cat); if (list) { list.push(tag); } else { categories.set(cat, [tag]); } } if (lines.length > 0) lines.push(""); lines.push("# Content Tags"); for (const [category, catTags] of categories) { lines.push("", `## ${category}`); for (const tag of catTags) { lines.push(` ${tag.name} - ${tag.description}`); } } } return lines.join("\n"); } catch (error) { return throwToolError(error, "fetching genre list"); } }, }); - src/schemas.ts:782-795 (schema)Zod schema for GenreListInput: includeAdultTags (boolean, default false), filter (enum all/genres/tags, default all), category (optional string).
export const GenreListInputSchema = z.object({ includeAdultTags: z .boolean() .default(false) .describe("Include adult/NSFW tags in the list"), filter: z .enum(["all", "genres", "tags"]) .default("all") .describe("Show only genres, only tags, or both (default all)"), category: z .string() .optional() .describe("Filter tags to a specific category (e.g. Theme, Setting, Cast)"), }); - src/api/queries.ts:603-613 (helper)GraphQL query GENRE_TAG_COLLECTION_QUERY used to fetch GenreCollection and MediaTagCollection with name, description, category, isAdult fields.
export const GENRE_TAG_COLLECTION_QUERY = ` query GenreTagCollection { GenreCollection MediaTagCollection { name description category isAdult } } `; - src/types.ts:406-414 (helper)TypeScript interface GenreTagCollectionResponse defining the shape of the API response for genre/tag queries.
export interface GenreTagCollectionResponse { GenreCollection: string[]; MediaTagCollection: Array<{ name: string; description: string; category: string; isAdult: boolean; }>; }