Skip to main content
Glama
Grinv

AniList MCP Server

Add an entry to your AniList list

add_list_entry

Add an anime or manga to your AniList list by media ID, setting status, score, progress, and more; existing entries are updated in place rather than duplicated.

Instructions

[Requires login] Add an anime/manga to the authenticated user's own AniList list. Use search_media first to resolve the title to its AniList media ID. Only set the fields you care about — everything else is left at AniList's defaults ONLY if this media isn't already on the list. AniList upserts by media ID: if an entry for it already exists (e.g. previously dropped, with its own score/notes/progress), calling this updates that entry in place instead — every field you don't set here keeps its previous value, not a default. Use get_user_list first to check for an existing entry if you need a guaranteed-fresh one. The response echoes what AniList actually stored, so check it rather than assuming the write landed verbatim. It includes customLists/advancedScores only when you set them — those are the fields AniList zeroes/replaces rather than merges, so they're worth reading back; otherwise the echo is trimmed, since a list sync is hundreds of writes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
notesNoFree-text notes for this entry (per AniList's own schema, capped at 6000 characters).
scoreNoScore out of 10 (decimals allowed, e.g. 8.5), always on this scale regardless of the account's configured scoreFormat (set via update_user) — no conversion needed.
repeatNoNumber of times rewatched/reread (per AniList's own schema, capped at 1000).
statusNoList status. If omitted on a genuinely NEW entry, AniList defaults to CURRENT (with `startedAt` auto-set to today) — confirmed live; despite AniList's own site UI defaulting new entries to Planning, the API itself does not. If the media is already on the list, this default does NOT apply — omitting `status` on an update-in-place leaves the entry's existing status untouched.
mediaIdYesAniList anime/manga ID to add (from search_media).
privateNoHide this entry from your public list.
priorityNoList priority (higher = more important; per AniList's own schema, capped at 255).
progressNoEpisodes watched / chapters read.
startedAtNoDate you started.
completedAtNoDate you completed.
customListsNoNames of custom lists to file this entry under — REPLACES this entry's full set of enabled lists, not merged: naming only a subset silently turns OFF every other list this entry was previously filed under (confirmed live), it doesn't leave them alone. Include every list name you want this entry to stay tagged with, not just the one you're adding. Also, the list must already exist on the account (update_user's `animeListOptions`/`mangaListOptions` `customLists`) — naming one that doesn't exist yet is silently a no-op, not an error.
advancedScoresNoPer-category scores, 0-10 scale (e.g. {Story: 8, Characters: 9}) — errors if advanced scoring isn't enabled for this media's type, or if a key doesn't match the account's configured category list for it (anime and manga have SEPARATELY configured lists). Any of that list's categories you omit here is set to 0, not left unchanged — include every category if you don't want the others zeroed. Stored positionally, not by name: matched against the account's category order (update_user's `advancedScoring`) at READ time, not write time — if that order is later renamed/reordered, a score you write for 'Story' today can silently be read back as 'Characters' tomorrow, with no error.
progressVolumesNoVolumes read (manga only).
hiddenFromStatusListsNoHide this entry from the public status-grouped list views (e.g. 'Watching') while still counting it in statistics — distinct from `private`, which hides the entry entirely.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
entryYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed10 schema fields changedv0.9.0
    • changedOutput schema / properties / entry / properties / customLists / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": {},
      -      "properties": {
      -        "enabled": {
      -          "anyOf": [
      -            {
      -              "type": "boolean"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "name": {
      -          "anyOf": [
      -            {
      -              "type": "string"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        }
      -      },
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "enabled": {
      +          "type": [
      +            "boolean",
      +            "null"
      +          ]
      +        },
      +        "name": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / entry / properties / hiddenFromStatusLists / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / entry / properties / hiddenFromStatusLists / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
    • removedOutput schema / properties / entry / properties / notes / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / entry / properties / notes / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / entry / properties / private / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / entry / properties / private / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
    • addedOutput schema / properties / entry / properties / score / description
      Added value: +"This user's own score for the entry, on a 0-10 scale (decimals allowed). It stays 0-10 on every account whatever the configured scoreFormat is, and matches the scale add_list_entry/update_list_entry take on write. This is NOT the 0-100 scale `averageScore`/`meanScore`/search_media's `averageScore_greater` filter use."
    • removedOutput schema / properties / entry / properties / status / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / entry / properties / status / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  2. Changed12 schema fields changedv0.8.0
    • addedOutput schema / $defs
      Added value: +{
      +  "__schema0": {
      +    "anyOf": [
      +      {
      +        "type": "string"
      +      },
      +      {
      +        "type": "number"
      +      },
      +      {
      +        "type": "boolean"
      +      },
      +      {
      +        "type": "null"
      +      },
      +      {
      +        "items": {
      +          "$ref": "#/$defs/__schema0"
      +        },
      +        "type": "array"
      +      },
      +      {
      +        "additionalProperties": {
      +          "$ref": "#/$defs/__schema0"
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    ]
      +  }
      +}
    • addedOutput schema / properties / entry / properties / advancedScores
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/__schema0"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Per-category advanced scores as AniList actually stores them — an untyped value (the write side takes a plain {category: score} map via add_list_entry/update_list_entry's `advancedScores`, but the echoed read-back shape isn't guaranteed to match it)."
      +}
    • addedOutput schema / properties / entry / properties / completedAt
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {
      +        "day": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "month": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "year": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / createdAt
      Added value: +{
      +  "anyOf": [
      +    {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / customLists
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "enabled": {
      +            "anyOf": [
      +              {
      +                "type": "boolean"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "name": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Every custom list configured on the account, with `enabled` showing whether THIS entry is filed under it. Naming a list here (via add_list_entry/update_list_entry) that isn't already in the account's `animeListOptions`/`mangaListOptions` `customLists` is silently a no-op on write — the list must exist first."
      +}
    • addedOutput schema / properties / entry / properties / notes
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / priority
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 9007199254740991,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / private
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / progressVolumes
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 9007199254740991,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / repeat
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 9007199254740991,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / startedAt
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {
      +        "day": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "month": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "year": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / entry / properties / updatedAt
      Added value: +{
      +  "anyOf": [
      +    {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  3. Changed13 schema fields changedv0.7.1
    • changedInput schema / properties / advancedScores / description
      Previous value: -"Per-category scores, 0-10 scale (e.g. {Story: 8, Characters: 9}) — errors if advanced scoring isn't enabled for this media's type, or if a key doesn't match the account's configured category list for it (anime and manga have SEPARATELY configured lists). Any of that list's categories you omit here is set to 0, not left unchanged — include every category if you don't want the others zeroed."New value: +"Per-category scores, 0-10 scale (e.g. {Story: 8, Characters: 9}) — errors if advanced scoring isn't enabled for this media's type, or if a key doesn't match the account's configured category list for it (anime and manga have SEPARATELY configured lists). Any of that list's categories you omit here is set to 0, not left unchanged — include every category if you don't want the others zeroed. Stored positionally, not by name: matched against the account's category order (update_user's `advancedScoring`) at READ time, not write time — if that order is later renamed/reordered, a score you write for 'Story' today can silently be read back as 'Characters' tomorrow, with no error."
    • addedInput schema / properties / completedAt / properties / year / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / completedAt / properties / year / minimum
      Removed value: --9007199254740991
    • addedInput schema / properties / mediaId / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / mediaId / minimum
      Removed value: --2147483648
    • addedInput schema / properties / startedAt / properties / year / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / startedAt / properties / year / minimum
      Removed value: --9007199254740991
    • addedOutput schema / properties / entry / properties / id / exclusiveMinimum
      Added value: +0
    • changedOutput schema / properties / entry / properties / id / maximum
      Previous value: -9007199254740991New value: +2147483647
    • removedOutput schema / properties / entry / properties / id / minimum
      Removed value: --9007199254740991
    • changedOutput schema / properties / entry / properties / mediaId / anyOf
      Previous value: -[
      -  {
      -    "maximum": 9007199254740991,
      -    "minimum": -9007199254740991,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "exclusiveMinimum": 0,
      +    "maximum": 2147483647,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / entry / properties / progress / anyOf
      Previous value: -[
      -  {
      -    "maximum": 9007199254740991,
      -    "minimum": -9007199254740991,
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maximum": 9007199254740991,
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / entry / properties / score / anyOf
      Previous value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "minimum": 0,
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  4. Changed6 schema fields changedv0.5.0
    • changedInput schema / properties / notes / description
      Previous value: -"Free-text notes for this entry."New value: +"Free-text notes for this entry (per AniList's own schema, capped at 6000 characters)."
    • addedInput schema / properties / notes / maxLength
      Added value: +6000
    • changedInput schema / properties / priority / description
      Previous value: -"List priority (higher = more important)."New value: +"List priority (higher = more important; per AniList's own schema, capped at 255)."
    • changedInput schema / properties / priority / maximum
      Previous value: -9007199254740991New value: +255
    • changedInput schema / properties / repeat / description
      Previous value: -"Number of times rewatched/reread."New value: +"Number of times rewatched/reread (per AniList's own schema, capped at 1000)."
    • changedInput schema / properties / repeat / maximum
      Previous value: -9007199254740991New value: +1000
  5. Changed2 schema fields changedv0.4.0
    • changedInput schema / properties / customLists / description
      Previous value: -"Names of custom lists to file this entry under. The list must already exist on the account (update_user's `animeListOptions`/`mangaListOptions` `customLists`) — naming one that doesn't exist yet is silently a no-op, not an error."New value: +"Names of custom lists to file this entry under — REPLACES this entry's full set of enabled lists, not merged: naming only a subset silently turns OFF every other list this entry was previously filed under (confirmed live), it doesn't leave them alone. Include every list name you want this entry to stay tagged with, not just the one you're adding. Also, the list must already exist on the account (update_user's `animeListOptions`/`mangaListOptions` `customLists`) — naming one that doesn't exist yet is silently a no-op, not an error."
    • changedInput schema / properties / status / description
      Previous value: -"List status. If omitted, AniList defaults to CURRENT (with `startedAt` auto-set to today) — confirmed live; despite AniList's own site UI defaulting new entries to Planning, the API itself does not."New value: +"List status. If omitted on a genuinely NEW entry, AniList defaults to CURRENT (with `startedAt` auto-set to today) — confirmed live; despite AniList's own site UI defaulting new entries to Planning, the API itself does not. If the media is already on the list, this default does NOT apply — omitting `status` on an update-in-place leaves the entry's existing status untouched."
  6. Changed3 schema fields changedv0.3.0
    • addedInput schema / properties / advancedScores / additionalProperties / maximum
      Added value: +10
    • addedInput schema / properties / advancedScores / additionalProperties / minimum
      Added value: +0
    • changedInput schema / properties / advancedScores / description
      Previous value: -"Per-category scores, 0-10 scale (e.g. {Story: 8, Characters: 9}) — only meaningful if the account has advanced scoring enabled for this media's type. Anime and manga have SEPARATELY configured category lists, so keys must match whichever list applies to this entry. Any of that list's categories you omit here is set to 0, not left unchanged — include every category if you don't want the others zeroed."New value: +"Per-category scores, 0-10 scale (e.g. {Story: 8, Characters: 9}) — errors if advanced scoring isn't enabled for this media's type, or if a key doesn't match the account's configured category list for it (anime and manga have SEPARATELY configured lists). Any of that list's categories you omit here is set to 0, not left unchanged — include every category if you don't want the others zeroed."
  7. Changed4 schema fields changedv0.2.0
    • changedInput schema / properties / customLists / description
      Previous value: -"Names of custom lists to file this entry under."New value: +"Names of custom lists to file this entry under. The list must already exist on the account (update_user's `animeListOptions`/`mangaListOptions` `customLists`) — naming one that doesn't exist yet is silently a no-op, not an error."
    • addedInput schema / properties / hiddenFromStatusLists
      Added value: +{
      +  "description": "Hide this entry from the public status-grouped list views (e.g. 'Watching') while still counting it in statistics — distinct from `private`, which hides the entry entirely.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / status / description
      Previous value: -"List status. Defaults to PLANNING if omitted."New value: +"List status. If omitted, AniList defaults to CURRENT (with `startedAt` auto-set to today) — confirmed live; despite AniList's own site UI defaulting new entries to Planning, the API itself does not."
    • addedOutput schema / properties / entry / properties / hiddenFromStatusLists
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  8. First observedv0.1.5

TDQS

A4/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=false), the description reveals the upsert behavior: if the entry already exists, unspecified fields keep previous values rather than defaults. It also discloses that customLists and advancedScores are zeroed/replaced rather than merged, the response echo should be checked, and login is required. These are significant behavioral traits not inferable from annotations alone.

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

Conciseness4/5

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

The description is long but efficiently front-loaded with the core purpose, then covers usage prerequisites, upsert behavior, and response handling. Every sentence serves a purpose, though there is slight redundancy between the 'defaults ONLY if not already on the list' and the upsert explanation. It could be tightened by a sentence without losing clarity.

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

Completeness5/5

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

For a complex 14-parameter tool with nested objects and output schema, the description covers all essential aspects: authentication, media resolution, upsert semantics, defaults, response verification, and the special handling of customLists/advancedScores. It also notes the echo trimming rationale. Nothing critical for an agent to invoke it correctly is missing.

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 the schema already documents all 14 parameters in detail. The description adds no new per-parameter semantics beyond what the schema provides. According to the calibration rule, high coverage yields a baseline of 3; the description's extra context about customLists/advancedScores is already mirrored in the schema's own param descriptions.

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: 'Add an anime/manga to the authenticated user's own AniList list.' It also provides the required input ('Use search_media first to resolve the title to its AniList media ID'). However, it doesn't explicitly distinguish this tool from sibling 'update_list_entry' — the upsert behavior overlaps with that tool, so an agent might not know which to prefer for modifying an existing entry.

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

Usage Guidelines3/5

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

The description gives clear context: it advises using search_media to resolve media IDs, and get_user_list to check for an existing entry when a guaranteed-fresh one is needed. It explains when defaults apply vs. when existing values are kept. However, it never mentions alternatives like update_list_entry or update_list_entries, nor does it state when to prefer this tool over those to avoid ambiguity. The guidance is context-rich but lacks explicit alternative routing.

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