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
"""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