get-top-posts
Retrieve a WordPress site's most viewed posts and pages within a specified time period using authenticated API access. Ideal for analyzing site traffic and content performance.
Instructions
View a site's top posts and pages by views
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of posts to return | |
| password | Yes | WordPress application password | |
| period | No | Time period for stats | |
| siteId | Yes | WordPress site ID | |
| siteUrl | Yes | WordPress site URL | |
| username | Yes | WordPress username |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"limit": {
"description": "Maximum number of posts to return",
"maximum": 100,
"minimum": 1,
"type": "number"
},
"password": {
"description": "WordPress application password",
"type": "string"
},
"period": {
"description": "Time period for stats",
"enum": [
"day",
"week",
"month",
"year"
],
"type": "string"
},
"siteId": {
"description": "WordPress site ID",
"type": "number"
},
"siteUrl": {
"description": "WordPress site URL",
"format": "uri",
"type": "string"
},
"username": {
"description": "WordPress username",
"type": "string"
}
},
"required": [
"siteUrl",
"username",
"password",
"siteId"
],
"type": "object"
}
Implementation Reference
- src/index.ts:1227-1277 (handler)Full handler implementation for the 'get-top-posts' MCP tool. Registers the tool, defines input schema with Zod, and implements the logic to fetch top posts/pages by views from WordPress Jetpack stats API endpoint `sites/{siteId}/stats/top-posts`, formats the results, and returns them as text content.server.tool( "get-top-posts", "View a site's top posts and pages by views", { siteUrl: z.string().url().describe("WordPress site URL"), username: z.string().describe("WordPress username"), password: z.string().describe("WordPress application password"), siteId: z.number().describe("WordPress site ID"), period: z.enum(["day", "week", "month", "year"]).optional().describe("Time period for stats"), limit: z.number().min(1).max(100).optional().describe("Maximum number of posts to return"), }, async ({ siteUrl, username, password, siteId, period = "week", limit = 10 }) => { try { const topPosts = await makeWPRequest<{posts: WPTopPost[]}>({ siteUrl, endpoint: `sites/${siteId}/stats/top-posts`, auth: { username, password }, params: { period, limit } }); const postsText = Array.isArray(topPosts.posts) && topPosts.posts.length > 0 ? topPosts.posts.map((post, index) => `${index + 1}. "${post.title}" (ID: ${post.id}) Views: ${post.views || 0} Comments: ${post.comment_count || 0} Likes: ${post.likes || 0} URL: ${post.url || "No URL"} ---` ).join("\n") : "No top posts found"; return { content: [ { type: "text", text: `Top Posts for site #${siteId} (${period}):\n\n${postsText}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error retrieving top posts: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } );
- src/index.ts:116-123 (schema)TypeScript interface defining the expected structure of individual top post data used in the get-top-posts tool response parsing.interface WPTopPost { id: number; title: string; url: string; views: number; comment_count: number; likes: number; }
- src/index.ts:157-194 (helper)Generic helper function makeWPRequest used by get-top-posts (and other tools) to make authenticated HTTP requests to WordPress REST API endpoints.// Helper function for making WordPress API requests 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; } }