anilist_profile
View an AniList user's profile to get their bio, anime and manga stats, top favourites, and account age.
Instructions
View a user's AniList profile including bio, stats, and favourites. Returns bio, anime/manga stats summary, top favourites by category, and account age.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| username | No | AniList username. Falls back to configured default if not provided. |
Implementation Reference
- src/tools/social.ts:131-146 (handler)The execute handler for the 'anilist_profile' tool. Calls the AniList API with USER_PROFILE_QUERY and formats the result using formatProfile.
execute: async (args) => { try { const username = getDefaultUsername(args.username); const data = await anilistClient.query<UserProfileResponse>( USER_PROFILE_QUERY, { name: username }, { cache: "stats" }, ); return formatProfile(data.User); } catch (error) { return throwToolError(error, "fetching profile"); } }, }); - src/tools/social.ts:118-146 (registration)The tool registration block that adds the 'anilist_profile' tool to the server via server.addTool, with name, description, parameters (ProfileInputSchema), annotations, and the execute handler.
server.addTool({ name: "anilist_profile", description: "View a user's AniList profile including bio, stats, and favourites. " + "Returns bio, anime/manga stats summary, top favourites by category, and account age.", parameters: ProfileInputSchema, annotations: { title: "User Profile", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, execute: async (args) => { try { const username = getDefaultUsername(args.username); const data = await anilistClient.query<UserProfileResponse>( USER_PROFILE_QUERY, { name: username }, { cache: "stats" }, ); return formatProfile(data.User); } catch (error) { return throwToolError(error, "fetching profile"); } }, }); - src/schemas.ts:867-873 (schema)ProfileInputSchema: defines input validation using Zod. Expects an optional 'username' string using the shared usernameSchema.
export const ProfileInputSchema = z.object({ username: usernameSchema .optional() .describe( "AniList username. Falls back to configured default if not provided.", ), }); - src/tools/social.ts:646-711 (helper)formatProfile helper function that formats a UserProfileResponse User object into a markdown string with bio, anime/manga stats, favourites (anime, manga, characters, staff, studios), and account age.
export function formatProfile(user: UserProfileResponse["User"]): string { const lines: string[] = [`# ${user.name}`, user.siteUrl, ""]; // About/bio if (user.about) { lines.push(truncateDescription(user.about, 500), ""); } // Anime stats const a = user.statistics.anime; if (a.count > 0) { const days = (a.minutesWatched / 1440).toFixed(1); lines.push( `## Anime: ${a.count} titles | ${a.episodesWatched} episodes | ${days} days | Mean ${a.meanScore.toFixed(1)}`, ); } // Manga stats const m = user.statistics.manga; if (m.count > 0) { lines.push( `## Manga: ${m.count} titles | ${m.chaptersRead} chapters | ${m.volumesRead} volumes | Mean ${m.meanScore.toFixed(1)}`, ); } // Favourites const fav = user.favourites; if (fav.anime.nodes.length) { lines.push( "", "Favourite Anime: " + fav.anime.nodes.map((n) => getTitle(n.title)).join(", "), ); } if (fav.manga.nodes.length) { lines.push( "Favourite Manga: " + fav.manga.nodes.map((n) => getTitle(n.title)).join(", "), ); } if (fav.characters.nodes.length) { lines.push( "Favourite Characters: " + fav.characters.nodes.map((n) => n.name.full).join(", "), ); } if (fav.staff.nodes.length) { lines.push( "Favourite Staff: " + fav.staff.nodes.map((n) => n.name.full).join(", "), ); } if (fav.studios.nodes.length) { lines.push( "Favourite Studios: " + fav.studios.nodes.map((n) => n.name).join(", "), ); } // Account age const created = new Date(user.createdAt * 1000).toLocaleDateString("en-US", { month: "short", year: "numeric", }); lines.push("", `Member since ${created}`); return lines.join("\n"); } - src/api/queries.ts:686-731 (schema)USER_PROFILE_QUERY: GraphQL query that fetches user profile data including id, name, bio (about), avatar, banner, siteUrl, dates, statistics (anime/manga counts, scores, episodes/chapters/volumes), and favourites (anime, manga, characters, staff, studios).
export const USER_PROFILE_QUERY = ` query UserProfile($name: String) { User(name: $name) { id name about avatar { large } bannerImage siteUrl createdAt updatedAt donatorTier statistics { anime { count meanScore episodesWatched minutesWatched } manga { count meanScore chaptersRead volumesRead } } favourites { anime(perPage: 5) { nodes { id title { romaji english native } siteUrl } } manga(perPage: 5) { nodes { id title { romaji english native } siteUrl } } characters(perPage: 5) { nodes { id name { full } siteUrl } } staff(perPage: 5) { nodes { id name { full } siteUrl } } studios(perPage: 5) { nodes { id name siteUrl } } } } } `;