AFP新闻MCP服务

AFP新闻MCP服务是一个通过Model Context Protocol向AI助手提供AFP新闻搜索、文章获取、相似推荐、媒体检索与新闻简报生成等能力的服务,适用于在Claude、ChatGPT等MCP客户端中集成实时权威新闻内容。

  • by julesbonnard
  • TypeScript
  • 本地部署
  • 5 星标
  • 更新于
在 GitHub 查看 julesbonnard/afpnews-mcp-server

使用说明

afpnews-mcp

MCP (Model Context Protocol) server that exposes AFP news content as tools for AI assistants. Works with any MCP-compatible client.

The package can also be used as a library without MCP server glue via afpnews-mcp-server/definitions.

Prerequisites

  • Bun 1.3+
  • An AFP API account (API key + username/password)

Setup

git clone https://github.com/julesbonnard/afpnews-mcp-server.git
cd afpnews-mcp-server
bun install

Create a .env file:

APICORE_API_KEY=your-api-key
APICORE_USERNAME=your-username
APICORE_PASSWORD=your-password

Usage

Stdio transport (default)

For local MCP clients like Claude Code or Claude Desktop:

{
  "mcpServers": {
    "afpnews": {
      "command": "bun",
      "args": ["src/index.ts"],
      "cwd": "/absolute/path/to/afpnews-mcp-server",
      "env": {
        "APICORE_API_KEY": "your-api-key",
        "APICORE_USERNAME": "your-username",
        "APICORE_PASSWORD": "your-password"
      }
    }
  }
}

HTTP transport

For remote or multi-user deployments. Stateless: each request is served by a fresh MCP server instance built from that request's own bearer token, so any number of instances can sit behind a plain round-robin load balancer with no sticky sessions or shared store. Users authenticate via OAuth2 PKCE using their AFP credentials.

Required environment variables for HTTP mode:

APICORE_API_KEY=your-api-key
APICORE_BASE_URL=https://api.afp.com
MCP_SERVER_URL=https://news-mcp.example.com
JWT_SECRET=a-random-string-of-at-least-32-characters
MCP_TRANSPORT=http
PORT=3000

Optional:

  • MCP_ALLOWED_REDIRECT_URIS — comma-separated list of allowed OAuth redirect URIs. localhost/127.0.0.1 (any port) is always allowed regardless of this list — it covers any client that runs a local OAuth callback server (Claude Code, MCP Inspector, most IDEs). This var is the single place to allowlist clients with a fixed, non-localhost callback URL. Known ones:

    • Claude: https://claude.ai/api/mcp/auth_callback, https://claude.com/api/mcp/auth_callback
    • ChatGPT: https://chatgpt.com/connector_platform_oauth_redirect, https://chatgpt.com/oauth/callback, https://chat.openai.com/oauth/callback
    • Mistral (Le Chat): https://callback.mistral.ai/v1/integrations_auth/oauth2_callback

    Add others as you connect new clients — the exact redirect_uri shows up in the failed /oauth/authorize request when a client isn't allowlisted yet.

bun src/index.ts

If you expose the server remotely, use HTTPS.

Docker

docker build -t afpnews-mcp .
docker run \
  -e APICORE_API_KEY=your-api-key \
  -e APICORE_BASE_URL=https://api.afp.com \
  -e MCP_SERVER_URL=https://news-mcp.example.com \
  -e JWT_SECRET=your-secret-32-chars-minimum \
  -e MCP_TRANSPORT=http \
  -p 3000:3000 \
  afpnews-mcp

Cloudflare Workers

The HTTP transport is built as a plain Hono app with no server-side state (the OAuth authorization code and the bearer tokens are all self-contained), so it also runs as a Cloudflare Worker via src/http/worker.ts — no KV, Durable Objects, or other bindings needed.

bunx wrangler login
bunx wrangler secret put APICORE_API_KEY
bunx wrangler secret put JWT_SECRET

Edit wrangler.toml's [vars] (APICORE_BASE_URL, MCP_SERVER_URL — the latter must match your actual *.workers.dev subdomain or custom domain), then:

bun run dev:worker      # local dev server via workerd (bunx wrangler dev)
bun run deploy:worker   # bunx wrangler deploy

Rate limiting isn't implemented in-process (it would be per-isolate and largely pointless on the edge) — use Cloudflare's own Rate Limiting in front of the Worker instead.

As a library (without MCP server dependency)

You can import pure definitions (tools, prompts, resources) and wire them into your own runtime:

import { AFP_DEFINITIONS } from 'afpnews-mcp-server/definitions';

const { tools, prompts, resources } = AFP_DEFINITIONS;

Or import each collection directly:

import {
  TOOL_DEFINITIONS,
  PROMPT_DEFINITIONS,
  RESOURCE_DEFINITIONS,
} from 'afpnews-mcp-server/definitions';

Each definition is framework-agnostic:

  • tools: name, title, description, inputSchema, handler(apicore, args)
  • prompts: name, title, description, argsSchema, handler(args)
  • resources: name, uri, description, mimeType, handler()

Tools

Tool Description
afp_search_articles Search AFP articles with filters, presets, and full-text mode
afp_get_article Get a full article by its UNO identifier
afp_find_similar Find similar articles (More Like This) from a UNO
afp_list_facets List facet values (topics, genres, countries) with frequency counts
afp_search_media Search AFP media documents (photos, videos, graphics)
afp_get_media Get a full media document by UNO, with optional base64 image embed

Search presets

The afp_search_articles tool supports presets that apply predefined filters:

  • a-la-une — Top story (French, last 24h)
  • agenda — Upcoming events
  • previsions — Editorial planning / forecasts
  • major-stories — Major articles

List preset

  • trending-topics — Trending topics from the last 24h

Full text

By default, afp_search_articles returns excerpts (first 2 paragraphs). Set fullText: true to get the complete article body. Presets default to full text.

Pagination

Use offset to paginate through results (e.g. offset: 10 to skip the first 10). For large chronological scans, prefer narrowing dateFrom/dateTo ranges in facets over high offsets. Keep size small (10–20) for best performance.

Prompts

Prompt Description
daily-briefing Generate a daily news briefing
comprehensive-analysis In-depth analysis on a topic
factcheck Verify facts using AFP factchecks
country-news News summary for a specific country

Resources

Resource Description
afp://topics AFP Stories topic catalog by language

Development

bun install
bun test

Internal Architecture

  • src/tools/*.ts, src/prompts/*.ts, src/resources/*.ts contain pure definitions.
  • src/tools/index.ts, src/prompts/index.ts, src/resources/index.ts contain MCP registration glue.
  • src/definitions.ts exports aggregated, server-agnostic definitions:
    • AFP_DEFINITIONS
    • TOOL_DEFINITIONS
    • PROMPT_DEFINITIONS
    • RESOURCE_DEFINITIONS

License

ISC