
Octen Mcp
io.github.Octen-TeamPublished by GitHub account Octen-Teamv0.1.5Updated Oct 24, 2026
URL to LLM-ready markdown — plus per-page category, page_structure, and query-driven highlights.
Overview
Octen MCP gives an assistant live web search, news search, multi-angle research search, and clean markdown extraction of web pages.
- What you can do
- Search the live web with domain, text, language, time and content filters
- Search news specifically, or run broad multi-sub-query research searches
- Fetch up to 20 URLs and return clean markdown or text, with categories, page structure and query-driven highlights
- Search images and videos (beta tools, hidden if disabled)
- When to use it
- Useful when an assistant needs current web information, multi-source research, or readable page content for summarization, RAG or fact lookup. It is a focused six-tool surface, so it suits clients that want search and extraction without a large tool list.
- Requirements
- Either the hosted remote endpoint (OAuth sign-in or an API key) or the local npm package run with npx, which needs Node.js 18.17 or later. A key comes from the provider's site, passed as OCTEN_API_KEY locally or as a header or URL parameter for the hosted endpoint. Network access to the provider's API; proxy variables must be set explicitly in the client config.
Installation
In SourceWeft
- Open Octen Mcp in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
octen-mcp
[npm version] [npm downloads] [License: MIT] [CI]
MCP server for Octen. Plug it into Claude, Cursor, VS Code, Windsurf, or any MCP client to give your agent live web search and URL extraction.
Core capabilities:
search: search the live web with domain, text, language, and time filters.news_search: recent news, returned both as articles and as storylines — the coverage grouped into subjects, each with a summary and the span it covers.pulse_search: the URL a query most likely means, in about 10ms — official docs, help centres, a site you could almost name. No freshness, no filters.place_search: real-world places as structured cards — address, coordinates, phone, opening hours, rating — around a point you give it, or in an area the query names.business_search: a company or person, returned as a structured card — profile, financials, key people, career history, recent announcements — alongside the sources behind it.broad_search: decompose a query into multiple sub-queries, search them concurrently, and return results grouped per sub-query for broad coverage.extract: turn one or more URLs into clean, LLM-ready content.image_search: search the web for images by text query, by a reference image URL, or by base64 image data — exactly one of the three.video_search(In Beta — contact us for beta access): search the web for videos by text query.
What makes Octen useful for agents is that extract returns more than page text. Each successful result also includes:
category: what the page is aboutpage_structure: what kind of page it ishighlights: ranked snippets when you pass aquery
That lets an agent skip login walls, nav pages, and off-topic URLs before spending tokens on the full body.
Why Octen MCP
Fast
Web search averages 62ms. Fast enough for multi-step MCP workflows.
Accurate
Powered by SOTA text and VL embedding models. Better sources, fewer hallucinations.
Fresh
Live web data with minute-level updates. Useful for news, prices, and fast-moving pages.
Efficient
Clean highlights, optional full_content, and page labels keep model context relevant.
Quick start
You need an OCTEN_API_KEY from octen.ai — or nothing at
all, if your client signs in over OAuth (see Signing in instead).
Two ways to connect. Both serve the same six tools.
Node compatibility (local only): 0.4.2 and later run on every supported Node (>= 18.17), including Node 26+. Versions 0.4.1 and below fail every call on hosts whose embedded undici is v8+ (Node 26 and later) with
Network error … code=UND_ERR_INVALID_ARG cause=invalid onError method— if you see that error, upgrade the package (or run on Node <= 24).
Connect to the hosted endpoint
Passing your key
Three ways, tried in this order. Prefer a header — a key in a URL is
exposed to proxy logs, browser history and Referer headers.
Or use OAuth and paste no key at all — see Signing in instead.
By client
Claude Code — install the plugin. It brings the hosted server together with
two skills, octen-web-search (routes a request to the right tool) and
octen-research (multi-source research pipeline):
Or from inside a session: /plugin marketplace add Octen-Team/octen-mcp, then
/plugin install octen@octen.
The plugin carries no credential. The first call is answered 401 and Claude
Code walks you through the OAuth sign-in — run /mcp if you want to start it
yourself. To register the server on its own instead, with a key:
Cursor — clone this repository into Cursor's local plugin directory to get the hosted server and both skills in one step:
A Cursor Marketplace listing is pending review; this section will point at it
once it is live. To wire up only the server, add it to ~/.cursor/mcp.json:
VS Code — .vscode/mcp.json (workspace) or the user config. Note servers,
not mcpServers, and the explicit type:
Codex
Windsurf / Devin Desktop — ~/.config/devin/mcp_config.json on macOS and
Linux ($XDG_CONFIG_HOME/devin/ when that is set), %APPDATA%\devin\mcp_config.json
on Windows. Cascade accepts either serverUrl or url for a remote server;
~/.codeium/windsurf/mcp_config.json is the path for the legacy agent:
Gemini CLI — ~/.gemini/settings.json. The key is httpUrl:
Claude Desktop takes the URL directly — no config file, no bridge. In
Settings → Connectors, click Add custom connector, name it Octen, and
enter:
Leave the Advanced settings empty: the OAuth Client ID and Secret fields are for servers that cannot register a client on their own, and ours can. Claude will offer to sign you in, and an Octen key is issued to that connection when you approve.
The connector dialog has no field for request headers, so an API key goes in the URL instead:
Signing in is the better of the two — a URL is not a secret-carrying medium, and the sign-in flow can be revoked from your account without editing anything on this side. Note also that Claude connects from Anthropic's servers rather than from your machine, so a self-hosted deployment has to be reachable from the public internet for this to work at all; a private one wants the bridge below.
Zed, Warp, Raycast, and Cline all connect to a remote server directly — point them at the endpoint and sign in. Raycast's HTTP transport offers an OAuth type of Dynamic, which is the one to pick: this server supports dynamic client registration, so there is no client ID to arrange.
A client with no field for headers takes the key in the URL instead:
https://mcp.octen.ai/mcp?octenApiKey=your-key-here.
Only for a client that still cannot reach a remote server at all, the
mcp-remote bridge runs locally and forwards each request. Note there is no
space after the colon in --header — the value is split on the first one:
Signing in instead
If the deployment is configured with an authorization server — the hosted one
is — a request with no credential is answered 401 +
WWW-Authenticate: Bearer resource_metadata="…". That is the signal MCP
clients use to start an OAuth flow, so a client that supports OAuth will offer
to sign you in rather than ask for a key.
To move a connection that already has a key onto OAuth, point it at
https://mcp.octen.ai/mcp/oauth (or append ?login). That path issues the
challenge even when a key is present, which is the only way to trigger the
switch — with a key attached, the ordinary endpoint has no reason to.
Loading fewer tools
?tools=search,extract limits a connection to the tools you name, for both
tools/list and tools/call:
Clients load every advertised tool's full schema into the model's context, so
narrowing the set is a real saving when you only need one or two. An unknown
name is refused with a 400 listing the valid ones, rather than a connection
that quietly comes up short.
Run it locally instead
[Install in VS Code] [Install in VS Code Insiders]
Config file locations
- Claude Desktop:
~/Library/Application\ Support/Claude/claude_desktop_config.json— only needed for a local (stdio) install; the hosted endpoint is added as a connector instead - Cursor:
~/.cursor/mcp.json - VS Code workspace:
.vscode/mcp.json(useserversinstead ofmcpServers) - Windsurf:
~/.codeium/windsurf/mcp_config.json - Gemini CLI:
~/.gemini/settings.json - Cline / other clients: paste it into that client's MCP settings
Troubleshooting
401 on every call. No credential reached the server, or the sign-in was
never completed. On a client that signs in, authorise the connection from its
MCP settings. On one that passes a key, check the header name — x-api-key, or
Authorization: Bearer — and, if you are using mcp-remote, that there is no
space after the colon in --header.
The tools do not appear. Most clients read MCP config once at startup;
restart the client after editing it. If the config uses the wrong key for your
client (url vs serverUrl vs httpUrl), the server is never contacted at
all — see the per-client sections above.
406 Not Acceptable. The request's Accept header must list both
application/json and text/event-stream. Clients do this for you; hand-rolled
curl probes usually do not, and the resulting 406 looks like an auth failure.
400 mentioning tools. A name in ?tools= is not one this deployment
serves. The error lists the ones that are.
A tool errors with code=403 … beta access. video_search is in Beta and enabled per account; the message says how to
request it.
Errors name what happened. A failed call reports which dependency failed
and why — a timeout, a connection code, an expired token and by how long — plus
Octen's own request_id where the API returned one. Quote that id in a support
request; it is the one an engineer can look up.
Tools
These nine are the whole surface, on purpose. Embeddings, chat completions, Answer and Research are Octen APIs that this server deliberately does not expose — reach them through the Python SDK or the CLI. A tool an agent can see is a tool it will try, so the roster stays the set that earns its place in a tool list.
Reference docs:
- Search: docs.octen.ai/api-reference/search
- Extract: docs.octen.ai/api-reference/extract
Parameters
Transcribed from the schemas each tool publishes — and those are enforced, so an out-of-contract value is refused before any call is made, with a message naming the field. The limits track the API reference; a test fails if the two drift apart.
image_search takes exactly one of query, image_url or image_data.
query must be non-empty: an empty string is refused by the schema, and a
whitespace-only one by the handler. Neither reaches the API.
timeout means two different things. On search, news_search,
broad_search, image_search and video_search it is this server's own HTTP
deadline for the call — it is removed from the request body and never sent to
the API. On extract it is the API's documented per-URL fetch budget
(1-60s) and does travel in the body; the local deadline for an extract call is
derived from it with headroom, so raising timeout raises both.
Overlapping include_domains and exclude_domains are passed through as
given. The API currently answers a domain listed in both with a validation
error; the published
reference describes exclusion
taking precedence. Until those agree, this server neither silently drops nor
reorders your filters — you get the API's answer.
search
news_search
/news-search is its own endpoint, so this is a different parameter set from
search: no include_text/exclude_text, format, safesearch or
include_images, and subjects on top. Omit subjects to take the API's
default (on, 2 storylines, 5 supporting articles each).
business_search
The domain, time and language filters narrow the ranked results only — never
the entity cards. Omit entities to take the API's default (on, 2 entities,
5 activities and 5 news items each).
place_search
web_search holds the filters the other search tools take top-level:
enable (default false), count 1–100, highlight, full_content,
include_domains, exclude_domains, language, time_basis, time_range,
start_time, end_time.
The places are the answer here and the pages cost context, which is why
web_search is off unless asked for. Pass a coordinate pair to get a
distance on every card; user_location is the fallback when only the city
is known, and returns no distances.
pulse_search
A destination predictor, not a search: one inference produces the URLs a query
most likely means. It takes none of search's domain, text, time or language
filters, sees no fresh content, and caps count at 10 rather than 100.
In lite the API returns URLs without a scheme; this server puts https://
back so the result can be passed straight to extract. standard adds
highlights, full content and images at roughly twice the latency.
broad_search
extract
Choosing mode:
standard can report success with empty or skeletal content on hard sites;
retry just those URLs with advanced. advanced is slower and 2.5x the price
of standard; auto bills each URL at the mode it used. With advanced or
auto, raise timeout (e.g. 60). Each result shows its resolved_mode, and
the meta line's billed: counts come from meta.usage.successful_by_mode,
which is authoritative for billing.
image_search
video_search
Keep the tools always on (optional)
In clients with MCP tool search enabled (the Claude Code default), tools are
deferred — the model runs a ToolSearch step to load them on demand. If you'd
rather have the Octen tools resident from the first turn (no discovery step), set
alwaysLoad on the server in your .mcp.json (Claude Code v2.1.121+):
Each always-loaded tool uses context on every turn, and alwaysLoad blocks startup
until the server connects (capped at the ~5s connect timeout), so reserve it for tools
you hit constantly. To keep the cost down, mark just the highest-traffic tools — e.g.
search and broad_search — with "anthropic/alwaysLoad": true in each tool's _meta,
leaving the rest deferred.
Why agents like this
Most extract tools stop at "here is the page body." Octen helps one step earlier:
- Skip bad pages early:
page_structure.primary == "No Main Content"tells the agent it hit a login wall, empty shell, or similar non-content page. - Filter by topic early:
categoryhelps a pipeline ignore pages outside the target vertical before embedding or summarizing. - Use less context:
queryreturnshighlightswhen the user wants a specific fact instead of the full page.
For the full decision tree and integration patterns, see docs/best-practices.md.
Example prompts
Fetch octen.ai and summarize the main product features.Search for recent MCP news from the last week.Fetch these URLs and only summarize the ones whose category is Finance.Search site:docs.anthropic.com prompt caching and return only the relevant highlights.
Self-hosting the HTTP server
The hosted endpoint above runs this same code; you can run it yourself instead:
Endpoints: POST /mcp (stateless Streamable HTTP) and GET /healthz. Stateless
by design — there is no session to lose, so scaling is a matter of running more
copies behind a load balancer. Credentials travel per request and never come
from the server's own environment: a request without one fails rather than
quietly spending the host's key.
Authorization is off unless you configure it. Set both
OCTEN_OAUTH_AUTHORIZATION_SERVER and OCTEN_MCP_RESOURCE and the server
advertises RFC 9728 protected-resource metadata and answers uncredentialed
requests with a 401 challenge. Leave them unset and it advertises nothing —
an instance should never point clients at an authorization server it does not
have — and a missing key surfaces at call time instead.
Argument validation. Each tool's declared inputSchema is enforced, not
just advertised: types, ranges, string lengths, array sizes, enums, required
parameters, and the property list itself. An out-of-contract call is refused
with a message naming the field, before anything is sent to the API.
Sending an image as base64. image_search accepts image_data up to 5MB
encoded, which travels inside the JSON-RPC body. OCTEN_MCP_MAX_BODY defaults
to 6 MiB to make that work unconfigured; OCTEN_MCP_MAX_INFLIGHT_BODY (24 MiB)
separately bounds what all in-flight bodies hold at once, since a per-request
cap does nothing about many concurrent ones.
Environment variables
Remote HTTP form only
These are read only by octen-mcp-http; the stdio entry ignores them.
OAuth. Off unless both of the first two are set, so an instance never advertises an authorization server it does not have.
Setting these in Claude Desktop (and where the logs go)
MCP servers do not inherit your shell environment. Claude Desktop spawns them
with HOME, LOGNAME, PATH, SHELL and USER — and nothing else except what
you put in the server's env block. A proxy configured system-wide will not be
picked up; it has to be named explicitly, alongside the API key:
Restart Claude Desktop after editing the config — it reads it at launch.
Server output lands in:
- macOS:
~/Library/Logs/Claude/mcp-server-octen.log - Windows:
%APPDATA%\Claude\logs\mcp-server-octen.log
Everything the server writes to stderr, including the tracing below, goes there.
Diagnosing a slow or failing call
Add "OCTEN_MCP_DEBUG": "1" to the env block above while you are investigating,
and take it out afterwards — the client appends this to a log file that is
never rotated, so leaving it on grows that file for the life of the install.
With it on, every call is traced to stderr:
Each field answers a specific question:
call #N receivedtimestamp — when the call reached this process. Subtract it from the time your MCP client issued the tool call: the difference is time spent entirely outsideocten-mcp, in the host or in whatever relays between them. A client-side stopwatch alone cannot separate that from time we are responsible for.connect … established in Xms— a handshake happened, and what it cost.connect FAILEDnames the phase and error code instead.peer=/tls=/alpn=— which address the connection actually reached (the API hostname is anycast, so the hostname alone cannot tell you which edge), and the negotiated TLS version and protocol — a mismatch there otherwise presents as an unexplained slow or failed handshake.socket=new/socket=reused— whether this call paid for a handshake. This is the difference between "the service is slow" and "the connection was thrown away between calls".elapsedvshandler_total— time in the HTTP request vs time in the tool handler. A large gap means the cost is in request assembly or response formatting, not the network.request_id— in this trace only: the client-generated correlation id, stable across the retry, tying a call's attempts together. It never appears in user-facing error messages, deliberately: Octen support cannot look it up (the gateway does not record the header), and an id labelledrequest_idreads like one they could. Error messages carry only ids verified searchable on Octen's side — today that is exactly one: the server's ownrequest_idfrom an API error envelope.
Failures name the cause rather than fetch failed:
UND_ERR_CONNECT_TIMEOUT means the connection was never established, ECONNRESET
means it was established and then torn down, and ENOTFOUND means DNS — three
different problems with three different owners.
Request timeouts: search and the media tools default to 30s, broad_search to 120s (raisable to 300s),
and extract to its per-URL budget plus headroom. The search tools accept a
timeout parameter to override; extract's timeout is the server-side,
per-URL fetch budget, so the client ceiling is derived from it rather than
equal to it. The automatic retry draws down the same deadline as the first
attempt, so the stated timeout bounds the whole call, retry included.
Local development
More docs
- Best practices for agent integration: docs/best-practices.md
- Search API reference: docs.octen.ai/api-reference/search
- Extract API reference: docs.octen.ai/api-reference/extract
License
MIT © Octen
Source: README.md at commit 6a38d04
Tools
0Version history
1- v0.1.5LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts