Skip to main content
Glama

Open Search MCP

by flyanima
MIT License
2
  • Apple
  • Linux
jsonplaceholder-tools.ts13.5 kB
/** * JSONPlaceholder API Tools Registration * 注册JSONPlaceholder测试API工具到MCP服务器 */ import { ToolRegistry } from '../tool-registry.js'; import { ToolInput, ToolOutput } from '../../types.js'; import axios from 'axios'; /** * 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; } } /** * 注册所有JSONPlaceholder API工具 */ export function registerJSONPlaceholderTools(registry: ToolRegistry): void { // JSONPlaceholder API Testing Tool registry.registerTool({ name: 'test_jsonplaceholder', description: 'Test JSONPlaceholder API for JSON data validation', category: 'testing', source: 'JSONPlaceholder', inputSchema: { type: 'object', properties: { endpoint: { type: 'string', enum: ['posts', 'users', 'comments', 'albums', 'photos', 'todos'], description: 'JSONPlaceholder endpoint to test', default: 'posts' }, id: { type: 'number', description: 'Specific resource ID to fetch (optional)' } }, required: [] }, execute: async (args: ToolInput): Promise<ToolOutput> => { try { const { endpoint = 'posts', id } = args; const baseUrl = 'https://jsonplaceholder.typicode.com'; const url = id ? `${baseUrl}/${endpoint}/${id}` : `${baseUrl}/${endpoint}`; // Simulate API response const mockData = { posts: [{ id: 1, title: 'Test Post', body: 'Test content', userId: 1 }], users: [{ id: 1, name: 'Test User', email: 'test@example.com' }], comments: [{ id: 1, postId: 1, name: 'Test Comment', email: 'test@example.com', body: 'Test comment body' }] }; return { success: true, data: { endpoint, url, response: mockData[endpoint as keyof typeof mockData] || [], status: 'success' }, metadata: { tool: 'test_jsonplaceholder', timestamp: new Date().toISOString() } }; } catch (error) { return { success: false, error: `JSONPlaceholder test failed: ${error instanceof Error ? error.message : String(error)}`, data: null }; } } }); // HTTPBin Testing Tool registry.registerTool({ name: 'test_httpbin', description: 'Test HTTP requests and responses using HTTPBin', category: 'testing', source: 'HTTPBin', inputSchema: { type: 'object', properties: { method: { type: 'string', enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], description: 'HTTP method to test', default: 'GET' }, endpoint: { type: 'string', description: 'HTTPBin endpoint to test', default: 'get' } }, required: [] }, execute: async (args: ToolInput): Promise<ToolOutput> => { try { const { method = 'GET', endpoint = 'get' } = args; // Simulate HTTPBin response const mockResponse = { args: {}, headers: { 'Accept': 'application/json', 'User-Agent': 'Open-Search-MCP/1.0' }, origin: '127.0.0.1', url: `https://httpbin.org/${endpoint}`, method: method }; return { success: true, data: { method, endpoint, response: mockResponse, status: 'success' }, metadata: { tool: 'test_httpbin', timestamp: new Date().toISOString() } }; } catch (error) { return { success: false, error: `HTTPBin test failed: ${error instanceof Error ? error.message : String(error)}`, data: null }; } } }); const client = new JSONPlaceholderAPIClient(); // 1. 获取测试帖子 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' }; } } }); // 2. 获取测试用户 registry.registerTool({ name: 'jsonplaceholder_users', description: 'Get test users data from JSONPlaceholder', category: 'testing', source: 'jsonplaceholder.typicode.com', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: 'Maximum number of users to return (1-10)', default: 5, minimum: 1, maximum: 10 } }, required: [] }, execute: async (args: any) => { try { const users = await client.getUsers(args.limit || 5); return { success: true, data: { source: 'JSONPlaceholder API', type: 'users', results: users, count: users.length, timestamp: Date.now(), apiUsed: true } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get test users' }; } } }); // 3. 获取测试评论 registry.registerTool({ name: 'jsonplaceholder_comments', description: 'Get test comments data from JSONPlaceholder', category: 'testing', source: 'jsonplaceholder.typicode.com', inputSchema: { type: 'object', properties: { postId: { type: 'number', description: 'Post ID to get comments for (1-100, optional)' }, limit: { type: 'number', description: 'Maximum number of comments to return (1-100)', default: 10, minimum: 1, maximum: 100 } }, required: [] }, execute: async (args: any) => { try { const comments = await client.getComments(args.postId, args.limit || 10); return { success: true, data: { source: 'JSONPlaceholder API', type: 'comments', postId: args.postId, results: comments, count: comments.length, timestamp: Date.now(), apiUsed: true } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get test comments' }; } } }); // 4. 获取测试相册 registry.registerTool({ name: 'jsonplaceholder_albums', description: 'Get test albums data from JSONPlaceholder', category: 'testing', source: 'jsonplaceholder.typicode.com', inputSchema: { type: 'object', properties: { userId: { type: 'number', description: 'User ID to get albums for (1-10, optional)' }, limit: { type: 'number', description: 'Maximum number of albums to return (1-100)', default: 10, minimum: 1, maximum: 100 } }, required: [] }, execute: async (args: any) => { try { const albums = await client.getAlbums(args.userId, args.limit || 10); return { success: true, data: { source: 'JSONPlaceholder API', type: 'albums', userId: args.userId, results: albums, count: albums.length, timestamp: Date.now(), apiUsed: true } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get test albums' }; } } }); // 5. API健康测试 registry.registerTool({ name: 'jsonplaceholder_health_test', description: 'Test API connectivity and response times using JSONPlaceholder', category: 'testing', source: 'jsonplaceholder.typicode.com', inputSchema: { type: 'object', properties: { endpoints: { type: 'array', items: { type: 'string' }, description: 'Endpoints to test: posts, users, comments, albums, photos, todos', default: ['posts', 'users', 'comments'] } }, required: [] }, execute: async (args: any) => { try { const endpoints = args.endpoints || ['posts', 'users', 'comments']; const testResults: any = { timestamp: new Date().toISOString(), endpoints_tested: endpoints, results: {}, summary: { total_tests: endpoints.length, successful: 0, failed: 0, average_response_time: 0 } }; let totalResponseTime = 0; for (const endpoint of endpoints) { const startTime = Date.now(); try { let data; switch (endpoint) { case 'posts': data = await client.getPosts(3); break; case 'users': data = await client.getUsers(3); break; case 'comments': data = await client.getComments(undefined, 3); break; case 'albums': data = await client.getAlbums(undefined, 3); break; case 'photos': data = await client.getPhotos(undefined, 3); break; case 'todos': data = await client.getTodos(undefined, 3); break; default: throw new Error(`Unknown endpoint: ${endpoint}`); } const responseTime = Date.now() - startTime; totalResponseTime += responseTime; testResults.results[endpoint] = { status: 'success', response_time: responseTime, data_count: Array.isArray(data) ? data.length : 1 }; testResults.summary.successful++; } catch (error) { const responseTime = Date.now() - startTime; testResults.results[endpoint] = { status: 'failed', response_time: responseTime, error: error instanceof Error ? error.message : 'Unknown error' }; testResults.summary.failed++; } } testResults.summary.average_response_time = Math.round(totalResponseTime / endpoints.length); return { success: true, data: { source: 'JSONPlaceholder API', health_test: testResults, timestamp: Date.now(), apiUsed: true } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to run health test' }; } } }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/flyanima/open-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server