gqai-editorial-mcp-server
Provides read-only access to the editorial (사설) table in a Supabase project, enabling keyword and date-range search, retrieval of full editorial text by id or link, and listing of media outlets with editorial counts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gqai-editorial-mcp-serverFind editorials mentioning "semiconductors" from Chosun Ilbo in the last month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
gqai-editorial-mcp-server
Remote MCP server exposing read-only access to the editorial (사설) table
in the GQAI Supabase project (20250320-exnews-supabase, 23k+ Korean newspaper
editorials from 35 outlets).
Live deployment
Endpoint:
https://gqai-editorial-mcp.vercel.app/api/mcpHosted on Vercel; every push to
maindeploys automatically.
Related MCP server: law-search-mcp
Quick install
No auth needed — just point your client at the live endpoint.
Claude Code:
claude mcp add --transport http editorial https://gqai-editorial-mcp.vercel.app/api/mcpClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"editorial": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://gqai-editorial-mcp.vercel.app/api/mcp"]
}
}
}Any other Streamable HTTP-capable client: add
https://gqai-editorial-mcp.vercel.app/api/mcp as the server URL — see
Connecting a client below for the raw config format.
Tools
Every tool takes response_format: markdown (default) or json.
search_editorials
Find editorials by keyword, outlet, and date range. Returns summaries, not full
text — use get_editorial for the body.
Input | Description |
| Keyword (2–200 chars), matched against title and body |
|
|
| Exact outlet name, e.g. |
|
|
| Page size 1–100 (default 20) and offset |
Each result has id, title, media, published_at, link, a 220-character
snippet, and — when there is a query — matched_in (title or body). The
response also carries total, has_more, and next_offset.
How matching works:
Ranking. With a
query, editorials whose title matches come first, then those matching only in the body; each group is newest first. Without aquery(or withtitle_only), everything is newest first.Case-insensitive substring match, except that an English edge of the keyword never matches inside a longer English word:
AImatchesAI가,(AI), andAI속도조절, but notsaidorStrait;inflationdoes not matchinflationary. Korean keywords are plain substring matches.%,_, and regex characters in the keyword are matched literally.
get_editorial
Full text of one editorial by id or link (id wins if both are given), with
title, outlet, date, and link. Bodies over 25,000 characters are truncated and
flagged truncated: true.
list_media_outlets
Every outlet name with its editorial count, plus the total.
Why it's safe to expose openly
No auth gate on the MCP endpoint itself — anyone with the URL can call it.
That's fine here because the
editorialtable's only RLS policy (editorial_public_select) grantsSELECTtoanon/authenticated— the app can never write, and it exposes nothing that isn't already readable with the public anon key.The
editorial_dedupedview the app searches issecurity_invoker, so it is read under that same policy, and anon writes through it are rejected.
Local development
npm install
cp .env.example .env.local # fill in SUPABASE_ANON_KEY
npm run devThe MCP endpoint is http://localhost:3000/api/mcp (Streamable HTTP,
JSON-RPC 2.0). Test it with:
curl -X POST http://localhost:3000/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Deploying to Vercel
vercel link
vercel env add SUPABASE_URL
vercel env add SUPABASE_ANON_KEY
vercel deploy --prodConnecting a client
Any MCP client that supports Streamable HTTP — no auth needed:
{
"mcpServers": {
"editorial": {
"url": "https://gqai-editorial-mcp.vercel.app/api/mcp"
}
}
}For stdio-only clients, bridge with
mcp-remote:
{
"mcpServers": {
"editorial": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://gqai-editorial-mcp.vercel.app/api/mcp"]
}
}
}Data coverage
Snapshot taken 2026-09-26 from editorial_deduped (the rows the tools
search). Re-run db/coverage.sql to refresh these numbers.
All dates are KST.
Range: 2025-05-01 → 2026-09-24, 23,186 editorials.
published_atis never null.Last insert: 2026-09-24 06:00. Nothing arrived through the snapshot, which falls in the Chuseok holiday (2026-09-24 – 09-26); past holidays show the same kind of gap. If it outlasts the holiday, check the collector.
Collector schedule: rows land at 00:00, 03:00, 06:00, 12:00, and 18:00 (insert times over the last 14 days).
Volume: about 60 editorials per weekday.
Outlets that start later than May 2025: 강원일보 and 강원도민일보 (2025-05-07), 한경비즈니스 (2025-09-15, 7 total), 머니투데이 (2026-03-05), 동행미디어 시대 (2026-03-31), 아시아경제 (2026-06-17), 전자신문 (2026-06-24), kbc광주방송 (one editorial, 2026-07-15). Date-range comparisons across outlets before these dates aren't like-for-like.
Sparse outlets: 주간조선 (43), 미디어오늘 (44), 전자신문 (12), 한경비즈니스 (7) — a few dozen or fewer over the whole range, so don't expect them in any given week.
Days with no editorials (54 in all):
Saturdays up to 2026-02-07 (38 of them): Saturday was routinely empty until then, so treat those as normal. Since then only 2026-04-11 is empty, next to the 04-10 gap below.
Public holidays: 2025-06-06, 2025-08-15, 2025-10-03 – 10-08 (Chuseok), 2026-02-16 – 02-17 (Seollal; 02-16 has 1 editorial).
A few Sundays: 2025-05-04, 2025-12-28, 2026-02-08, 2026-02-15.
Unexplained weekday gaps: 2025-09-26 (Fri), 2026-01-30 (Fri), and 2026-04-10 (Fri). Treat these as possible collection misses.
Notes on the underlying data
Search and outlet counts read the
editorial_dedupedview, which hides Korea JoongAng Daily English-only rows whose"<title> (KOR)"twin exists (the twin carries the same English text plus a Korean translation).get_editorialstill reads the table, so a hidden row'sidorlinkresolves. The view is defined indb/editorial_deduped_view.sql.title/contenthavepg_trgmGIN indexes (editorial_title_trgm_idx,editorial_content_trgm_idx) added specifically to makeILIKEsearch fast enough to stay under Postgres' statement timeout — without them,search_editorialstimes out on the 23k-row table. Keywords with an English edge are matched with a case-insensitive regex (~*) instead ofILIKE; a full-body regex scan takes roughly 0.6s.published_atis used as the canonical date for filtering/sorting (falls back topubdatefor display if null, though in practice both are always populated).
This server cannot be deployed
Maintenance
Related MCP Connectors
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Your Supabase account in natural language: run SQL, apply migrations, manage tables, storage, edge f
Read-only search of your Sortio knowledge graph (files and entities) for Claude and ChatGPT.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to perform CRUD operations on Supabase databases through natural language. Supports advanced filtering, pagination, and safety checks for seamless database interaction.MIT
- FlicenseAqualityDmaintenanceEnables searching and retrieving Korean Supreme Court precedents from the law.go.kr Open API, with support for keyword search and detailed judgment text.2-
- AlicenseCqualityCmaintenanceEnables search and retrieval of speech turns from Korea's National Assembly records using Korean or English natural-language queries, with citation-ready context and tools for exploring committees and meetings.51Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables read-only search and retrieval of press releases from 12 South Korean government agencies, returning metadata like title, agency, publication date, and original URL.3-