Skip to main content
Glama
TahiryMSX

basic-mcp-server

by TahiryMSX

ai-news-mcp

Un servidor de Model Context Protocol que responde preguntas sobre un corpus de noticias de IA, servido a través de Streamable HTTP.

Es el backend de datos para un agente de noticias de IA: el agente hace preguntas, estas herramientas buscan y leen news.articles en Supabase Postgres.

Cada herramienta es de solo lectura. Ver Garantía de solo lectura.

Sin estado: cada solicitud obtiene su propia instancia del servidor MCP, no se guarda nada entre solicitudes, por lo que no hay IDs de sesión ni enrutamiento fijo. El pool de la base de datos es compartido.

El corpus

news.articles, en un Supabase Postgres. A fecha de 2026-08-24:

Artículos

1083

Rango de fechas

2026-04-01 → 2026-08-24

Idioma

Francés

Categorías distintas

668

Etiquetas distintas

927

Dos propiedades guían el diseño de las herramientas:

  • Las categorías son texto libre y fragmentado — 668 valores distintos en 1083 artículos, con casi duplicados como Cybersécurité, Cybersécurité des agents IA y Cybersécurité et agents IA. La coincidencia exacta de categorías es casi inútil, por lo que search_news coincide con las categorías como una subcadena que no distingue mayúsculas.

  • views es NULL en cada fila. Deliberadamente no hay una herramienta de "más leído"; devolvería ruido.

Related MCP server: MCP Server Basic Example

Lo que expone

Tipo

Nombre

Descripción

Herramienta

search_news

Búsqueda por texto libre, categoría, etiquetas y rango de fechas; paginada

Herramienta

get_article

Un artículo completo, por id o article_url

Herramienta

list_categories

Categorías distintas con recuentos, para descubrimiento

Herramienta

list_tags

tags o key_words distintos con recuentos

Herramienta

news_stats

Cobertura: totales, rango de fechas, volumen por mes, temas principales

Recurso

news://overview

Tamaño del corpus, rango de fechas y etiquetas principales como JSON

Prompt

ai_news_analyst

Fundamenta una respuesta en el corpus, con citas

search_news devuelve resúmenes truncados a 320 caracteres — los resúmenes completos llenan el contexto de un modelo rápidamente. Llama a get_article para el texto completo de un artículo.

Archivos

  • index.js — Host HTTP(S): enrutamiento, verificación de autenticación, TLS, ciclo de vida

  • mcp-server.js — El servidor MCP: herramientas, recurso, prompt

  • db.js — Pool de Postgres y el helper de consulta de solo lectura

  • auth.js — Verificación de token bearer

  • inspect-cli.js — Helper de desarrollo; ejecuta la CLI del Inspector MCP contra este servidor

Ejecutar

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 es obligatorio — el servidor sale con instrucciones si falta. Usa la cadena del transaction pooler de Supabase (puerto 6543): panel → Conectar → Transaction pooler.

Garantía de solo lectura

El endpoint MCP puede estar expuesto sin autenticación, por lo que "nuestro SQL solo hace SELECTs" no es una garantía suficientemente fuerte. Dos capas independientes:

  1. Ninguna herramienta acepta SQL. Las cinco ejecutan sentencias fijas; la entrada del llamador solo llega como parámetros vinculados, y el único identificador interpolado (tags vs key_words en list_tags) está restringido por un enum de Zod antes de usarse.

  2. Postgres rechaza escrituras. Cada consulta se ejecuta dentro de BEGIN READ ONLY con un SET LOCAL statement_timeout (db.js). SET LOCAL en lugar de un SET a nivel de sesión porque bajo transaction pooling un ajuste de sesión se filtraría al cliente que reciba ese backend a continuación.

Verificado contra la base de datos en vivo:

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

Para defensa en profundidad, apunta DATABASE_URL a un rol de solo lectura dedicado en lugar de al propietario:

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

Entonces un error en este servidor no puede escribir incluso si se eliminara la protección de transacción.

Autenticación

Desactivada a menos que se establezca MCP_AUTH_TOKEN. Establécelo. Cada herramienta lee tu base de datos, por lo que un endpoint abierto permite que cualquiera que encuentre la URL consulte el corpus y queme tu cuota de Supabase. El banner de inicio advierte cuando falta el token.

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

Con un token establecido, las solicitudes necesitan Authorization: Bearer <token>. El esquema es insensible a mayúsculas; el token no lo es. Las credenciales faltantes o incorrectas reciben 401 y un desafío WWW-Authenticate, comparado en tiempo constante (ambos lados con SHA-256, luego timingSafeEqual) para que el token no pueda recuperarse midiendo los tiempos de respuesta.

Los tokens de menos de 32 caracteres activan una advertencia de inicio — un token que protege una base de datos no debería ser una palabra memorable. Usa gen-token.

GET /health nunca requiere una credencial, por lo que funciona como verificación de salud de la plataforma.

Comportamiento verificado:

Solicitud

Resultado

Sin cabecera Authorization

401 + WWW-Authenticate: Bearer

Token incorrecto

401 + error="invalid_token"

Token sin el prefijo Bearer

401

Prefijo correcto del token real

401

Token correcto

200

GET /health, sin credencial

200

Configuración

Variable de entorno

Predeterminado

Propósito

DATABASE_URL

Obligatorio. Cadena de conexión de Supabase Postgres

DIRECT_URL

Respaldo si DATABASE_URL no está establecido

MCP_AUTH_TOKEN

Sin establecer ⇒ abierto a todos; establecido ⇒ se requiere token bearer

PORT

8080

Puerto de escucha

HOST

0.0.0.0

Dirección de enlace. Establece 127.0.0.1 para solo local

MCP_PATH

/mcp

Ruta del endpoint

PGPOOL_MAX

4

Tamaño del pool; mantenlo pequeño, los poolers tienen límites de conexiones

PG_STATEMENT_TIMEOUT_MS

8000

Límite por consulta

PGSSL_STRICT

1 verifica el certificado del servidor (necesita la CA de Supabase)

TLS_KEY / TLS_CERT

Rutas a archivos PEM; ambos establecidos ⇒ HTTPS

Pruébalo con 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}}}'

Añade -H "authorization: Bearer $MCP_AUTH_TOKEN" si estableciste un token.

Pruébalo en el 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"

La interfaz web (npm run inspect) necesita Transport Streamable HTTP y URL http://127.0.0.1:8080/mcp. Si estableciste un token, completa Authentication → Header Name Authorization, valor Bearer <token> — de lo contrario el Inspector ve el 401, asume OAuth, y comienza un flujo de descubrimiento que este servidor no implementa.

Conéctalo a un agente

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

Con un token, añade --header "Authorization: Bearer <token>".

El prompt ai_news_analyst es el punto de entrada previsto para un agente: le dice al modelo que busque antes de responder, que busque en francés independientemente del idioma de la pregunta, que cite article_url, y que diga claramente cuando el corpus no tiene nada en lugar de recurrir al conocimiento general.

Buscar texto en francés

La búsqueda usa la búsqueda de texto completo de Postgres con la configuración french, que maneja derivación y palabras vacías. No pliega acentos, porque la extensión unaccent no está instalada en esta base de datos — energie no coincidirá con énergie.

Para arreglarlo, ejecuta una vez en el editor SQL de Supabase y ajusta FTS en mcp-server.js:

CREATE EXTENSION IF NOT EXISTS unaccent;

Con 1083 filas, cada consulta es un escaneo secuencial rápido, por lo que aún no se necesita índice. Si el corpus crece más allá de ~50k filas, añade un índice GIN en la expresión to_tsvector.

Despliegue

Actualmente en vivo en Render. Consulta DEPLOYMENT.md para la configuración de ese servicio, pasos de redespliegue y peculiaridades de la plataforma.

Establece DATABASE_URL — e idealmente MCP_AUTH_TOKEN — en la configuración de entorno del host. Nunca los confirmes; .gitignore cubre .env y *.pem.

El servidor se enlaza a 0.0.0.0 y respeta un PORT inyectado, que es lo que requieren las plataformas de contenedores. Un proceso enlazado a 127.0.0.1 es inalcanzable desde fuera de su contenedor aunque sus registros parezcan saludables.

Añadir tu propia herramienta

En mcp-server.js, y enruta la consulta a través del helper de solo lectura:

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) }] };
  }
);

Nunca construyas SQL concatenando entrada del llamador, y nunca añadas una herramienta que acepte SQL como argumento — eso entregaría la superficie de lectura del corpus a cualquiera que pueda alcanzar el endpoint.

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