guardian_search
Search and filter The Guardian archives since 1999 by query, section, tag, date, and more. Retrieve articles with customizable fields, sorting, and detail levels.
Instructions
Search Guardian articles with flexible filtering options
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| detail_level | No | Response detail level: 'minimal' (fast), 'standard' (default), 'full' (complete) | |
| from_date | No | Start date (YYYY-MM-DD format) | |
| order_by | No | Sort order: 'newest', 'oldest', 'relevance' (default: 'relevance') | |
| page | No | Page number (default: 1) | |
| page_size | No | Results per page, max 200 (default: 20) | |
| production_office | No | Filter by office: 'uk', 'us', 'au' | |
| query | No | Search terms (can be empty to browse all content) | |
| section | No | Filter by section ID (get available sections via guardian_get_sections) | |
| show_fields | No | Comma-separated fields to include (headline,standfirst,body,byline,thumbnail,publication) | |
| tag | No | Filter by tag (over 50,000 available tags) | |
| to_date | No | End date (YYYY-MM-DD format) |
Implementation Reference
- src/tools/guardian-search.ts:5-73 (handler)The core handler function `guardianSearch` that implements the tool logic: parses args with schema, builds Guardian API search parameters (handling dates, detail levels, fields), calls client.search(), and formats results.export async function guardianSearch(client: GuardianClient, args: any): Promise<string> { const params = SearchParamsSchema.parse(args); // Build search parameters for Guardian API const searchParams: Record<string, any> = {}; if (params.query) { searchParams.q = params.query; } if (params.section) { searchParams.section = params.section; } if (params.tag) { searchParams.tag = params.tag; } 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; } searchParams['order-by'] = params.order_by || 'relevance'; searchParams['page-size'] = params.page_size || 20; searchParams.page = params.page || 1; // Handle detail_level for performance optimization const detailLevel = params.detail_level || 'minimal'; let showFields = params.show_fields; if (!showFields) { switch (detailLevel) { case 'minimal': showFields = 'headline,sectionName,webPublicationDate'; break; case 'standard': showFields = 'headline,standfirst,byline,publication,firstPublicationDate'; break; case 'full': showFields = 'headline,standfirst,body,byline,publication,firstPublicationDate,wordcount'; break; } } searchParams['show-fields'] = showFields; if (params.production_office) { searchParams['production-office'] = params.production_office; } const response = await client.search(searchParams); const articles = response.response.results; const pagination = response.response; // Apply truncation based on detail level const formatOptions = { truncate: detailLevel !== 'full', // Only show full content for 'full' detail level maxLength: 500 }; return formatArticleResponse(articles, pagination, formatOptions); }
- src/types/guardian.ts:65-77 (schema)Zod input validation schema `SearchParamsSchema` used by the handler to parse and validate tool arguments.export const SearchParamsSchema = z.object({ query: z.string().optional(), section: z.string().optional(), tag: 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(), page: z.number().min(1).optional(), show_fields: z.string().optional(), production_office: z.enum(['uk', 'us', 'au']).optional(), detail_level: z.enum(['minimal', 'standard', 'full']).optional(), });
- src/tools/index.ts:21-39 (registration)The `registerTools` function that maps tool names to their handlers, including `guardian_search` bound to `guardianSearch(client, args)`. This map is used in the MCP server's handleToolCall.export function registerTools(client: GuardianClient): Record<string, ToolHandler> { return { guardian_search: (args) => guardianSearch(client, args), guardian_get_article: (args) => guardianGetArticle(client, args), guardian_longread: (args) => guardianLongread(client, args), guardian_lookback: (args) => guardianLookback(client, args), guardian_browse_section: (args) => guardianBrowseSection(client, args), guardian_get_sections: (args) => guardianGetSections(client, args), guardian_search_tags: (args) => guardianSearchTags(client, args), guardian_search_by_length: (args) => guardianSearchByLength(client, args), guardian_search_by_author: (args) => guardianSearchByAuthor(client, args), guardian_find_related: (args) => guardianFindRelated(client, args), guardian_get_article_tags: (args) => guardianGetArticleTags(client, args), guardian_content_timeline: (args) => guardianContentTimeline(client, args), guardian_author_profile: (args) => guardianAuthorProfile(client, args), guardian_topic_trends: (args) => guardianTopicTrends(client, args), guardian_top_stories_by_date: (args) => guardianTopStoriesByDate(client, args), guardian_recommend_longreads: (args) => guardianRecommendLongreads(client, args), };
- src/index.ts:60-118 (registration)MCP tool registration in listTools response: declares 'guardian_search' with name, description, and inputSchema matching the Zod schema.{ name: 'guardian_search', description: 'Search Guardian articles with flexible filtering options', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search terms (can be empty to browse all content)', }, section: { type: 'string', description: 'Filter by section ID (get available sections via guardian_get_sections)', }, tag: { type: 'string', description: 'Filter by tag (over 50,000 available tags)', }, 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: 'relevance')", enum: ['newest', 'oldest', 'relevance'], }, page_size: { type: 'integer', description: 'Results per page, max 200 (default: 20)', minimum: 1, maximum: 200, }, page: { type: 'integer', description: 'Page number (default: 1)', minimum: 1, }, show_fields: { type: 'string', description: 'Comma-separated fields to include (headline,standfirst,body,byline,thumbnail,publication)', }, production_office: { type: 'string', description: "Filter by office: 'uk', 'us', 'au'", enum: ['uk', 'us', 'au'], }, detail_level: { type: 'string', description: "Response detail level: 'minimal' (fast), 'standard' (default), 'full' (complete)", enum: ['minimal', 'standard', 'full'], }, }, }, },