list-categories
Retrieve and filter WordPress categories by ID, slug, parent, or post using secure API authentication. Manage and organize site content efficiently with customizable sorting and pagination options.
Instructions
Get a list of categories with filtering options
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| context | No | Scope under which the request is made | view |
| exclude | No | Ensure result set excludes specific IDs | |
| hideEmpty | No | Whether to hide terms not assigned to any posts | |
| include | No | Limit result set to specific IDs | |
| order | No | Order sort attribute ascending or descending | asc |
| orderby | No | Sort collection by term attribute | name |
| page | No | Current page of the collection | |
| parent | No | Limit result set to terms assigned to a specific parent | |
| password | Yes | WordPress application password | |
| perPage | No | Maximum number of items to be returned | |
| post | No | Limit result set to terms assigned to a specific post | |
| search | No | Limit results to those matching a string | |
| siteUrl | Yes | WordPress site URL | |
| slug | No | Limit result set to terms with one or more specific slugs | |
| username | Yes | WordPress username |
Implementation Reference
- src/index.ts:1805-1879 (handler)Handler function that constructs API parameters from inputs, calls makeWPRequest to fetch categories from /wp-json/wp/v2/categories, formats the results into a readable text list, and returns as MCP content or error.async ({ siteUrl, username, password, context, page, perPage, search, exclude, include, order, orderby, hideEmpty, parent, post, slug, }) => { try { const params: Record<string, any> = { context, page, per_page: perPage, order, orderby, }; if (search) params.search = search; if (exclude) params.exclude = exclude.join(','); if (include) params.include = include.join(','); if (hideEmpty !== undefined) params.hide_empty = hideEmpty; if (parent) params.parent = parent; if (post) params.post = post; if (slug) params.slug = slug.join(','); const categories = await makeWPRequest<WPCategory[]>({ siteUrl, endpoint: "categories", auth: { username, password }, params }); const formattedCategories = Array.isArray(categories) ? categories.map(category => ({ id: category.id, name: category.name || "No name", slug: category.slug || "No slug", description: category.description || "No description", parent: category.parent || 0, count: category.count || 0 })) : []; const categoriesText = formattedCategories.length > 0 ? formattedCategories.map(category => `ID: ${category.id}\nName: ${category.name}\nSlug: ${category.slug}\nDescription: ${category.description}\nParent ID: ${category.parent}\nPost Count: ${category.count}\n---` ).join("\n") : "No categories found"; return { content: [ { type: "text", text: `Categories from ${siteUrl}:\n\n${categoriesText}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error retrieving categories: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }
- src/index.ts:1789-1804 (schema)Zod schema for input parameters including authentication details and comprehensive WP categories filtering options (pagination, search, ordering, hierarchy, etc.).siteUrl: z.string().url().describe("WordPress site URL"), username: z.string().describe("WordPress username"), password: z.string().describe("WordPress application password"), context: z.enum(["view", "embed", "edit"]).optional().default("view").describe("Scope under which the request is made"), page: z.number().min(1).optional().default(1).describe("Current page of the collection"), perPage: z.number().min(1).max(100).optional().default(10).describe("Maximum number of items to be returned"), search: z.string().optional().describe("Limit results to those matching a string"), exclude: z.array(z.number()).optional().describe("Ensure result set excludes specific IDs"), include: z.array(z.number()).optional().describe("Limit result set to specific IDs"), order: z.enum(["asc", "desc"]).optional().default("asc").describe("Order sort attribute ascending or descending"), orderby: z.enum(["id", "include", "name", "slug", "include_slugs", "term_group", "description", "count"]).optional().default("name").describe("Sort collection by term attribute"), hideEmpty: z.boolean().optional().describe("Whether to hide terms not assigned to any posts"), parent: z.number().optional().describe("Limit result set to terms assigned to a specific parent"), post: z.number().optional().describe("Limit result set to terms assigned to a specific post"), slug: z.array(z.string()).optional().describe("Limit result set to terms with one or more specific slugs"), },
- src/index.ts:1785-1880 (registration)McpServer.tool registration for 'list-categories' tool, specifying name, description, input schema, and handler function.server.tool( "list-categories", "Get a list of categories with filtering options", { siteUrl: z.string().url().describe("WordPress site URL"), username: z.string().describe("WordPress username"), password: z.string().describe("WordPress application password"), context: z.enum(["view", "embed", "edit"]).optional().default("view").describe("Scope under which the request is made"), page: z.number().min(1).optional().default(1).describe("Current page of the collection"), perPage: z.number().min(1).max(100).optional().default(10).describe("Maximum number of items to be returned"), search: z.string().optional().describe("Limit results to those matching a string"), exclude: z.array(z.number()).optional().describe("Ensure result set excludes specific IDs"), include: z.array(z.number()).optional().describe("Limit result set to specific IDs"), order: z.enum(["asc", "desc"]).optional().default("asc").describe("Order sort attribute ascending or descending"), orderby: z.enum(["id", "include", "name", "slug", "include_slugs", "term_group", "description", "count"]).optional().default("name").describe("Sort collection by term attribute"), hideEmpty: z.boolean().optional().describe("Whether to hide terms not assigned to any posts"), parent: z.number().optional().describe("Limit result set to terms assigned to a specific parent"), post: z.number().optional().describe("Limit result set to terms assigned to a specific post"), slug: z.array(z.string()).optional().describe("Limit result set to terms with one or more specific slugs"), }, async ({ siteUrl, username, password, context, page, perPage, search, exclude, include, order, orderby, hideEmpty, parent, post, slug, }) => { try { const params: Record<string, any> = { context, page, per_page: perPage, order, orderby, }; if (search) params.search = search; if (exclude) params.exclude = exclude.join(','); if (include) params.include = include.join(','); if (hideEmpty !== undefined) params.hide_empty = hideEmpty; if (parent) params.parent = parent; if (post) params.post = post; if (slug) params.slug = slug.join(','); const categories = await makeWPRequest<WPCategory[]>({ siteUrl, endpoint: "categories", auth: { username, password }, params }); const formattedCategories = Array.isArray(categories) ? categories.map(category => ({ id: category.id, name: category.name || "No name", slug: category.slug || "No slug", description: category.description || "No description", parent: category.parent || 0, count: category.count || 0 })) : []; const categoriesText = formattedCategories.length > 0 ? formattedCategories.map(category => `ID: ${category.id}\nName: ${category.name}\nSlug: ${category.slug}\nDescription: ${category.description}\nParent ID: ${category.parent}\nPost Count: ${category.count}\n---` ).join("\n") : "No categories found"; return { content: [ { type: "text", text: `Categories from ${siteUrl}:\n\n${categoriesText}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error retrieving categories: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } );
- src/index.ts:76-84 (schema)TypeScript interface defining the shape of WordPress category objects used in type annotations for API responses.interface WPCategory { id: number; name?: string; slug?: string; description?: string; parent?: number; count?: number; meta?: Record<string, any>; }
- src/index.ts:158-194 (helper)Reusable helper for authenticated HTTP requests to WordPress REST API endpoints, used by list-categories handler to fetch data.async function makeWPRequest<T>({ siteUrl, endpoint, method = 'GET', auth, data = null, params = null }: { siteUrl: string; endpoint: string; method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; auth: { username: string; password: string }; data?: any; params?: any; }): Promise<T> { const authString = Buffer.from(`${auth.username}:${auth.password}`).toString('base64'); try { const response = await axios({ method, url: `${siteUrl}/wp-json/wp/v2/${endpoint}`, headers: { 'Authorization': `Basic ${authString}`, 'Content-Type': 'application/json', }, data: data, params: params }); return response.data as T; } catch (error) { if (axios.isAxiosError(error) && error.response) { throw new Error(`WordPress API error: ${error.response.data?.message || error.message}`); } throw error; } }