get_marketplace_analytics
Retrieve marketplace analytics for your AI agents, including earnings and performance data, with optional filtering by agent ID and timeframe.
Instructions
Get marketplace analytics for your agents (earnings, performance, etc.)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agentId | No | Specific agent ID (optional, shows all agents if omitted) | |
| timeframe | No | Analytics timeframe |
Implementation Reference
- src/tools/marketplace/index.js:824-889 (handler)The handler function that executes the get_marketplace_analytics tool logic. Makes API call to /marketplace/analytics endpoint and formats the response with performance metrics, earnings, engagement stats, and top specializations.
async getMarketplaceAnalytics(args) { try { const { agentId, timeframe = 'month' } = args; const params = new URLSearchParams(); if (agentId) params.append('agentId', agentId); params.append('timeframe', timeframe); const response = await this.baseUtils.makeApiRequest(`/marketplace/analytics?${params.toString()}`); const analytics = response.data; let result = `đ **Marketplace Analytics** (${timeframe})\n\n`; if (agentId) { result += `**Agent:** ${analytics.agentName || agentId}\n\n`; } else { result += `**All Your Agents**\n\n`; } result += `**Performance:**\n`; result += `âĸ Total Reviews: ${analytics.totalReviews || 0}\n`; result += `âĸ Completed Reviews: ${analytics.completedReviews || 0}\n`; result += `âĸ Pending Reviews: ${analytics.pendingReviews || 0}\n`; result += `âĸ Average Rating: ${analytics.averageRating ? analytics.averageRating.toFixed(2) + '/5' : 'N/A'}\n`; result += `âĸ Completion Rate: ${analytics.completionRate ? (analytics.completionRate * 100).toFixed(1) + '%' : 'N/A'}\n\n`; result += `**Earnings:**\n`; result += `âĸ Total Earned: ${analytics.totalEarnings || 0} credits\n`; result += `âĸ Average Per Review: ${analytics.averageEarningsPerReview || 0} credits\n`; result += `âĸ Pending Earnings: ${analytics.pendingEarnings || 0} credits\n\n`; result += `**Engagement:**\n`; result += `âĸ Review Requests: ${analytics.totalRequests || 0}\n`; result += `âĸ Acceptance Rate: ${analytics.acceptanceRate ? (analytics.acceptanceRate * 100).toFixed(1) + '%' : 'N/A'}\n`; result += `âĸ Average Response Time: ${analytics.avgResponseTime || 'N/A'}\n\n`; if (analytics.topSpecializations && analytics.topSpecializations.length > 0) { result += `**Top Specializations:**\n`; analytics.topSpecializations.forEach((spec, index) => { result += `${index + 1}. ${spec.name} (${spec.count} reviews)\n`; }); result += '\n'; } result += `**đĄ Performance Tips:**\n`; result += `âĸ Maintain high ratings by providing thorough, constructive reviews\n`; result += `âĸ Respond quickly to requests to improve acceptance metrics\n`; result += `âĸ Specialize in specific areas to build expertise reputation\n`; result += `âĸ Use \`update_marketplace_profile\` to optimize your profile`; return this.baseUtils.formatResponse(result); } catch (error) { // If endpoint doesn't exist, provide helpful placeholder if (error.response?.status === 404) { return this.baseUtils.formatResponse( `đ **Marketplace Analytics** (Coming Soon)\n\n` + `The marketplace analytics feature is currently being developed.\n\n` + `**Alternative ways to track performance:**\n` + `âĸ Use \`get_review_requests\` to see your request history\n` + `âĸ Use \`get_credit_balance\` to track your earnings\n` + `âĸ Check individual agent profiles with \`get_reviewer_details\`` ); } throw new McpError(ErrorCode.InternalError, `Failed to get marketplace analytics: ${error.message}`); } } - Input schema definition for the get_marketplace_analytics tool, defining optional agentId and timeframe (week/month/quarter/year) parameters.
{ name: "get_marketplace_analytics", description: "Get marketplace analytics for your agents (earnings, performance, etc.)", inputSchema: { type: "object", properties: { agentId: { type: "string", description: "Specific agent ID (optional, shows all agents if omitted)" }, timeframe: { type: "string", enum: ["week", "month", "quarter", "year"], description: "Analytics timeframe" } } } - src/tools/marketplace/index.js:326-341 (registration)Registration of the get_marketplace_analytics handler in getToolHandlers(), mapping the tool name to the getMarketplaceAnalytics method.
// Get tool handlers for this module getToolHandlers() { return { "search_reviewers": this.searchReviewers.bind(this), "get_reviewer_details": this.getReviewerDetails.bind(this), "request_review": this.requestReview.bind(this), "get_review_requests": this.getReviewRequests.bind(this), "respond_to_review_request": this.respondToReviewRequest.bind(this), "create_marketplace_profile": this.createMarketplaceProfile.bind(this), "request_reviewer_for_paper": this.requestReviewerForPaper.bind(this), "update_marketplace_profile": this.updateMarketplaceProfile.bind(this), "get_marketplace_analytics": this.getMarketplaceAnalytics.bind(this), "get_incoming_requests": this.getIncomingRequests.bind(this), "bulk_respond_requests": this.bulkRespondRequests.bind(this), "update_request_status": this.updateRequestStatus.bind(this) }; - src/server-static.js:109-112 (registration)The MCP server's CallToolRequestSchema handler that dispatches incoming tool calls to the registered handler by name.
setupServerHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: this.tools, })); - src/utils/baseServer.js:277-378 (helper)The makeApiRequest helper used by getMarketplaceAnalytics to make HTTP requests to the backend API.
async makeApiRequest(endpoint, method = 'GET', data = null, requireAuth = true) { this._ensureInitialized(); // Lazy initialization console.error(`đĄ Making API request to: ${endpoint}`); const config = { method: method, url: `${this.apiBaseUrl}${endpoint}`, headers: {}, timeout: 30000 // Increased timeout for file uploads }; // Handle FormData vs JSON if (data && typeof data.getHeaders === 'function') { // This is FormData - let it set its own headers config.data = data; Object.assign(config.headers, data.getHeaders()); } else { // Regular JSON data config.headers['Content-Type'] = 'application/json'; if (data) { config.data = data; } } // Conditionally add authentication based on requireAuth parameter if (requireAuth) { // Use API key if available (preferred method) if (this.apiKey && this.apiKey !== 'test-api-key-for-mcp') { console.error(`đ Using API key authentication`); config.headers['X-API-Key'] = this.apiKey; } else { // Fall back to JWT token authentication const token = await this.ensureAuthentication(); console.error(`đ Using JWT token authentication`); config.headers['Authorization'] = `Bearer ${token}`; } } else { // For public endpoints, try to add auth if available but don't fail if missing if (this.apiKey && this.apiKey !== 'test-api-key-for-mcp') { console.error(`đ Adding optional API key authentication`); config.headers['X-API-Key'] = this.apiKey; } else if (this.jwtToken && this.tokenExpiry && Date.now() < this.tokenExpiry) { console.error(`đ Adding optional JWT token authentication`); config.headers['Authorization'] = `Bearer ${this.jwtToken}`; } else if (this.authToken) { console.error(`đ Adding optional injected token authentication`); config.headers['Authorization'] = `Bearer ${this.authToken}`; } else { console.error(`âšī¸ Making anonymous request (no authentication available)`); } } try { const response = await axios(config); console.error(`â API request successful: ${response.status}`); // Normalize response structure for backward compatibility const normalizedData = this.normalizeResponse(response.data); return normalizedData; } catch (error) { console.error(`â API request failed: ${error.message}`); if (error.response) { console.error(` Status: ${error.response.status}`); console.error(` Data:`, error.response.data); } // If we get a 401 with JWT auth (not API key), try refreshing token if (error.response?.status === 401 && config.headers['Authorization'] && !config._isRetry) { console.error('đ JWT token expired, attempting to refresh authentication...'); try { // Clear the current token and get a new one this.jwtToken = null; this.tokenExpiry = null; const newToken = await this.ensureAuthentication(); // Retry the request with the new token config.headers['Authorization'] = `Bearer ${newToken}`; config._isRetry = true; const retryResponse = await axios(config); console.error(`â Retry successful after token refresh`); return this.normalizeResponse(retryResponse.data); } catch (retryError) { console.error(`â Authentication refresh failed: ${retryError.message}`); throw new McpError( ErrorCode.InternalError, `Authentication refresh failed: ${retryError.message}` ); } } if (error.response) { throw new McpError( ErrorCode.InternalError, `API request failed: ${error.response.data.message || error.response.data.error || error.message}` ); } throw new McpError(ErrorCode.InternalError, `Network error: ${error.message}`); } }