Skip to main content
Glama

get_leech_cards

Retrieve cards tagged as leeches from Anki to identify and address difficult-to-memorize items in your flashcard collection.

Instructions

Retrieve cards tagged as leeches from Anki

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
detailedNoWhether to return detailed card information or just IDs
countNoNumber of random cards to return (defaults to all)

Implementation Reference

  • The primary handler for the 'get_leech_cards' tool. It processes the request parameters (detailed, count), finds leech cards using AnkiConnectClient, selects a random subset if specified, fetches detailed card information if requested, and returns a structured JSON response.
    private async handleGetLeechCards(request: any) {
      // Default to detailed = true if not specified
      const detailed = request.params.arguments?.detailed !== false;
    
      // Get the count parameter (optional)
      const count =
        typeof request.params.arguments?.count === "number"
          ? request.params.arguments.count
          : undefined;
    
      // Find all leech cards
      const allLeechCardIds = await this.ankiClient.findLeechCards();
    
      if (allLeechCardIds.length === 0) {
        return {
          content: [
            {
              type: "text",
              text: "No leech cards found in Anki.",
            },
          ],
        };
      }
    
      // Select random subset if count is specified
      const leechCardIds = count
        ? this.getRandomCardIds(allLeechCardIds, count)
        : allLeechCardIds;
    
      // Add information about total vs. returned cards
      const cardCountInfo = count
        ? `Returning ${leechCardIds.length} random cards out of ${allLeechCardIds.length} total leech cards.`
        : `Returning all ${leechCardIds.length} leech cards.`;
    
      if (!detailed) {
        // Just return the IDs if detailed=false
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify(
                {
                  message: cardCountInfo,
                  count: leechCardIds.length,
                  totalLeechCards: allLeechCardIds.length,
                  cardIds: leechCardIds,
                },
                null,
                2
              ),
            },
          ],
        };
      }
    
      // Get detailed information for each selected leech card
      const cardsInfo = await this.ankiClient.getCardsInfo(leechCardIds);
    
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                message: cardCountInfo,
                count: cardsInfo.length,
                totalLeechCards: allLeechCardIds.length,
                cards: cardsInfo.map((card) => ({
                  id: card.id,
                  noteId: card.noteId,
                  deck: card.deck,
                  modelName: card.modelName,
                  fields: Object.entries(card.fields).reduce(
                    (acc, [key, field]) => {
                      acc[key] = field.value;
                      return acc;
                    },
                    {} as Record<string, string>
                  ),
                  tags: card.tags,
                  front: card.front,
                  back: card.back,
                  statistics: card.statistics,
                })),
              },
              null,
              2
            ),
          },
        ],
      };
    }
  • src/index.ts:482-501 (registration)
    Registration of the 'get_leech_cards' tool in the MCP server's listTools handler, including name, description, and input schema definition.
    {
      name: "get_leech_cards",
      description: "Retrieve cards tagged as leeches from Anki",
      inputSchema: {
        type: "object",
        properties: {
          detailed: {
            type: "boolean",
            description:
              "Whether to return detailed card information or just IDs",
          },
          count: {
            type: "number",
            description:
              "Number of random cards to return (defaults to all)",
            minimum: 1,
          },
        },
      },
    },
  • Input schema definition for the 'get_leech_cards' tool, specifying optional 'detailed' boolean and 'count' number parameters.
    inputSchema: {
      type: "object",
      properties: {
        detailed: {
          type: "boolean",
          description:
            "Whether to return detailed card information or just IDs",
        },
        count: {
          type: "number",
          description:
            "Number of random cards to return (defaults to all)",
          minimum: 1,
        },
      },
    },
  • Helper method in AnkiConnectClient that finds leech cards by querying AnkiConnect for cards tagged 'leech' excluding those tagged with yesterday's review tag.
    async findLeechCards(): Promise<number[]> {
      // Generate yesterday's review tag to exclude
      const yesterdayTag = this.generateYesterdayReviewedTag();
    
      // Construct query to find leech cards but exclude those with yesterday's review tag
      return this.request<number[]>("findCards", {
        query: `tag:leech -tag:${yesterdayTag}`,
      });
    }
  • Helper method to randomly select a specified number of card IDs from a list using Fisher-Yates shuffle.
    private getRandomCardIds(cardIds: number[], count: number): number[] {
      // If count is greater than or equal to the total number of cards, return all cards
      if (count >= cardIds.length) {
        return cardIds;
      }
    
      // Fisher-Yates shuffle and take the first 'count' elements
      const shuffled = [...cardIds];
      for (let i = shuffled.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
      }
    
      return shuffled.slice(0, count);
    }
Behavior2/5

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

No annotations are provided, so the description carries full burden for behavioral disclosure. While 'Retrieve' implies a read operation, it doesn't specify whether this requires authentication, how results are returned (format, pagination), error conditions, or performance characteristics. The description is minimal and lacks behavioral context.

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?

The description is a single, clear sentence with zero wasted words. It's appropriately sized for a simple retrieval tool and front-loads the essential information. Every word earns its place.

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

Completeness3/5

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

For a retrieval tool with 2 parameters and 100% schema coverage but no annotations or output schema, the description provides basic purpose but lacks behavioral context and usage guidance. It's minimally adequate but has clear gaps in explaining how the tool behaves and when to use 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 description coverage is 100%, so the schema already documents both parameters thoroughly. The description adds no parameter-specific information beyond what's in the schema. Baseline 3 is appropriate when the schema does the heavy lifting, though no additional semantic context is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Retrieve') and target resource ('cards tagged as leeches from Anki'), making the purpose immediately understandable. It doesn't explicitly differentiate from its sibling tool 'tag_reviewed_cards', but the distinction is implied through the different operations (retrieval vs tagging).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives or in what context. The description only states what the tool does, without mentioning prerequisites, timing considerations, or relationship to the sibling tool beyond their different names.

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/captain-blue210/anki-mcp-server'

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