Skip to main content
Glama
gavxm
by gavxm

anilist_recommendations

Read-only

Get community recommendations for anime or manga similar to a specific title. Returns ranked results with format, score, and genres.

Instructions

Get community recommendations for a specific anime or manga. Use when the user asks for shows similar to a specific title, or says "I liked X, what else should I watch?" Returns titles ranked by recommendation count with format, score, and genres.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoAniList media ID
titleNoSearch by title if no ID is known
typeNoMedia type. Defaults to ANIME.ANIME
limitNoNumber of recommendations to return (default 10, max 25)

Implementation Reference

  • The execute handler for the anilist_recommendations tool. Queries the AniList API for community recommendations, filters by rating and NSFW status, and formats results with media summaries and recommendation counts.
    execute: async (args) => {
      try {
        const variables: Record<string, unknown> = {
          type: args.type,
          perPage: args.limit,
        };
        if (args.id) variables.id = args.id;
        if (args.title) variables.search = args.title;
    
        const data = await anilistClient.query<RecommendationsResponse>(
          RECOMMENDATIONS_QUERY,
          variables,
          { cache: "media" },
        );
    
        const source = data.Media;
        const sourceTitle = getTitle(source.title);
        const nsfw = isNsfwEnabled();
        const recs = source.recommendations.nodes.filter(
          (n) =>
            n.mediaRecommendation &&
            n.rating > 0 &&
            (nsfw || !n.mediaRecommendation.isAdult),
        );
    
        if (!recs.length) {
          return `No community recommendations found for "${sourceTitle}".`;
        }
    
        const lines: string[] = [
          `# Recommendations based on ${sourceTitle}`,
          `${recs.length} community suggestion${recs.length !== 1 ? "s" : ""}:`,
          "",
        ];
    
        for (let i = 0; i < recs.length; i++) {
          const rec = recs[i];
          const m = rec.mediaRecommendation;
          if (!m) continue;
    
          lines.push(
            `${i + 1}. ${formatMediaSummary(m)}`,
            `  Recommended by ${rec.rating} user${rec.rating !== 1 ? "s" : ""}`,
            "",
          );
        }
    
        return lines.join("\n");
      } catch (error) {
        return throwToolError(error, "fetching recommendations");
      }
    },
  • The tool registration using server.addTool() with name 'anilist_recommendations', description, schema, and execute handler.
    });
    
    // === Community Recommendations ===
    
    server.addTool({
  • Zod schema defining input parameters: id (optional int), title (optional string), type (ANIME/MANGA, default ANIME), limit (1-25, default 10). Requires id or title.
    export const RecommendationsInputSchema = z
      .object({
        id: z.number().int().positive().optional().describe("AniList media ID"),
        title: z.string().optional().describe("Search by title if no ID is known"),
        type: z
          .enum(["ANIME", "MANGA"])
          .default("ANIME")
          .describe("Media type. Defaults to ANIME."),
        limit: z
          .number()
          .int()
          .min(1)
          .max(25)
          .default(10)
          .describe("Number of recommendations to return (default 10, max 25)"),
      })
      .refine((data) => data.id !== undefined || data.title !== undefined, {
        message: "Provide either an id or a title.",
      });
  • GraphQL query (RECOMMENDATIONS_QUERY) used to fetch community recommendations from the AniList API, sorted by rating descending.
    export const RECOMMENDATIONS_QUERY = `
      query MediaRecommendations($id: Int, $search: String, $type: MediaType, $perPage: Int) {
        Media(id: $id, search: $search, type: $type) {
          id
          title { romaji english native }
          recommendations(sort: RATING_DESC, perPage: $perPage) {
            nodes {
              rating
              mediaRecommendation {
                ...MediaFields
              }
            }
          }
        }
      }
      ${MEDIA_FRAGMENT}
    `;
  • TypeScript interface (RecommendationsResponse) defining the shape of the API response for recommendations.
    export interface RecommendationsResponse {
      Media: {
        id: number;
        title: {
          romaji: string | null;
          english: string | null;
          native: string | null;
        };
        recommendations: {
          nodes: Array<{
            rating: number;
            mediaRecommendation: AniListMedia | null;
          }>;
        };
      };
    }
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds valuable behavioral details: returns 'titles ranked by recommendation count with format, score, and genres'. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no redundant words. First sentence defines purpose, second gives usage trigger, third summarizes output. Efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite many sibling tools, the description clearly covers the use case and output. No output schema exists, but the description mentions key return fields. Could mention the 'limit' parameter behavior, but schema already covers it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all four parameters are described in the schema. The description does not add new meaning to the parameters but mentions output fields (format, score, genres) which are not part of the input schema. Baseline 3 is appropriate.

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?

Description clearly states the tool 'Get community recommendations' for 'a specific anime or manga', and distinguishes itself by providing explicit usage context (e.g., 'I liked X, what else should I watch?'). This differentiates it from siblings like anilist_similar and anilist_sequels.

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?

Explicitly states when to use: 'when the user asks for shows similar to a specific title, or says "I liked X, what else should I watch?"'. Does not explicitly state when not to use or mention alternatives, but the context is clear enough for an agent to decide.

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

Install Server

Other Tools

Latest Blog Posts

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/gavxm/ani-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server