jsonplaceholder_posts
Retrieve test posts data from JSONPlaceholder to validate and test search functionality with configurable limits.
Instructions
Get test posts data from JSONPlaceholder (always works, good for testing)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of posts to return (1-100) |
Implementation Reference
- The execute handler function that implements the core tool logic: calls client.getPosts with optional limit, formats the response with metadata, or returns error on failure.
execute: async (args: any) => { try { const posts = await client.getPosts(args.limit || 10); return { success: true, data: { source: 'JSONPlaceholder API', type: 'posts', results: posts, count: posts.length, timestamp: Date.now(), apiUsed: true, note: 'This is test data from JSONPlaceholder - always reliable for testing' } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get test posts' }; } } - src/tools/testing/jsonplaceholder-tools.ts:189-230 (registration)The registry.registerTool invocation that defines and registers the jsonplaceholder_posts tool with its metadata, inline input schema, and execute handler.
registry.registerTool({ name: 'jsonplaceholder_posts', description: 'Get test posts data from JSONPlaceholder (always works, good for testing)', category: 'testing', source: 'jsonplaceholder.typicode.com', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: 'Maximum number of posts to return (1-100)', default: 10, minimum: 1, maximum: 100 } }, required: [] }, execute: async (args: any) => { try { const posts = await client.getPosts(args.limit || 10); return { success: true, data: { source: 'JSONPlaceholder API', type: 'posts', results: posts, count: posts.length, timestamp: Date.now(), apiUsed: true, note: 'This is test data from JSONPlaceholder - always reliable for testing' } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get test posts' }; } } }); - src/utils/input-validator.ts:267-269 (schema)Zod-based input validation schema for the jsonplaceholder_posts tool used by the global InputValidator.
'jsonplaceholder_posts': z.object({ limit: z.number().int().min(1).max(100).optional().default(10) }), - The JSONPlaceholderAPIClient class providing helper methods like makeRequest and getPosts used by the tool handler to interact with the JSONPlaceholder API.
class JSONPlaceholderAPIClient { private baseURL = 'https://jsonplaceholder.typicode.com'; async makeRequest(endpoint: string, params: Record<string, any> = {}) { try { const response = await axios.get(`${this.baseURL}${endpoint}`, { params, timeout: 10000 }); return response.data; } catch (error) {throw error; } } async getPosts(limit?: number) { const posts = await this.makeRequest('/posts'); return limit ? posts.slice(0, limit) : posts; } async getUsers(limit?: number) { const users = await this.makeRequest('/users'); return limit ? users.slice(0, limit) : users; } async getComments(postId?: number, limit?: number) { const endpoint = postId ? `/posts/${postId}/comments` : '/comments'; const comments = await this.makeRequest(endpoint); return limit ? comments.slice(0, limit) : comments; } async getAlbums(userId?: number, limit?: number) { const endpoint = userId ? `/users/${userId}/albums` : '/albums'; const albums = await this.makeRequest(endpoint); return limit ? albums.slice(0, limit) : albums; } async getPhotos(albumId?: number, limit?: number) { const endpoint = albumId ? `/albums/${albumId}/photos` : '/photos'; const photos = await this.makeRequest(endpoint); return limit ? photos.slice(0, limit) : photos; } async getTodos(userId?: number, limit?: number) { const endpoint = userId ? `/users/${userId}/todos` : '/todos'; const todos = await this.makeRequest(endpoint); return limit ? todos.slice(0, limit) : todos; } }