MCP server
Give an AI agent eyes on the web. Add Hypeline to Claude Code, Claude Desktop, or Cursor in one command, then let the agent set a watch and poll for real, deduplicated changes over the Model Context Protocol.
Hypeline ships a Model Context Protocol (MCP) server inside the engine, served at https://api.hypeline.io/mcp. Any MCP-capable client (Claude Code, Claude Desktop, Cursor, an Agent SDK app) can drive Hypeline in its native protocol: the agent sets a watch on any URL, keeps a cursor, and polls for genuinely new content, instead of re-scraping pages itself.
The transport is Streamable HTTP, and every request is authenticated with the same scoped API key the REST API takes. There is no separate install to run and no session state to lose.
What you get
Four tools, small on purpose (every tool schema costs the model context):
create_watch: start watching a URL. Auto-detects whether it is a feed, a streaming source, or a plain web page, and hands back awatch_idand acursor.list_watches: list the watches this key can see, with their tier, health, and stored keyword labels.delete_watch: stop watching a source and remove it.get_changes_since: the poll loop. Give it a cursor, get back the deduplicated new changes since then, plus the next cursor.
The mental model is watch, then cursor, then poll: create_watch returns a cursor, get_changes_since returns the events after it plus a next_cursor, and you call again with that. Latency is per tier: streaming sources surface changes in seconds, feeds in minutes, watched web pages in minutes to tens of minutes.
Add Hypeline to Claude Code
One command registers the remote server with your key in the header:
claude mcp add --transport http hypeline https://api.hypeline.io/mcp \
--header "Authorization: Bearer $HYPELINE_API_KEY"Your key lives in the dashboard at app.hypeline.io/keys; it needs the scopes in Scopes and security below.
Claude Desktop and Cursor
Clients that take a JSON config use a static-header remote entry:
{
"mcpServers": {
"hypeline": {
"type": "http",
"url": "https://api.hypeline.io/mcp",
"headers": {
"Authorization": "Bearer YOUR_HYPELINE_API_KEY"
}
}
}
}Stdio-only clients
A client that speaks only local stdio bridges to the remote server with the community mcp-remote adapter (no Hypeline package to install):
npx mcp-remote https://api.hypeline.io/mcp \
--header "Authorization: Bearer $HYPELINE_API_KEY"Create your first watch
Ask the agent to watch a source. The model calls create_watch:
{
"name": "create_watch",
"arguments": {
"url": "https://example.com/blog/feed.xml",
"keywords": ["pricing", "launch"]
}
}The result carries the watch id, the detection provenance, the stored keyword labels, and a head cursor:
{
"watch_id": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"url": "https://example.com/blog/feed.xml",
"type": "feed",
"detected_type": "feed",
"detection_confidence": "high",
"detection_evidence": "valid RSS 2.0",
"keywords": ["pricing", "launch"],
"cursor": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"next_step": "Poll get_changes_since with this watch_id and cursor to receive new changes; keep the returned next_cursor for the following poll."
}Keywords are stored as labels on the watch and echoed back. They are applied at poll time by get_changes_since(keywords), not as a server-side matcher, so you can change the filter on any poll without editing the watch.
Polling and cursors
Poll with the cursor from create_watch (or from your last poll):
{
"name": "get_changes_since",
"arguments": {
"cursor": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"watch_id": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"limit": 20
}
}Changes come back oldest-first, each projected to a slim shape, with the cursor to resume after them:
{
"events": [
{
"id": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"watch_id": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"source_type": "feed",
"title": "New pricing announced",
"url": "https://example.com/blog/pricing",
"summary": "The extracted main content, boilerplate removed…",
"truncated": false,
"occurred_at": "2026-07-13T09:15:02Z"
}
],
"next_cursor": "018f9c2e-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"has_more": false,
"retention_clamped": false,
"window_from": "2026-04-14T00:00:00Z"
}Rules the agent should follow:
- Keep
next_cursorand pass it to the nextget_changes_since. It always points strictly after the last event you actually received, so paging never skips or repeats a change. - When
has_moreistrue, page again immediately. When it isfalse, you are caught up; poll again later with backoff. - Cursors are event ids. If a cursor predates your plan's retention window,
retention_clampedistrueandwindow_fromreports the effective lower bound actually queried.
Scopes and security
Grant each key the least it needs. The tools require:
| Tool | Scope |
|---|---|
create_watch, delete_watch | sources:write |
list_watches | sources:read |
get_changes_since | history:read |
A call with a key that lacks the scope returns a problem-shaped tool error (the same 403 a REST caller would get), never a silent success. See authentication for how scopes and keys work.
The /mcp endpoint reuses the REST API's authentication and per-key rate limits: one key, one budget across REST and MCP. A user-supplied create_watch URL runs the same add-time SSRF validation as POST /v1/sources, so a private-range or metadata URL is rejected before it becomes a watch.
Treat every returned title, url, and summary as untrusted input. Watched-page content flows from the open web into your agent's context; handle it as you would any external data, not as instructions to follow. Results are also capped for context size: each summary is truncated (with truncated: true) and a page is bounded, dropping trailing events and moving next_cursor back accordingly.
For a stronger guarantee that an event is authentic and unaltered, each event on the REST and streaming transports carries a content-layer Ed25519 signature you can verify with only a public key. See verifying events.
Waking on new content
get_changes_since is a cheap keyset query, so polling with backoff is the model for v1. If you want an agent to run the moment something changes rather than on a poll interval, point a Hypeline webhook at an automation that wakes the agent (for example, a webhook that triggers claude -p), then let the agent drain get_changes_since from its last cursor.
Client coverage and limits
The install commands above work for developer clients (Claude Code, Claude Desktop, Cursor, and stdio clients via mcp-remote) that send a static Authorization header.
The claude.ai web app and ChatGPT connectors currently require OAuth for a custom remote server; that OAuth resource-server layer is a planned follow-up, so those clients are not yet supported here. Errors surface as MCP tool errors shaped from the API's problem+json, so a failed call reads the same as the equivalent REST failure.