getProjectChanges
Retrieve recent modifications for a Weblate translation project to track updates and monitor translation activity.
Instructions
Get recent changes for a specific project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectSlug | Yes | The slug of the project |
Implementation Reference
- src/tools/changes.tool.ts:80-127 (handler)Primary handler for the 'getProjectChanges' MCP tool. Includes registration via @Tool decorator, input schema validation with Zod, execution logic that calls the Weblate API service, formats results using helper methods, handles empty results and errors, and returns structured content.@Tool({ name: 'getProjectChanges', description: 'Get recent changes for a specific project', parameters: z.object({ projectSlug: z.string().describe('The slug of the project'), }), }) async getProjectChanges({ projectSlug }: { projectSlug: string }) { try { const result = await this.weblateApiService.getProjectChanges(projectSlug); if (result.results.length === 0) { return { content: [ { type: 'text', text: `No changes found for project "${projectSlug}".`, }, ], }; } const changesList = result.results .slice(0, 20) .map(change => this.formatChangeResult(change)) .join('\n\n---\n\n'); return { content: [ { type: 'text', text: `Recent changes in project "${projectSlug}" (${result.count} total):\n\n${changesList}`, }, ], }; } catch (error) { this.logger.error(`Failed to get changes for project ${projectSlug}`, error); return { content: [ { type: 'text', text: `Error getting changes for project "${projectSlug}": ${error.message}`, }, ], isError: true, }; } }
- Core service method that performs the actual API call to retrieve project changes using projectsChangesRetrieve from the Weblate client, handles response parsing, and error management. Called by the tool handler via proxies.async getProjectChanges( projectSlug: string ): Promise<{ results: Change[]; count: number; next?: string; previous?: string }> { try { const client = this.weblateClientService.getClient(); const response = await projectsChangesRetrieve({ client, path: { slug: projectSlug }, }); const changeList = response.data as any; // Handle different response formats if (Array.isArray(changeList)) { return { results: changeList, count: changeList.length, }; } if (changeList && changeList.results) { return { results: changeList.results || [], count: changeList.count || 0, next: changeList.next || undefined, previous: changeList.previous || undefined, }; } return { results: [], count: 0 }; } catch (error) { this.logger.error(`Failed to get changes for project ${projectSlug}`, error); throw new Error(`Failed to get project changes: ${error.message}`); } }
- src/tools/changes.tool.ts:127-247 (helper)Helper method used by the handler to format each change into a markdown string with action, user, time, and target details.} @Tool({ name: 'getComponentChanges', description: 'Get recent changes for a specific component', parameters: z.object({ projectSlug: z.string().describe('The slug of the project'), componentSlug: z.string().describe('The slug of the component'), }), }) async getComponentChanges({ projectSlug, componentSlug, }: { projectSlug: string; componentSlug: string; }) { try { const result = await this.weblateApiService.getComponentChanges( projectSlug, componentSlug, ); if (result.results.length === 0) { return { content: [ { type: 'text', text: `No changes found for component "${componentSlug}" in project "${projectSlug}".`, }, ], }; } const changesList = result.results .slice(0, 20) .map(change => this.formatChangeResult(change)) .join('\n\n---\n\n'); return { content: [ { type: 'text', text: `Recent changes in component "${componentSlug}" (${result.count} total):\n\n${changesList}`, }, ], }; } catch (error) { this.logger.error( `Failed to get changes for component ${componentSlug} in project ${projectSlug}`, error, ); return { content: [ { type: 'text', text: `Error getting changes for component "${componentSlug}": ${error.message}`, }, ], isError: true, }; } } @Tool({ name: 'getChangesByUser', description: 'Get recent changes by a specific user', parameters: z.object({ user: z.string().describe('Username to filter by'), limit: z.number().optional().describe('Number of changes to return (default: 20)').default(20), }), }) async getChangesByUser({ user, limit = 20, }: { user: string; limit?: number; }) { try { const result = await this.weblateApiService.getChangesByUser(user, limit); if (result.results.length === 0) { return { content: [ { type: 'text', text: `No changes found for user "${user}".`, }, ], }; } const changesList = result.results .slice(0, limit) .map(change => this.formatChangeResult(change)) .join('\n\n---\n\n'); return { content: [ { type: 'text', text: `Recent changes by user "${user}" (${result.count} total):\n\n${changesList}`, }, ], }; } catch (error) { this.logger.error(`Failed to get changes by user ${user}`, error); return { content: [ { type: 'text', text: `Error getting changes by user "${user}": ${error.message}`, }, ], isError: true, }; } } private formatChangeResult(change: Change): string {
- src/tools/changes.tool.ts:83-85 (schema)Zod schema defining the input parameter for the tool: projectSlug as a required string.parameters: z.object({ projectSlug: z.string().describe('The slug of the project'), }),
- src/tools/changes.tool.ts:80-86 (registration)@Tool decorator that registers the getProjectChanges method as an MCP tool with name, description, and parameters schema.@Tool({ name: 'getProjectChanges', description: 'Get recent changes for a specific project', parameters: z.object({ projectSlug: z.string().describe('The slug of the project'), }), })