Repository navigation
Add real-time WebSocket tools - #6
Merged
Merged
Conversation
Sync with python-client 0.3.0. Adds four tools: register_realtime_query, list_realtime_queries, delete_realtime_query, and stream_news. MCP tools are request/response, so stream_news is deliberately bounded — it collects until max_articles arrive or wait_seconds elapses, whichever comes first, and always returns within wait_seconds. Every reply states stopped_because (max_articles | timeout | connection_closed) so the model can tell a hit cap from a quiet feed. Call it again to keep listening. register and delete are annotated as mutating (the latter destructive) since they create and remove server-side state; the rest stay read-only. fetch() now carries an HTTP method. registration_id is constrained to the spec's 32 characters, and the stream_news docstring warns that each delivered article costs 1 API credit per connected device, with at most 5 devices per registration.
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.
Syncs this client with python-client 0.3.0 (PR #27), which added the real-time WebSocket service.
What's here
Query management — three REST endpoints, verified against the OpenAPI 3.1 spec:
websocket/registerPOST(query params, no body)websocket/fetchGETwebsocket/deleteDELETERegister once, stream many times. A registered query has no date or paging filters — it matches news as it is published. Registering identical filters twice answers
409with the existingregistration_id.Failure model
Per the spec, the handshake is always accepted; a refused connection is then closed with code 1008 carrying one of three reasons —
invalid credentials or registration not found,api limit reached, ordevice limit reached(>5 devices on oneregistration_id). Those raise the new typed auth error and are never retried. Every other close code, including1013(send timeout), is transient.MCP specifics — why
stream_newsis boundedMCP tools are request/response, so an open-ended stream cannot be a tool.
stream_newscollects until eithermax_articlesarrive orwait_secondselapses, whichever comes first, and always returns withinwait_seconds. Every reply states why it stopped:stopped_becausemax_articlestimeout0means the feed was quietconnection_closedA test caught the tool reporting
timeoutwhen the server had actually closed the feed — which would tell the model "nothing arrived" when the truth was "the feed ended". Fixed.Tool annotations
register_realtime_queryis annotated as creating,delete_realtime_queryas destructive; the rest stay read-only. Previously every tool shared one read-only constant.Cost guidance
registration_idis constrained to the spec's 32 characters so the model cannot invent one, and thestream_newsdocstring warns that each delivered article costs 1 API credit per connected device (max 5 devices per registration) — an LLM left to itself would happily burn credits on a broad query.Also regenerated
uv.lockfor the newwebsocketsdep; CI runsuv sync --frozenand would have failed without it.184 tests pass, ruff clean.