octen-mcp
MCP serverDocs & knowledgeGive your AI a URL and it receives the page as markdown it can read, along with the page's category, its structure, and the sections most relevant to your question. Octen converts web pages into this AI-ready format. Once added, your AI can take a link you share and work with the page's content directly.
Unavailable. This server has no hosted endpoint yet, so Ahel can't serve it.
Add to setup to save this item as a reference. Ahel cannot run it, and signing in will not install it.
What your AI can do with it
- Convert a URL into markdown the AI can read directly
- Label each page with its category
- Show how a page is structured
- Highlight the parts of a page that match your question
Getting started
- Save this item in Your setup as a reference.
- Read the source or reference documentation for its setup requirements. Saving it here does not connect it to your AI.
- Check this page for availability before trying to install it through Ahel.
From the project's README
As published by octen-team/octen-mcp in README.md.
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/news_search: search the live web with domain, text, language, and time filters.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(In Beta — contact us for beta access): 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.
Two ways to connect. Both serve the same six tools.
| Endpoint | When | |
|---|---|---|
| Hosted (recommended) | https://mcp.octen.ai/mcp | Nothing to install or update. Works with any client that speaks remote MCP. |
| Local | npx -y octen-mcp | Clients without remote support, air-gapped setups, or when you want the process on your own machine. |
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.
| Form | Use when |
|---|---|
x-api-key: <key> | The default. |
Authorization: Bearer <key> | Your client only offers one header field. |
?octenApiKey=<key> appended to the URL | Your client accepts nothing but a URL. |
Or use OAuth and paste no key at all — see Signing in instead.
By client
Claude Code
claude mcp add --transport http octen https://mcp.octen.ai/mcp --header "x-api-key: your-key-here"
Cursor — ~/.cursor/mcp.json
{
"mcpServers": {
"octen": {
"url": "https://mcp.octen.ai/mcp",
"headers": { "x-api-key": "your-key-here" }
}
}
}
VS Code — .vscode/mcp.json (workspace) or the user config. Note servers,
not mcpServers, and the explicit type:
{
"servers": {
"octen": {
"type": "http",
"url": "https://mcp.octen.ai/mcp",
"headers": { "x-api-key": "your-key-here" }
}
}
}
Codex
codex mcp add octen --url https://mcp.octen.ai/mcp --header "x-api-key: your-key-here"
Windsurf — ~/.codeium/windsurf/mcp_config.json. The key is serverUrl,
not url:
{
"mcpServers": {
"octen": {
"serverUrl": "https://mcp.octen.ai/mcp",
"headers": { "x-api-key": "your-key-here" }
}
}
}
Gemini CLI — ~/.gemini/settings.json. The key is httpUrl:
{
"mcpServers": {
"octen": {
"httpUrl": "https://mcp.octen.ai/mcp",
"headers": { "x-api-key": "your-key-here" }
}
}
}
Claude Desktop takes the URL directly — no config file, no bridge. In
Settings → Connectors, click Add custom connector, name it Octen, and
enter:
https://mcp.octen.ai/mcp
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:
https://mcp.octen.ai/mcp?octenApiKey=your-key-here
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.
Clients that only speak stdio (Zed, Warp, Raycast, Cline) reach a remote
server through the mcp-remote bridge. Note there is no space after the
colon in --header — the value is split on the first one:
{
"mcpServers": {
"octen": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.octen.ai/mcp",
"--header", "x-api-key:your-key-here"
]
}
}
}
If a client cannot pass a header at all and takes only a URL, put the key in
the URL instead: https://mcp.octen.ai/mcp?octenApiKey=your-key-here.
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:
https://mcp.octen.ai/mcp?tools=search,extract
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
{
"mcpServers": {
"octen": {
"command": "npx",
"args": ["-y", "octen-mcp"],
"env": { "OCTEN_API_KEY": "your-key-here" }
}
}
}
| Agent | One-line install |
|---|---|
| Claude Code | claude mcp add --scope user octen -e OCTEN_API_KEY=your-key-here -- npx -y octen-mcp |
| Codex | codex mcp add octen --env OCTEN_API_KEY=your-key-here -- npx -y octen-mcp |
| Gemini CLI | gemini mcp add octen -e OCTEN_API_KEY=your-key-here -- npx -y octen-mcp |
| VS Code | code --add-mcp '{"name":"octen","command":"npx","args":["-y","octen-mcp"],"env":{"OCTEN_API_KEY":"your-key-here"}}' (or click a badge above) |
| Cursor | Add to Cursor (then edit the key), or use the JSON above in ~/.cursor/mcp.json |
| Claude Desktop | No CLI. For the hosted endpoint use Settings → Connectors → Add custom connector (above); for a local install, the config file (below) |
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. 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. image_search and
video_search are 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
| Tool | What it does | Best for |
|---|---|---|
search | Search the live web with domain, text, language (ISO 639-1), time, and content controls | a single focused web search |
news_search | Same engine as search, fixed to news | current events and timely reporting |
broad_search | Decompose a query into up to max_queries sub-queries, search concurrently, return grouped results (same per-sub-query options as search, including the language filter) | research-style, multi-angle coverage |
extract | Fetch 1-20 URLs and return clean content, labels, and optional highlights | summarization, RAG, fact lookup |
image_search | In Beta — contact us for beta access. Search the web for images by text query (optional reference image_url) | finding pictures, photos, visual references |
video_search | In Beta — contact us for beta access. Search the web for videos by text query | finding videos, clips, footage |
These six 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
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
query | string | yes | 1–500 chars | |
topic | string | general / news | "general" | |
count | integer | 1–100 | 5 | |
include_domains | array | ≤1200 items; each ≤60 | ||
exclude_domains | array | ≤1200 items; each ≤60 | ||
include_text | array | ≤5 items; each ≤30 | ||
exclude_text | array | ≤5 items; each ≤30 | ||
time_basis | string | auto / published / crawled | "auto" | |
time_range | string | day / week / month / year / d / w / m / y | ||
start_time | string | |||
end_time | string | |||
format | string | text / markdown | "text" | |
safesearch | string | off / strict | "strict" | |
language | array | [] | ||
highlight | object | enable, max_tokens | ||
full_content | object | enable, max_tokens | ||
include_images | boolean | false | ||
timeout | integer | 1–60 |
news_search
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
query | string | yes | 1–500 chars | |
count | integer | 1–100 | 5 | |
include_domains | array | ≤1200 items; each ≤60 | ||
exclude_domains | array | ≤1200 items; each ≤60 | ||
include_text | array | ≤5 items; each ≤30 | ||
exclude_text | array | ≤5 items; each ≤30 | ||
time_basis | string | auto / published / crawled | "auto" | |
time_range | string | day / week / month / year / d / w / m / y | ||
start_time | string | |||
end_time | string | |||
format | string | text / markdown | "text" | |
safesearch | string | off / strict | "strict" | |
language | array | [] | ||
highlight | object | enable, max_tokens | ||
full_content | object | enable, max_tokens | ||
include_images | boolean | false | ||
timeout | integer | 1–60 |
broad_search
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
query | string | yes | 1–500 chars | |
max_queries | integer | 1–30 | 5 | |
topic | string | general / news | "general" | |
count | integer | 1–100 | 5 | |
include_domains | array | ≤1200 items; each ≤60 | ||
exclude_domains | array | ≤1200 items; each ≤60 | ||
include_text | array | ≤5 items; each ≤30 | ||
exclude_text | array | ≤5 items; each ≤30 | ||
time_basis | string | auto / published / crawled | "auto" | |
time_range | string | day / week / month / year / d / w / m / y | ||
start_time | string | |||
end_time | string | |||
format | string | text / markdown | "text" | |
safesearch | string | off / strict | "strict" | |
language | array | [] | ||
highlight | object | enable, max_tokens | ||
full_content | object | enable, max_tokens | ||
include_images | boolean | false | ||
timeout | integer | 1–300 |
extract
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
urls | array | yes | ≤20 items; each ≤2048 | |
query | string | ≤500 chars | ||
max_age_seconds | integer | 300–31536000 | 86400 | |
format | string | markdown / text | "markdown" | |
timeout | integer | 1–60 | 30 | |
include_images | boolean | false | ||
include_videos | boolean | false | ||
include_audio | boolean | false |
image_search
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
query | string | ≤500 chars | ||
image_url | string | |||
image_data | string | ≤5242880 chars | ||
topic | string | general / design | "general" | |
count | integer | 1–10 | 5 | |
include_domains | array | |||
exclude_domains | array | |||
safesearch | string | off / strict | "strict" | |
html_snippet | object | enable, max_tokens | ||
timeout | integer | 1–60 |
video_search
| Parameter | Type | Required | Limits | Default |
|---|---|---|---|---|
query | string | yes | 1–500 chars | |
count | integer | 1–10 | 5 | |
time_range | string | day / week / month / year / d / w / m / y | ||
start_time | string | |||
end_time | string | |||
safesearch | string | off / strict | "strict" | |
timeout | integer | 1–60 |
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+):
{
"mcpServers": {
"octen": {
"command": "npx",
"args": ["-y", "octen-mcp"],
"env": { "OCTEN_API_KEY": "your-key-here" },
"alwaysLoad": true
}
}
}
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:
PORT=8080 npx -y -p octen-mcp octen-mcp-http # or: octen-mcp-http after a global install
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
Shortened here. Read the whole README on GitHub.
Signals
- GitHub stars
- 21
- Forks
- 1
- Last commit
- Sep 2026
- Weekly downloads
- 323
- Weekly_downloads
- 323 weekly_downloads
Advanced
- Delivery
- octen-mcp MCP server → your Ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
io-github-octen-team-octen-mcp- Source
- github.com/octen-team/octen-mcp
github.com/octen-team/octen-mcp
More in Docs & knowledge
MCP server · dat999zx
More in Docs & knowledgeagent-native-slides
MCP server · builderio
More in Docs & knowledgemcp-memory-server
MCP server · mnemoverse
More in Docs & knowledgedatasinking
MCP server · heubme2020
More in Docs & knowledgespoken
MCP server · spokenmd
More in Docs & knowledgeemailmd
MCP server · anypost
More in Docs & knowledge