guardian_search_by_length
Search Guardian articles by specifying word count range to find content matching desired length requirements.
Instructions
Search Guardian articles filtered by word count range
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Search terms (optional) | |
| min_words | No | Minimum word count (default: 0) | |
| max_words | No | Maximum word count (default: unlimited) | |
| section | No | Filter by section ID | |
| from_date | No | Start date (YYYY-MM-DD format) | |
| to_date | No | End date (YYYY-MM-DD format) | |
| order_by | No | Sort order: 'newest', 'oldest', 'relevance' (default: 'newest') | |
| page_size | No | Results per page, max 200 (default: 20) |
Implementation Reference
- The core handler function that implements the tool logic: parses args, builds Guardian API search params, fetches articles, filters by wordcount range, and formats results.export async function guardianSearchByLength(client: GuardianClient, args: any): Promise<string> { const params = SearchByLengthParamsSchema.parse(args); // Build search parameters const searchParams: Record<string, any> = { 'show-fields': 'headline,standfirst,byline,publication,firstPublicationDate,wordcount', 'order-by': params.order_by || 'newest', 'page-size': Math.min(params.page_size || 20, 200) // Get max for filtering }; if (params.query) { searchParams.q = params.query; } if (params.section) { searchParams.section = params.section; } if (params.from_date) { const fromDate = validateDate(params.from_date); if (!fromDate) { throw new Error(`Invalid from_date format: ${params.from_date}. Use YYYY-MM-DD format.`); } searchParams['from-date'] = fromDate; } if (params.to_date) { const toDate = validateDate(params.to_date); if (!toDate) { throw new Error(`Invalid to_date format: ${params.to_date}. Use YYYY-MM-DD format.`); } searchParams['to-date'] = toDate; } const response = await client.search(searchParams); const articles = response.response.results; // Filter by word count const minWords = params.min_words || 0; const maxWords = params.max_words || Number.POSITIVE_INFINITY; const filteredArticles = articles.filter(article => { const wordCount = article.fields?.wordcount; if (wordCount && !isNaN(Number(wordCount))) { const count = Number(wordCount); return count >= minWords && count <= maxWords; } return false; }); if (filteredArticles.length > 0) { const maxWordsDisplay = maxWords === Number.POSITIVE_INFINITY ? '∞' : maxWords.toString(); let result = `Found ${filteredArticles.length} article(s) with ${minWords}-${maxWordsDisplay} words:\n\n`; filteredArticles.forEach((article, index) => { result += `**${index + 1}. ${article.webTitle || 'Untitled'}**\n`; if (article.fields) { const { fields } = article; if (fields.byline) { result += `By: ${fields.byline}\n`; } if (fields.firstPublicationDate) { const pubDate = fields.firstPublicationDate.substring(0, 10); result += `Published: ${pubDate}\n`; } if (fields.wordcount) { result += `Word count: ${fields.wordcount}\n`; } if (fields.standfirst) { result += `Summary: ${fields.standfirst}\n`; } } result += `Section: ${article.sectionName || 'Unknown'}\n`; result += `URL: ${article.webUrl || 'N/A'}\n\n`; }); return result; } else { const maxWordsDisplay = maxWords === Number.POSITIVE_INFINITY ? '∞' : maxWords.toString(); return `No articles found with word count between ${minWords} and ${maxWordsDisplay} words.`; } }
- src/types/guardian.ts:112-121 (schema)Zod schema for input validation used in the handler to parse and validate arguments.export const SearchByLengthParamsSchema = z.object({ query: z.string().optional(), min_words: z.number().min(0).optional(), max_words: z.number().min(1).optional(), section: z.string().optional(), from_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), to_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), order_by: z.enum(['newest', 'oldest', 'relevance']).optional(), page_size: z.number().min(1).max(200).optional(), });
- src/tools/index.ts:30-30 (registration)Registers the guardianSearchByLength handler function under the tool name 'guardian_search_by_length' in the tools registry returned by registerTools.guardian_search_by_length: (args) => guardianSearchByLength(client, args),
- src/index.ts:261-305 (schema)MCP tool schema definition including name, description, and inputSchema advertised in the ListTools response.name: 'guardian_search_by_length', description: 'Search Guardian articles filtered by word count range', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search terms (optional)', }, min_words: { type: 'integer', description: 'Minimum word count (default: 0)', minimum: 0, }, max_words: { type: 'integer', description: 'Maximum word count (default: unlimited)', minimum: 1, }, section: { type: 'string', description: 'Filter by section ID', }, from_date: { type: 'string', description: 'Start date (YYYY-MM-DD format)', }, to_date: { type: 'string', description: 'End date (YYYY-MM-DD format)', }, order_by: { type: 'string', description: "Sort order: 'newest', 'oldest', 'relevance' (default: 'newest')", enum: ['newest', 'oldest', 'relevance'], }, page_size: { type: 'integer', description: 'Results per page, max 200 (default: 20)', minimum: 1, maximum: 200, }, }, }, },