DeepSeek Search MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@DeepSeek Search MCPsearch for recent MCP server tutorials and fetch the top result"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
deepseek-search-mcp
Unofficial. A community project. Not affiliated with, endorsed by, or supported by DeepSeek. It only calls the public Search / Fetch REST APIs with your own API key.
A TypeScript MCP server that wraps DeepSeek's Search and Fetch APIs into two read-only tools, so any MCP-capable agent can use DeepSeek's own search engine regardless of which model it runs on.
Tool | What it does | Upstream |
| Ranked web results ( |
|
| One page as Markdown text, truncated to |
|
Verified end to end: 6/6 checks in scripts/smoke.ts (discovery, happy path, 429 retry, 401 surfacing, missing key, truncation), run against a mock API so no key or quota is needed.
Install
# from npm
npx -y @evilwk/deepseek-search-mcp
# straight from GitHub, no registry involved
npx -y github:evilwk/deepseek-search-mcp
# from source
git clone https://github.com/evilwk/deepseek-search-mcp
cd deepseek-search-mcp && pnpm install && pnpm buildGet a key at https://platform.deepseek.com/api_keys. Search and Fetch are billed per successful request (¥5 / 1000), so the account needs a positive balance — an HTTP 402 from the server means it ran out.
Related MCP server: websearch-deepseek
Run
export DEEPSEEK_API_KEY=sk-...
node dist/index.js # stdio, for local agents
node dist/index.js --http # Streamable HTTP, for sharingA one-liner sanity check of the stdio handshake:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
| node dist/index.jsClient configuration
Each snippet below launches the server from a local build (node /abs/path/.../dist/index.js). If you installed from npm or GitHub instead, swap that for npx:
// from npm
{ "command": "npx", "args": ["-y", "@evilwk/deepseek-search-mcp"] }
// straight from GitHub
{ "command": "npx", "args": ["-y", "github:evilwk/deepseek-search-mcp"] }Claude Code
claude mcp add deepseek-search -e DEEPSEEK_API_KEY=sk-... -- node /abs/path/deepseek-search-mcp/dist/index.jsGeneric mcpServers block (Cursor, Claude Desktop, DSH, most hosts)
{
"mcpServers": {
"deepseek-search": {
"command": "node",
"args": ["/abs/path/deepseek-search-mcp/dist/index.js"],
"env": { "DEEPSEEK_API_KEY": "sk-..." }
}
}
}Codex CLI (~/.codex/config.toml)
[mcp_servers.deepseek-search]
command = "node"
args = ["/abs/path/deepseek-search-mcp/dist/index.js"]
env = { DEEPSEEK_API_KEY = "sk-..." }Pi (~/.pi/agent/mcp.json, or .pi/mcp.json in a trusted project)
{
"mcpServers": {
"deepseek-search": {
"command": "node",
"args": ["/abs/path/deepseek-search-mcp/dist/index.js"],
"env": { "DEEPSEEK_API_KEY": "${DEEPSEEK_API_KEY}" },
"description": "DeepSeek 自研搜索引擎:网页搜索与单页 Markdown 抓取",
"exposure": "direct",
"timeout": 60
}
}
}Pi's default exposure is codemode: the tools are registered but never declared to the model, so it would only reach them from codemode scripts or via tool_search. Two read-only tools belong at the top level — hence "exposure": "direct". Validate with pi mcp list, inspect with /mcp, and run /reload after editing the file outside a session.
OpenCode (~/.config/opencode/opencode.json, or project opencode.json)
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"deepseek-search": {
"type": "local",
"command": ["node", "/abs/path/deepseek-search-mcp/dist/index.js"],
"enabled": true,
"environment": { "DEEPSEEK_API_KEY": "{env:DEEPSEEK_API_KEY}" }
}
}
}Note the shape differences from the Claude-style blocks above: command is an array, the env map is called environment, and interpolation is {env:NAME} rather than ${NAME}. For the HTTP mode below, use "type": "remote" with url + headers and set "oauth": false, otherwise OpenCode will try an OAuth flow the bearer token already replaces.
HTTP mode (shared / remote)
MCP_PORT=3000 MCP_AUTH_TOKEN=change-me DEEPSEEK_API_KEY=sk-... node dist/index.js --http
# -> http://127.0.0.1:3000/mcp (Streamable HTTP, session-based)The DeepSeek key stays server-side; callers only need MCP_AUTH_TOKEN as a bearer token. There is no OAuth flow here — if you expose this beyond localhost, put it behind a real gateway. It bills your account.
Environment variables
Var | Default | Notes |
| — | Required for tool calls |
|
| For testing against a mock |
|
|
|
|
| HTTP mode only |
| unset | HTTP mode; unset = no auth, localhost only |
Design notes
stdout is forbidden territory in stdio mode. All logging goes to
stderr; a strayconsole.logcorrupts the JSON-RPC stream and produces the classic "server disconnected" symptom.Retries match the documented policy. 408 / 429 / 5xx get two retries with 500 ms → 1 s backoff (enough for the account-wide 5 QPS cap). 402 is a hard stop — retrying only burns quota.
Errors are model-readable. Failures come back as
isError: truewith an explicit "retry" / "do not retry" hint, so the agent does not hammer a permanent 4xx.need_contentdefaults to false.summary(600–800 chars) answers most questions; full page bodies would inflate the context window by orders of magnitude.readOnlyHint: trueon both tools, so hosts can auto-approve them without a prompt.The API client is transport-agnostic.
src/deepseek.tsimports nothing from the MCP SDK — it can back a CLI or an HTTP tool just as easily as this server.
Layout
src/deepseek.ts REST client: retry, timeouts, truncation, typed errors
src/server.ts McpServer + tool registration (zod schemas, annotations)
src/index.ts entry: stdio by default, --http for Streamable HTTP
src/http.ts express 5 + session map + bearer auth
scripts/smoke.ts mock-API end-to-end test, no real key neededSkill or MCP?
Both are thin shells over src/deepseek.ts. Use MCP when the host cannot execute shell commands or needs typed tool schemas; use a Skill when the host has bash and you want to avoid a resident process and per-tool schema overhead. This repo is the MCP half.
Available Tools
2 toolsfetchDeepSeek Web FetchARead-only
Fetch one web page and return its title plus Markdown body. Use after search when a single result needs full-text reading. Long pages are truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Absolute http(s) URL with a host, no embedded credentials. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety and scope are covered structurally. The description adds genuinely useful behavior the agent cannot infer: the return shape (title + Markdown body) and the truncation of long pages, which affects how results should be trusted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, zero redundancy, with the core capability front-loaded and the usage rule and truncation caveat following in order of importance. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with no output schema, the description covers what the agent most needs: the return format and the truncation limit. Nothing required to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single `url` parameter is 100% documented in the schema (absolute http(s), host required, no credentials), so the description is not obligated to compensate. 'One web page' reinforces the single-URL constraint but adds no syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fetch), a bounded resource (one web page), and the exact return payload (title plus Markdown body). An agent can distinguish this from `search` purely from the description without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the sibling and the condition that selects this tool: 'Use after `search` when a single result needs full-text reading.' It does not state the inverse case (e.g., don't use it to read many documents at once), but the sequencing guidance is clear enough to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchDeepSeek Web SearchARead-only
Search the web and return ranked results (title, url, snippet, summary, date, authority). Supports site:, -site:, lang:, after:, before: and quoted exact phrases in query. summary is 600-800 characters and is usually enough to answer; enable needContent only when you truly need page bodies.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of results to return (1-50). | |
| query | Yes | Search query, 1-128 characters. Supports site:/lang:/after:/before: operators. | |
| needContent | No | Return full page text in each result's `content` field. Makes responses much larger. | |
| oriQuestion | No | The user's original question, which helps the engine infer search intent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds real value beyond them: the shape of each result, the size of the summary field, the cost implication of needContent (responses become much larger), and supported query operators. It stops short of pagination or rate-limit behavior, which is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with purpose and return shape, then operators, then the summary-vs-content tradeoff. No filler, no restatement of the title, and the most decision-relevant constraint (summary is usually enough) lands where an agent will read it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must carry return-value information, and it does so by listing result fields and summary length. It omits any note on count limits or the role of oriQuestion/query length, though those are documented in the schema, so the definition is nearly complete for a four-parameter search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description goes beyond the schema by enumerating the query operator syntax (site:, -site:, lang:, after:, before:, quoted phrases) and by giving decision guidance for needContent ('only when you truly need page bodies'), which the schema only describes as making responses larger.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (the web/tool owner: DeepSeek Web Search) and enumerates the returned fields (title, url, snippet, summary, date, authority), which is exactly what separates it from the sibling fetch tool. An agent can tell this is a query-and-rank tool rather than a URL-retrieval tool without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-not condition: enable needContent only when you truly need page bodies, plus the inference that summary (600-800 chars) is usually sufficient. It does not name the sibling tool fetch as the alternative for full-page retrieval, so routing between the two is left to inference rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.1- First observed
fetch - First observed
search
TDQS
Scored across 2 tools
Search and fetch target clearly different operations: search returns ranked results, while fetch retrieves a single page's full content. The descriptions reinforce the intended use sequence (search then fetch), leaving no meaningful ambiguity.
Both tool names are simple lowercase verbs (search, fetch), following a consistent single-verb convention. There is no mixing of styles or noun phrasing.
Two tools is slightly below the typical 3–15 range, but each is well-scoped and earns its place for a focused web search and retrieval server. The surface is minimal yet sufficient for the core workflow.
The server is read-only, and its domain lifecycle is search then fetch; both operations are present with useful filtering parameters. No obvious gaps exist for basic web search and page retrieval.
Related MCP Connectors
Docs: https://docs.keenable.ai/mcp-server Keenable is a free, remote MCP server that gives agents access to the web index. Search the web with ranked results and date/site filters, then fetch any indexed page as clean markdown. Works out of the box with no account or API key.
Free web search for AI agents. No API key required. Hosted MCP in active development.
MCP server for Firecrawl — web search, scraping, and biomedical/arXiv paper search.
Scrape, crawl and search the web for AI agents via MCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server that exposes web_search and web_fetch tools, allowing LLM applications to search the web via DuckDuckGo and fetch page content as cleaned markdown.-
- AlicenseAqualityCmaintenanceAn MCP server that provides web search powered by DeepSeek's native search API, returning AI-generated answers with source links. Integrates with MCP-compatible clients like Claude Code and Cursor.1MIT
- FlicenseAqualityBmaintenanceExposes web search and page fetching tools via the MCP protocol, allowing integration with AI editors like Cursor for autonomous research workflows.2-
- AlicenseAqualityAmaintenanceEnables AI agents to run local deep-research workflows via a single MCP stdio server, combining web search, page extraction, query-aware distillation, and caching without cloud quotas. It exposes tools for deep research, search, and single or batch URL reading.6MIT