feat: add news search to CLI and MCP#94
Merged
Microck merged 5 commits intoMicrock:mainfrom May 2, 2026
Merged
Conversation
Surfaces the existing `kagi news` command via the MCP server. The tool needs no auth (mirrors `kagi news`) and accepts `category` (default `world`), `limit` (default `12`), and `lang` (default `default`).
`NewsStoriesPayload` and `NewsStoriesResponse` declared `total_stories` as `String`, but the live Kagi News API always returns it as an integer, so every live `kagi news` invocation failed with a parse error. The existing integration fixture hardcoded the field as a JSON string, which masked the bug in CI. Switch the type to `u64`, update the fixture, and correct the documented JSON shape. The output JSON now emits an integer for `total_stories` instead of the never-actually-delivered string form.
Adds a News-tab vertical to `kagi search`. With `--news`, the CLI hits
`kagi.com/news?q=...` (session auth) and returns articles grouped into
story clusters via a new `NewsSearchResponse` JSON shape. The flag
forces session-only auth and rejects incompatible options (--lens,
--snap, --from-date/--to-date, --verbatim, --personalized,
--no-personalized, --follow, --template, --time year, --order trackers).
A new HTML parser walks the `.newsResultGroup`/`.newsResultItem`
markup, preserves Kagi's relative time strings verbatim ("2 hours
ago"), and exposes the per-cluster grouping in the response.
Also exposes the same vertical via a new `kagi_news_search` MCP tool
that accepts `query`, optional `region`, `freshness` (day/week/month),
`order` (default/recency/website), and `limit`.
Replying to notifications (messages without an `id`) violates JSON-RPC 2.0 and caused Claude's MCP client to reject the connection with a Zod validation error on `notifications/initialized`. Skip notifications and return proper `error` objects for unsupported methods instead of embedding errors in `result`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kagi searchgains a--newsflag that hits Kagi's News tab and returns articles grouped into story clusters. The MCP server gets two corresponding tools:kagi_news(the existingkagi newsheadlines product) andkagi_news_search(the new vertical). Also fixes a pre-existing bug wherekagi newscould not parse live responses becausetotal_storieswas typed as a string but the API always returns an integer, and another bug with MCP notification handling.Why
I originally just wanted to add an MCP tool for searching for news stories. I first added an MCP tool for the
kagi newscommand and the bug was discovered during smoke testing. I then realizedkagi newswas fornews.kagi.comrather than for the "News" tab in a search result, so I decided to add a flag tokagi searchfor grabbing those news stories.Things to look out for
--newsflag, two new MCP tools, newNewsSearchResponseJSON shape. The--newspath forces session auth and rejects incompatible flags (--lens,--snap, date filters,--verbatim,--personalized,--follow,--template,--time year,--order trackers).kagi news:total_storiesshifts from"20"to20in the JSON output. Documented as Fixed in CHANGELOG. The live command never actually. returned data with the string form (parsing always failed), so no consumer can have depended on the string shape.Screenshots
Test plan
make check— fmt + clippy + 202 tests (8 new news-related).kagi search "iran" --news --format jsonreturns the documentedNewsSearchResponseshape.kagi search "iran" --news --lens 1exits non-zero with a clear error.kagi news --category techsucceeds and emits"total_stories": <integer>(regression check for the fix).echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | kagi mcp | jqlists bothkagi_newsandkagi_news_search.