Skip to main content
Glama
mmntm

Weblate MCP Server

by mmntm

searchStringInProject

Locate specific text within translation projects by searching source, target, or both in Weblate MCP Server.

Instructions

Search for translations containing specific text in a project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectSlugYesThe slug of the project to search in
searchInNoWhere to search: source text, target translation, or bothboth
valueYesThe text to search for

Implementation Reference

  • Primary tool handler: @Tool decorator with name, description, Zod schema; executes search via service, limits to 10 results, formats output, handles empty results and errors.
    @Tool({ name: 'searchStringInProject', description: 'Search for translations containing specific text in a project', parameters: z.object({ projectSlug: z.string().describe('The slug of the project to search in'), value: z.string().describe('The text to search for'), searchIn: z .enum(['source', 'target', 'both']) .optional() .describe('Where to search: source text, target translation, or both') .default('both'), }), }) async searchStringInProject({ projectSlug, value, searchIn = 'both', }: { projectSlug: string; value: string; searchIn?: 'source' | 'target' | 'both'; }) { try { const results = await this.weblateApiService.searchStringInProject( projectSlug, value, searchIn, ); if (results.length === 0) { return { content: [ { type: 'text', text: `No translations found containing "${value}" in project "${projectSlug}"`, }, ], }; } const formattedResults = results .slice(0, 10) .map(this.formatTranslationResult) .join('\n\n'); const totalText = results.length > 10 ? `\n\n*Showing first 10 of ${results.length} results*` : ''; return { content: [ { type: 'text', text: `Found ${results.length} translations containing "${value}" in project "${projectSlug}":\n\n${formattedResults}${totalText}`, }, ], }; } catch (error) { this.logger.error( `Failed to search for "${value}" in ${projectSlug}`, error, ); return { content: [ { type: 'text', text: `Error searching for "${value}" in project "${projectSlug}": ${error.message}`, }, ], isError: true, }; } }
  • MCP tool registration: WeblateTranslationsTool class (containing searchStringInProject handler) is provided in AppModule, making it available to McpModule for tool discovery.
    WeblateClientService, WeblateProjectsService, WeblateComponentsService, WeblateLanguagesService, WeblateTranslationsService, WeblateChangesService, WeblateApiService, WeblateStatisticsService, WeblateProjectsTool, WeblateComponentsTool, WeblateLanguagesTool, WeblateTranslationsTool, WeblateChangesTool, WeblateStatisticsTool, ], })
  • Zod input schema defining parameters for the tool: projectSlug (string), value (string), searchIn (enum: source|target|both, default 'both').
    parameters: z.object({ projectSlug: z.string().describe('The slug of the project to search in'), value: z.string().describe('The text to search for'), searchIn: z .enum(['source', 'target', 'both']) .optional() .describe('Where to search: source text, target translation, or both') .default('both'), }),
  • Private helper method to format individual translation results for output, used in handler to create readable summaries.
    private formatTranslationResult(translation: Unit): string { const status = translation.approved ? '✅ Approved' : translation.translated ? '📝 Translated' : '❌ Untranslated'; const sourceText = translation.source && Array.isArray(translation.source) ? translation.source.join('') : (translation.source || '(empty)'); const targetText = translation.target && Array.isArray(translation.target) ? translation.target.join('') : (translation.target || '(empty)'); return `**Key:** ${translation.context} **Source:** ${sourceText} **Target:** ${targetText} **Status:** ${status} **Context:** ${translation.context || '(none)'} **Note:** ${translation.note || '(none)'} **ID:** ${translation.id}`; }
  • Core search logic: searches source and/or target texts across project using Weblate API, deduplicates results by unit ID.
    async searchStringInProject( projectSlug: string, searchValue: string, searchIn: SearchIn = 'both', ): Promise<Unit[]> { try { let results: Unit[] = []; if (searchIn === 'source' || searchIn === 'both') { const sourceResults = await this.searchTranslations( projectSlug, undefined, undefined, undefined, searchValue, ); results = results.concat(sourceResults.results); } if (searchIn === 'target' || searchIn === 'both') { const targetResults = await this.searchTranslations( projectSlug, undefined, undefined, undefined, undefined, searchValue, ); results = results.concat(targetResults.results); } // Remove duplicates based on unit ID const uniqueResults = results.filter( (unit, index, self) => index === self.findIndex(u => u.id === unit.id) ); return uniqueResults; } catch (error) { this.logger.error( `Failed to search string in project ${projectSlug}`, error, ); throw new Error( `Failed to search string in project: ${error.message}`, ); } }

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/mmntm/weblate-mcp'

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