Skip to main content
Glama

Targetprocess MCP Server

context-builder.ts5.6 kB
import { TPService } from '../api/client/tp.service.js'; import { logger } from '../utils/logger.js'; export interface TPContextInfo { projects: Array<{ id: number; name: string; abbreviation: string; entityState: string; program?: string; }>; entityTypes: string[]; programs: Array<{ id: number; name: string; }>; entityStates: Array<{ id: number; name: string; entityType?: string; }>; users: Array<{ id: number; fullName: string; login: string; }>; } export class TPContextBuilder { constructor(private service: TPService) {} async buildContext(): Promise<TPContextInfo> { const context: TPContextInfo = { projects: [], entityTypes: [], programs: [], entityStates: [], users: [] }; // Fetch projects with error handling try { const projectsResult = await this.service.searchEntities<any>( 'Project', undefined, ['EntityState', 'Program'], 20 ); if (projectsResult && Array.isArray(projectsResult)) { context.projects = projectsResult.map((project: any) => ({ id: project.Id, name: project.Name, abbreviation: project.Abbreviation || '', entityState: project.EntityState?.Name || 'Unknown', program: project.Program?.Name })); } } catch (error) { logger.error('Failed to fetch projects for context:', error); } // Fetch programs with error handling try { const programsResult = await this.service.searchEntities<any>( 'Program', undefined, undefined, 20 ); if (programsResult && Array.isArray(programsResult)) { context.programs = programsResult.map((program: any) => ({ id: program.Id, name: program.Name })); } } catch (error) { logger.error('Failed to fetch programs for context:', error); } // Fetch entity states with error handling try { const statesResult = await this.service.searchEntities<any>( 'EntityState', undefined, ['EntityType'], 50 ); if (statesResult && Array.isArray(statesResult)) { context.entityStates = statesResult.map((state: any) => ({ id: state.Id, name: state.Name, entityType: state.EntityType?.Name })); } } catch (error) { logger.error('Failed to fetch entity states for context:', error); } // Fetch users with error handling try { const usersResult = await this.service.searchEntities<any>( 'GeneralUser', undefined, undefined, 20 ); if (usersResult && Array.isArray(usersResult)) { context.users = usersResult.map((user: any) => ({ id: user.Id, fullName: user.FullName, login: user.Login })); } } catch (error) { logger.error('Failed to fetch users for context:', error); } // Discover available entity types const entityTypes = new Set<string>(); const baseTypes = ['Project', 'Program', 'EntityState', 'GeneralUser']; const commonTypes = ['UserStory', 'Bug', 'Task', 'Feature', 'Epic', 'Iteration', 'Team', 'Release', 'TestCase', 'TestPlan']; // Add base types that we know exist baseTypes.forEach(type => entityTypes.add(type)); // Test common entity types for (const type of commonTypes) { try { const result = await this.service.searchEntities<any>( type, undefined, undefined, 1 ); if (result && Array.isArray(result) && result.length > 0) { entityTypes.add(type); } } catch (error) { // Type doesn't exist or not accessible, skip silently } } context.entityTypes = Array.from(entityTypes).sort(); return context; } generateContextDescription(context: TPContextInfo): string { const parts = []; parts.push(`This TargetProcess instance contains:`); if (context.projects.length > 0) { parts.push(`\n**Projects** (${context.projects.length} available):`); context.projects.slice(0, 10).forEach(p => { const program = p.program ? ` [${p.program}]` : ''; parts.push(`- ${p.name} (${p.abbreviation}) - ${p.entityState}${program}`); }); if (context.projects.length > 10) { parts.push(`... and ${context.projects.length - 10} more projects`); } } if (context.programs.length > 0) { parts.push(`\n**Programs** (${context.programs.length} available):`); context.programs.slice(0, 5).forEach(p => { parts.push(`- ${p.name}`); }); if (context.programs.length > 5) { parts.push(`... and ${context.programs.length - 5} more programs`); } } if (context.entityTypes.length > 0) { parts.push(`\n**Available Entity Types:**`); parts.push(context.entityTypes.join(', ')); } if (context.entityStates.length > 0) { parts.push(`\n**Entity States:**`); const statesByType = context.entityStates.reduce((acc, state) => { const type = state.entityType || 'General'; if (!acc[type]) acc[type] = []; acc[type].push(state.name); return acc; }, {} as Record<string, string[]>); Object.entries(statesByType).forEach(([type, states]) => { parts.push(`- ${type}: ${states.slice(0, 5).join(', ')}${states.length > 5 ? '...' : ''}`); }); } return parts.join('\n'); } }

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/aaronsb/apptio-target-process-mcp'

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