Skip to main content
Glama
Jameswlepage

WordPress Trac MCP Server

by Jameswlepage

getTracInfo

Retrieve WordPress Trac metadata including components, milestones, priorities, and severities to support development tracking and project management.

Instructions

Get WordPress Trac metadata like components, milestones, priorities, and severities.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeYesType of Trac information to retrieve

Implementation Reference

  • src/index.ts:140-153 (registration)
    Registration of the getTracInfo tool in the tools/list response, including name, description, and input schema.
    name: "getTracInfo", description: "Get WordPress Trac metadata like components, milestones, priorities, and severities.", inputSchema: { type: "object", properties: { type: { type: "string", enum: ["components", "milestones", "priorities", "severities"], description: "Type of Trac information to retrieve", }, }, required: ["type"], }, },
  • Input schema definition for getTracInfo tool.
    inputSchema: { type: "object", properties: { type: { type: "string", enum: ["components", "milestones", "priorities", "severities"], description: "Type of Trac information to retrieve", }, }, required: ["type"], },
  • Core handler implementation for the getTracInfo tool. Queries the Trac ticket list in CSV format, parses columns based on the requested type (milestones, priorities, types, statuses), collects unique values, sorts them, and returns a formatted result with metadata. Handles unsupported types like components and severities with appropriate errors.
    case "getTracInfo": { const { type } = args; try { let data: any = {}; let uniqueValues = new Set<string>(); // Get a sample of tickets to extract unique values for the requested field const queryUrl = new URL('https://core.trac.wordpress.org/query'); queryUrl.searchParams.set('format', 'csv'); queryUrl.searchParams.set('max', '1000'); // Get more tickets for better coverage const response = await fetch(queryUrl.toString(), { headers: { 'User-Agent': 'Mozilla/5.0 (compatible; WordPress-Trac-MCP-Server/1.0)', 'Accept': 'text/csv,text/plain,*/*', 'Accept-Language': 'en-US,en;q=0.9', } }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const csvData = await response.text(); // Parse CSV data const lines = csvData.replace(/^\uFEFF/, '').trim().split('\n'); const headers = (lines[0] || '').split(',').map(h => h.replace(/"/g, '').trim()); // Find the column index for the requested type let columnIndex = -1; switch (type) { case "components": // Components are not in the default query, need different approach throw new Error(`Components list not available in default query. Try using the search function instead.`); case "milestones": columnIndex = headers.indexOf('Milestone'); break; case "priorities": columnIndex = headers.indexOf('Priority'); break; case "severities": // Severities are not in the default query throw new Error(`Severities list not available in default query. Try using the search function instead.`); case "types": columnIndex = headers.indexOf('Type'); break; case "statuses": columnIndex = headers.indexOf('Status'); break; default: throw new Error(`Unknown info type: ${type}. Available types: milestones, priorities, types, statuses`); } if (columnIndex === -1) { throw new Error(`Column not found for type: ${type}. Available columns: ${headers.join(', ')}`); } // Extract unique values using better CSV parsing for (let i = 1; i < lines.length && lines[i]; i++) { const line = lines[i]?.trim(); if (!line) continue; // Better CSV parsing - handle quoted fields properly const values = []; let currentField = ''; let inQuotes = false; let escapeNext = false; for (let j = 0; j < line.length; j++) { const char = line[j]; if (escapeNext) { currentField += char; escapeNext = false; continue; } if (char === '\\') { escapeNext = true; continue; } if (char === '"') { if (inQuotes) { // Check if this is an escaped quote if (j + 1 < line.length && line[j + 1] === '"') { currentField += '"'; j++; // Skip the next quote } else { inQuotes = false; } } else { inQuotes = true; } } else if (char === ',' && !inQuotes) { values.push(currentField.trim()); currentField = ''; } else { currentField += char; } } values.push(currentField.trim()); if (values[columnIndex]?.trim()) { uniqueValues.add(values[columnIndex]?.trim() || ''); } } data = Array.from(uniqueValues).sort(); result = { id: type, title: `WordPress Trac ${type}`, text: `${type.charAt(0).toUpperCase() + type.slice(1)} available in WordPress Trac:\n\n${data.join('\n')}`, url: 'https://core.trac.wordpress.org/', metadata: { type, data, total: data.length, }, }; } catch (error) { result = { id: type, title: `Error loading ${type}`, text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}. Available types: components, milestones, priorities, severities, types, statuses`, url: 'https://core.trac.wordpress.org/', metadata: { error: true }, }; } break; }

Latest Blog Posts

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/Jameswlepage/trac-mcp'

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