Skip to main content
Glama

guardian_search_by_length

Filter and search The Guardian articles by word count range, section, date, and sorting preferences to find content matching specific criteria.

Instructions

Search Guardian articles filtered by word count range

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
from_dateNoStart date (YYYY-MM-DD format)
max_wordsNoMaximum word count (default: unlimited)
min_wordsNoMinimum word count (default: 0)
order_byNoSort order: 'newest', 'oldest', 'relevance' (default: 'newest')
page_sizeNoResults per page, max 200 (default: 20)
queryNoSearch terms (optional)
sectionNoFilter by section ID
to_dateNoEnd date (YYYY-MM-DD format)

Implementation Reference

  • The core handler function that executes the tool: parses args with schema, builds Guardian API search params, fetches articles, filters by word count 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.`; } }
  • Zod schema for validating input parameters to the guardian_search_by_length tool, used in the handler for parsing args.
    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(), });
  • Registers the guardianSearchByLength handler function under the 'guardian_search_by_length' key in the tools registry returned by registerTools.
    guardian_search_by_length: (args) => guardianSearchByLength(client, args),
  • src/index.ts:261-305 (registration)
    MCP protocol registration of the tool in the ListTools response, including name, description, and JSON schema matching the Zod schema.
    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, }, }, }, },
  • src/tools/index.ts:9-9 (registration)
    Import of the handler function into the tools index module.
    import { guardianSearchByLength } from './guardian-search-by-length.js';

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/jbenton/guardian-mcp-server'

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