Skip to main content
Glama
tools.py6.72 kB
"""MCP tool definitions for NYT API endpoints.""" from datetime import datetime from typing import Literal from nytimes_mcp.nyt_client import NytClient from nytimes_mcp.utils import ( format_articles_response, format_news_items_response, format_popular_response, ) # Module-level client _nyt_client: NytClient | None = None def get_client() -> NytClient: """Get or create the shared HTTP client.""" global _nyt_client if _nyt_client is None: _nyt_client = NytClient() return _nyt_client type NewsSource = Literal["nyt", "inyt", "all"] type SortOrder = Literal["best", "newest", "oldest", "relevance"] type PopularityType = Literal["viewed", "shared", "emailed"] type PopularityPeriod = Literal["1", "7", "30"] async def search_articles( query: str, sort: SortOrder = "best", begin_date: str | None = None, end_date: str | None = None, page: int | None = None, ) -> dict: """ Search New York Times articles by query, date range, and other criteria. Args: query: Search query string sort: Sort order - "best", "newest", "oldest", or "relevance" (default: "best") begin_date: Start date in YYYYMMDD format (optional) end_date: End date in YYYYMMDD format (optional) page: Page number for pagination (10 articles per page), 0-indexed, max=100 (optional) Returns: Formatted response with articles array containing headline, snippet, web_url, and pub_date """ params = { "q": query.strip(), "sort": sort, } # Add optional date parameters only if specified if begin_date and len(begin_date) == 8: params["begin_date"] = begin_date elif begin_date: raise ValueError("begin_date must be in YYYYMMDD format.") if end_date and len(end_date) == 8: params["end_date"] = end_date elif end_date: raise ValueError("end_date must be in YYYYMMDD format.") # Only add page if it's greater than 0 if page and page > 0 and page <= 100: params["page"] = str(page) elif page and page != 0: raise ValueError("Page number must be between 0 and 100.") client = get_client() response = await client.make_nyt_request("search/v2/articlesearch.json", params) return format_articles_response(response) async def get_news_sections() -> list[str]: """ Get the list of available news sections from the NYT news wire. Returns: List of section names as strings """ client = get_client() response = await client.make_nyt_request("news/v3/content/section-list.json", {}) sections = response.get("results", []) return [section.get("section") for section in sections if "section" in section] async def get_news_wire( limit: int = 20, offset: int = 0, source: NewsSource = "nyt", section: str = "all", ) -> dict: """ Get the latest news items from the NYT news wire (real-time news feed). Args: limit: Number of items to return (default: 20) offset: Pagination offset (default: 0) source: News source - "nyt", "inyt", or "all" (default: "nyt") section: News section (e.g., "all", "world", "business") (default: "all"). To see the latest list of sections available, refer to the get_news_sections tool. Returns: Formatted response with news_items array containing title, abstract, url, section, subsection, published_date, and byline """ params = { "limit": limit, "offset": offset, } client = get_client() response = await client.make_nyt_request( f"news/v3/content/{source}/{section}.json", params ) return format_news_items_response(response) async def get_most_popular( popularity_type: PopularityType = "viewed", time_period: PopularityPeriod = "1", ) -> dict: """ Get the most popular New York Times articles. Args: popularity_type: Type of popularity - "viewed", "shared", or "emailed" (default: "viewed") time_period: Time period in days - "1", "7", or "30" (default: "1") Returns: Formatted response with articles array containing title, abstract, url, and published_date """ client = get_client() response = await client.make_nyt_request( f"mostpopular/v2/{popularity_type}/{time_period}.json", {}, ) return format_popular_response(response) async def get_archive(year: int | None = None, month: int | None = None) -> dict: """ Get New York Times articles from a specific month and year archive. Args: year: Year (default: current year) month: Month 1-12 (default: current month) Returns: Full NYT archive API response (unformatted) """ now = datetime.now() year = year or now.year month = month or now.month client = get_client() response = await client.make_nyt_request(f"archive/v1/{year}/{month}.json", {}) # Return raw response (no formatting for archive) return response async def get_bestseller_list_names() -> list[str]: """ Get overview of New York Times bestseller lists. Returns: Full NYT Books API response (unformatted) """ client = get_client() response = await client.make_nyt_request("books/v3/lists/overview.json", {}) # Return raw response (no formatting for books) return [r["list_name_encoded"] for r in response["results"]["lists"]] async def get_bestseller_lists_overview() -> dict: """ Get overview of New York Times bestseller lists. Returns: Full NYT Books API response (unformatted) """ client = get_client() response = await client.make_nyt_request("books/v3/lists/overview.json", {}) # Return raw response (no formatting for books) return response async def get_bestseller_list(list: str = "hardcover-fiction", offset: int = 0) -> dict: """ Get New York Times bestseller lists. Args: list: List name (e.g., "hardcover-fiction", "hardcover-nonfiction", "paperback-nonfiction") Default is "hardcover-fiction" offset: Pagination offset (default: 0) Returns: Full NYT Books API response (unformatted) """ params = {"offset": offset} client = get_client() response = await client.make_nyt_request( f"books/v3/lists/current/{list}.json", params, ) # Return raw response (no formatting for books) return response async def cleanup_http_client(): """Close the shared HTTP client.""" global _nyt_client if _nyt_client is not None: await _nyt_client.client.aclose() _nyt_client = None

Implementation Reference

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/jeffmm/nytimes-mcp'

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