Skip to main content
Glama
TahiryMSX

basic-mcp-server

by TahiryMSX

ai-news-mcp

Model Context Protocol サーバーで、AIニュースコーパスに関する質問に回答します。Streamable HTTP で提供されます。

これはAIニュースエージェントのデータバックエンドです。エージェントが質問し、これらのツールがSupabase Postgresの news.articles を検索・読み取ります。

すべてのツールは読み取り専用です。 読み取り専用の保証 を参照してください。

ステートレス: 各リクエストは独自のMCPサーバーインスタンスを取得し、リクエスト間で何も保持されないため、セッションIDやスティッキールーティングはありません。データベースプールは共有されます。

コーパス

Supabase Postgres内の news.articles。2026-08-24時点:

記事数

1083

日付範囲

2026-04-01 → 2026-08-24

言語

フランス語

異なるカテゴリ数

668

異なるタグ数

927

ツール設計を左右する2つの特性:

  • カテゴリは自由テキストで断片化されている — 1083記事に対して668の異なる値があり、CybersécuritéCybersécurité des agents IACybersécurité et agents IA のような類似重複があります。完全一致のカテゴリマッチングはほぼ無意味なので、search_news はカテゴリを大文字小文字を区別しない部分文字列としてマッチングします。

  • views はすべての行で NULL です。 意図的に「最も読まれた」ツールはありません。ノイズを返すだけだからです。

Related MCP server: MCP Server Basic Example

公開内容

種類

名前

説明

ツール

search_news

自由テキスト、カテゴリ、タグ、日付範囲で検索。ページング対応

ツール

get_article

id または article_url で1記事を完全な形で取得

ツール

list_categories

カウント付きの異なるカテゴリ一覧。発見用

ツール

list_tags

カウント付きの異なる tags または key_words 一覧

ツール

news_stats

カバレッジ: 合計、日付範囲、月別ボリューム、主要テーマ

リソース

news://overview

コーパスサイズ、日付範囲、トップタグをJSONで

プロンプト

ai_news_analyst

回答をコーパスに基づかせ、引用付きで提供

search_news は320文字に切り詰めた要約を返します。完全な要約はモデルのコンテキストをすぐに埋めてしまいます。1記事の完全なテキストが必要な場合は get_article を呼び出してください。

ファイル

  • index.js — HTTP(S) ホスト: ルーティング、認証チェック、TLS、ライフサイクル

  • mcp-server.js — MCPサーバー: ツール、リソース、プロンプト

  • db.js — Postgresプールと読み取り専用クエリヘルパー

  • auth.js — ベアラートークン検証

  • inspect-cli.js — 開発用ヘルパー。このサーバーに対してMCP Inspector CLIを実行します

実行

npm install
cp .env.example .env     # then set DATABASE_URL
npm start
# ai-news-mcp listening on http://0.0.0.0:8080/mcp

DATABASE_URL は必須です。欠落している場合、サーバーは指示とともに終了します。Supabaseのトランザクションプーラー文字列(ポート6543)を使用してください: ダッシュボード → Connect → Transaction pooler。

読み取り専用の保証

MCPエンドポイントは認証なしで公開される可能性があるため、「当社のSQLはSELECTのみ」というだけでは十分な保証ではありません。独立した2つのレイヤー:

  1. SQLを受け入れるツールはありません。 5つすべてが固定ステートメントを実行します。呼び出し元の入力は常にバインドパラメータとしてのみ届き、補間される識別子(list_tagstagskey_words)は使用前にZod列挙型で制約されます。

  2. Postgresは書き込みを拒否します。 すべてのクエリは BEGIN READ ONLY 内で SET LOCAL statement_timeoutdb.js)とともに実行されます。セッションレベルの SET ではなく SET LOCAL を使用するのは、トランザクションプーリング下ではセッション設定が次にそのバックエンドを渡されるクライアントに漏れるためです。

ライブデータベースに対して検証済み:

INSERT  blocked: cannot execute INSERT in a read-only transaction
UPDATE  blocked: cannot execute UPDATE in a read-only transaction
DELETE  blocked: cannot execute DELETE in a read-only transaction
DDL     blocked: cannot execute CREATE TABLE in a read-only transaction
SELECT  still works: 1083 rows

多層防御として、DATABASE_URL をオーナーではなく専用の読み取り専用ロールに向けてください:

CREATE ROLE mcp_reader LOGIN PASSWORD '...';
GRANT USAGE ON SCHEMA news TO mcp_reader;
GRANT SELECT ON news.articles TO mcp_reader;

そうすれば、このサーバーのバグがあっても、トランザクションガードが削除された場合でも書き込みはできません。

認証

MCP_AUTH_TOKEN が設定されていない限りオフ。設定してください。 すべてのツールがデータベースを読み取るため、オープンなエンドポイントはURLを見つけた誰にでもコーパスのクエリを許可し、Supabaseのクォータを消費させます。起動バナーはトークンが欠落しているときに警告します。

npm run gen-token          # prints a random 32-byte hex token (64 chars)
MCP_AUTH_TOKEN=<token> npm start

トークンが設定されている場合、リクエストには Authorization: Bearer <token> が必要です。スキームは大文字小文字を区別しませんが、トークンは区別します。欠落または不正な資格情報は 401WWW-Authenticate チャレンジを取得し、定数時間で比較されます(両側をSHA-256でハッシュし、timingSafeEqual を使用)ので、応答のタイミングからトークンを回復することはできません。

32文字未満のトークンは起動警告をトリガーします。データベースを保護するトークンは覚えやすい単語であってはなりません。gen-token を使用してください。

GET /health は資格情報を必要としないため、プラットフォームのヘルスチェックとして機能します。

検証済みの動作:

リクエスト

結果

Authorization ヘッダーなし

401 + WWW-Authenticate: Bearer

誤ったトークン

401 + error="invalid_token"

Bearer プレフィックスなしのトークン

401

正しいトークンの正しいプレフィックス

401

正しいトークン

200

GET /health、資格情報なし

200

設定

環境変数

デフォルト

目的

DATABASE_URL

必須。 Supabase Postgres接続文字列

DIRECT_URL

DATABASE_URL が未設定の場合のフォールバック

MCP_AUTH_TOKEN

未設定 ⇒ 全員にオープン。設定 ⇒ ベアラートークン必須

PORT

8080

リッスンポート

HOST

0.0.0.0

バインドアドレス。ローカルのみの場合は 127.0.0.1 に設定

MCP_PATH

/mcp

エンドポイントパス

PGPOOL_MAX

4

プールサイズ。小さく保つ。プーラーには接続制限がある

PG_STATEMENT_TIMEOUT_MS

8000

クエリごとの上限

PGSSL_STRICT

1 はサーバー証明書を検証(Supabase CAが必要)

TLS_KEY / TLS_CERT

PEMファイルへのパス。両方設定 ⇒ HTTPS

curlで試す

curl -X POST http://127.0.0.1:8080/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_news","arguments":{"query":"Nvidia","limit":3}}}'

トークンを設定した場合は -H "authorization: Bearer $MCP_AUTH_TOKEN" を追加してください。

Inspectorで試す

npm run inspect:cli -- --method tools/list
npm run inspect:cli -- --method tools/call --tool-name news_stats
npm run inspect:cli -- --method tools/call --tool-name search_news --tool-arg query=Anthropic
npm run inspect:cli -- --method resources/read --uri "news://overview"

Web UI(npm run inspect)には、Transport Streamable HTTP とURL http://127.0.0.1:8080/mcp が必要です。トークンを設定した場合は、Authentication → Header Name Authorization、値 Bearer <token> を入力してください。そうしないと、Inspectorは 401 を認識し、OAuthを想定して、このサーバーが実装していないディスカバリーフローを開始します。

エージェントに接続

claude mcp add --transport http ai-news https://ai-news-mcp.onrender.com/mcp

トークンがある場合は、--header "Authorization: Bearer <token>" を追加してください。

ai_news_analyst プロンプトはエージェントの意図されたエントリーポイントです。モデルに、回答する前に検索すること、質問の言語に関係なくフランス語で検索すること、article_url を引用すること、コーパスに何もない場合は一般的な知識に頼るのではなく、その旨を明確に述べることを指示します。

フランス語テキストの検索

検索はPostgresの全文検索を french 設定で使用し、ステミングとストップワードを処理します。このデータベースには unaccent 拡張機能がインストールされていないため、アクセントの折りたたみは行いませんenergieénergie に一致しません。

これを修正するには、Supabase SQLエディタで一度実行し、mcp-server.jsFTS を調整してください:

CREATE EXTENSION IF NOT EXISTS unaccent;

1083行ではすべてのクエリが高速なシーケンシャルスキャンであるため、まだインデックスは不要です。コーパスが約5万行を超える場合は、to_tsvector 式にGINインデックスを追加してください。

デプロイ

現在Renderで稼働中。そのサービスの設定、再デプロイ手順、プラットフォームの癖については DEPLOYMENT.md を参照してください。

ホストの環境設定で DATABASE_URL — 理想的には MCP_AUTH_TOKEN — を設定してください。それらをコミットしないでください。.gitignore.env*.pem をカバーしています。

サーバーは 0.0.0.0 にバインドし、注入された PORT を尊重します。これはコンテナプラットフォームが要求するものです。127.0.0.1 にバインドされたプロセスは、ログが正常に見えても、コンテナの外部からは到達できません。

独自のツールを追加する

mcp-server.js で、読み取り専用ヘルパーを介してクエリをルーティングします:

import { query } from "./db.js";

server.registerTool(
  "my_tool",
  {
    title: "My tool",
    description: "What it does — the model reads this to decide when to call it.",
    inputSchema: { term: z.string() },
  },
  async ({ term }) => {
    const rows = await query("SELECT id, title FROM news.articles WHERE title ILIKE $1", [`%${term}%`]);
    return { content: [{ type: "text", text: JSON.stringify(rows, null, 2) }] };
  }
);

呼び出し元の入力を連結してSQLを構築しないでください。また、SQLを引数として受け取るツールを追加しないでください。それはコーパスの読み取り面をエンドポイントに到達できる人に渡すことになります。

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

0Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A simple implementation of a Model Context Protocol server that demonstrates core functionality including mathematical tools (add, subtract) and personalized greeting resources.
    93
    GPL 3.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    A demonstration implementation of a Model Context Protocol server that provides simple mathematical tools (add, subtract) and personalized greeting resources.
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that provides basic tools for arithmetic operations (addition) and dynamic greeting resources, demonstrating MCP integration patterns for other projects and clients.
    16
    ISC

View all related MCP servers

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/TahiryMSX/ai-news-mcp'

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