guardian_search_by_author
Find Guardian articles written by specific journalists, with options to filter by date, section, keywords, and sort results.
Instructions
Search Guardian articles by specific author/journalist
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| author | Yes | Author name to search for | |
| query | No | Additional search terms within author's articles | |
| 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) | |
| page | No | Page number (default: 1) |
Implementation Reference
- The core handler function that executes the tool logic: parses input params, constructs Guardian search query for articles by author, filters results by byline match, and formats output with article details.export async function guardianSearchByAuthor(client: GuardianClient, args: any): Promise<string> { const params = SearchByAuthorParamsSchema.parse(args); // Build search parameters - we'll search for the author name in the byline const searchParams: Record<string, any> = { 'show-fields': 'headline,standfirst,byline,publication,firstPublicationDate,wordcount', 'order-by': params.order_by || 'newest', 'page-size': params.page_size || 20, page: params.page || 1 }; // Combine author search with optional query if (params.query) { searchParams.q = `"${params.author}" ${params.query}`; } else { searchParams.q = `"${params.author}"`; } 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 to only articles where the author name appears in the byline const authorArticles = articles.filter(article => { const byline = article.fields?.byline || ''; return byline.toLowerCase().includes(params.author.toLowerCase()); }); if (authorArticles.length > 0) { const pagination = response.response; let result = `Found ${authorArticles.length} article(s) by ${params.author}:\n\n`; authorArticles.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`; }); if (pagination.pages > 1) { result += `\nPagination: Page ${pagination.currentPage} of ${pagination.pages}\n`; } return result; } else { return `No articles found by author '${params.author}'.`; } }
- src/types/guardian.ts:123-132 (schema)Zod schema defining and validating the input parameters for the guardian_search_by_author tool, used in the handler for parsing args.export const SearchByAuthorParamsSchema = z.object({ author: z.string(), query: z.string().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(), page: z.number().min(1).optional(), });
- src/tools/index.ts:21-39 (registration)Tool registration function that maps the 'guardian_search_by_author' name to the handler function, used by the MCP server.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:307-350 (registration)MCP tool listing registration including name, description, and input schema for the ListToolsRequest, advertised to MCP clients.name: 'guardian_search_by_author', description: 'Search Guardian articles by specific author/journalist', inputSchema: { type: 'object', properties: { author: { type: 'string', description: 'Author name to search for', }, query: { type: 'string', description: "Additional search terms within author's articles", }, 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, }, page: { type: 'integer', description: 'Page number (default: 1)', minimum: 1, }, }, required: ['author'], },
- Import of helper function used for date validation in the handler.import { validateDate } from '../utils/formatters.js';