Skip to main content
Glama
gavxm
by gavxm

anilist_delete_from_list

DestructiveIdempotent

Remove an entry from your AniList anime or manga list with list entry ID or media ID.

Instructions

Remove an entry from your anime or manga list. Pass either a list entry ID or a media ID. Requires ANILIST_TOKEN.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entryIdNoList entry ID to delete (from anilist_list)
mediaIdNoAniList media ID to remove from your list

Implementation Reference

  • Tool registration with execute handler for anilist_delete_from_list. Resolves mediaId to entryId, snapshots before deletion, calls DELETE_MEDIA_LIST_ENTRY_MUTATION, invalidates caches, and pushes undo record.
    server.addTool({
      name: "anilist_delete_from_list",
      description:
        "Remove an entry from your anime or manga list. " +
        "Pass either a list entry ID or a media ID. " +
        "Requires ANILIST_TOKEN.",
      parameters: DeleteFromListInputSchema,
      annotations: {
        title: "Delete from List",
        readOnlyHint: false,
        destructiveHint: true,
        idempotentHint: true,
        openWorldHint: true,
      },
      execute: async (args) => {
        try {
          requireAuth();
    
          // Resolve mediaId to entryId if needed
          let entryId = args.entryId;
          if (!entryId && args.mediaId) {
            const snapshot = await snapshotByMediaId(args.mediaId);
            if (!snapshot) {
              return `Media ${args.mediaId} is not on your list.`;
            }
            entryId = snapshot.id;
          }
    
          if (!entryId) {
            return "Provide either an entryId or a mediaId.";
          }
    
          // Snapshot before deletion
          const before = await snapshotByEntryId(entryId);
    
          const data = await anilistClient.query<DeleteMediaListEntryResponse>(
            DELETE_MEDIA_LIST_ENTRY_MUTATION,
            { id: entryId },
            { cache: null },
          );
    
          const viewerName = await getViewerName();
          anilistClient.invalidateUser(viewerName);
          invalidateUserProfiles(viewerName);
    
          if (!data.DeleteMediaListEntry.deleted) {
            return `Entry ${entryId} was not found or already removed.`;
          }
    
          // Track for undo
          if (before) {
            pushUndo({
              operation: { type: "delete", before },
              toolName: "anilist_delete_from_list",
              timestamp: Date.now(),
              description: `Deleted entry ${entryId} (media ${before.mediaId})`,
            });
          }
    
          const hint = before
            ? `\n(Deleted ${before.status} entry - say "undo" to restore)`
            : "";
          return `Entry ${entryId} deleted from your list.${hint}`;
        } catch (error) {
          return throwToolError(error, "deleting from list");
        }
      },
    });
  • Zod schema for DeleteFromListInputSchema. Accepts optional entryId or mediaId (must provide at least one).
    export const DeleteFromListInputSchema = z
      .object({
        entryId: z
          .number()
          .int()
          .positive()
          .optional()
          .describe("List entry ID to delete (from anilist_list)"),
        mediaId: z
          .number()
          .int()
          .positive()
          .optional()
          .describe("AniList media ID to remove from your list"),
      })
      .refine((data) => data.entryId !== undefined || data.mediaId !== undefined, {
        message: "Provide either an entryId or a mediaId.",
      });
  • The registerWriteTools function is called to register all write tools including anilist_delete_from_list.
    // === Tool Registration ===
    
    /** Register list mutation tools */
    export function registerWriteTools(server: FastMCP): void {
  • GraphQL mutation for DeleteMediaListEntry. Sends media list entry ID and expects a 'deleted' boolean response.
    export const DELETE_MEDIA_LIST_ENTRY_MUTATION = `
      mutation DeleteMediaListEntry($id: Int!) {
        DeleteMediaListEntry(id: $id) {
          deleted
        }
      }
    `;
  • TypeScript interface for the response of delete entry mutation.
    export interface DeleteMediaListEntryResponse {
      DeleteMediaListEntry: {
        deleted: boolean;
      };
    }
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=true. The description adds the authentication requirement (ANILIST_TOKEN), which is critical for invocation. It does not describe side effects beyond deletion, but the annotations cover the key traits.

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?

Two sentences, no waste. Front-loaded with verb and resource. Every word earns its place.

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?

No output schema, but the description explains deletion and authentication. It lacks details on return value or error handling, but for a simple destructive action with good annotations, it is reasonably complete.

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

Parameters4/5

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

Input schema has 100% coverage with descriptions. The description adds the 'either/or' constraint and contextual hint ('from anilist_list') that goes beyond the schema, clarifying usage.

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?

The description clearly states the action ('Remove an entry') and the resource ('anime or manga list'). It distinguishes from sibling tools like anilist_add_to_list (add) and anilist_list (view). The mention of two identification methods (entryId or mediaId) adds specificity.

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?

The description tells the user to pass either a list entry ID or a media ID, and mentions the required token. It does not explicitly state when not to use this tool (e.g., for batch operations) but the context of siblings provides implicit guidance.

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