Skip to main content
Glama
DeepSeek Search Everywhere MCP

DeepSeek Search Everywhere MCP

DeepSeek Search Everywhere MCP

CI License: MIT PyPI Python versions Glama score

An MCP server that gives AI agents web search, page fetching and multi-source research through the official DeepSeek Search & Fetch API.

It is a thin, careful layer over that API: results are deduplicated, content is capped to a budget you set, repeated calls are served from an in-memory cache, and outgoing calls are paced by a local rate limiter. Seven tools, stdio by default, optional bearer-protected streamable HTTP.

It is a standard MCP server, so it works with any MCP-compatible AI client or agent: Claude Code, Claude Desktop, Google Antigravity, Cursor, Windsurf, VS Code (GitHub Copilot), Gemini CLI, Codex CLI, Zed, opencode and others. Local clients launch it over stdio; remote or shared setups can connect over HTTP.

Not affiliated with DeepSeek. This is an independent, community-maintained project.

Features

  • Search with content in one request: need_content returns page text inline, so there is usually no need for a second fetch per result.

  • Batch fetch and research: deepseek_fetch_many fetches up to 10 URLs concurrently; deepseek_research gathers sources in a single pass: one search, then direct fetches for pages whose search content is missing. It does not iterate or summarise.

  • Deep research and structured extraction: deepseek_deep_research decomposes topics into subqueries and synthesizes cited briefing reports; deepseek_extract extracts validated structured JSON matching schemas or fields.

  • Result hygiene: canonical-URL and title/site deduplication, per-result and total character budgets, Markdown unescaping.

  • Optional query rewrite to English through deepseek-flash (thinking disabled), plus an explicit lang operator for non-English queries.

  • Cache and limiter: TTL + LRU cache with single-flight, per-endpoint token buckets, refresh to bypass.

  • Safe by default: static SSRF checks, secret redaction, no telemetry. See Security.

Related MCP server: Web Search MCP Server

Requirements

Install

The server is published on PyPI and listed in the official MCP Registry as io.github.radoxtech/deepseek-search-everywhere-mcp.

# Run without installing (uv)
uvx deepseek-search-everywhere-mcp

# Or install with pip
pip install deepseek-search-everywhere-mcp

The HTTP transport needs the http extra (it pulls in uvicorn):

pip install "deepseek-search-everywhere-mcp[http]"

To run the latest unreleased code from main, or from a source checkout:

uvx --from git+https://github.com/radoxtech/deepseek-search-everywhere-mcp deepseek-search-everywhere-mcp

git clone https://github.com/radoxtech/deepseek-search-everywhere-mcp.git
cd deepseek-search-everywhere-mcp
pip install -e ".[http]"

Check that the key and connectivity work (prints your balance, then exits):

export DEEPSEEK_API_KEY=sk-...
deepseek-search-everywhere-mcp --check

Quick start

All examples use stdio. Replace sk-... with your key.

The server is client-agnostic: the examples below cover common clients, and any other MCP client (Antigravity, Cursor, Windsurf, VS Code, Gemini CLI, Codex CLI, Zed, ...) works with the same command, arguments and environment variable in its own MCP configuration format.

Claude Code

claude mcp add deepseek-search-everywhere -e DEEPSEEK_API_KEY=sk-... -- \
  uvx deepseek-search-everywhere-mcp

Claude Desktop

Edit claude_desktop_config.json (Settings, Developer, Edit Config):

{
  "mcpServers": {
    "deepseek-search-everywhere": {
      "command": "uvx",
      "args": ["deepseek-search-everywhere-mcp"],
      "env": { "DEEPSEEK_API_KEY": "sk-..." }
    }
  }
}

opencode

In opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "deepseek-search-everywhere": {
      "type": "local",
      "command": ["uvx", "deepseek-search-everywhere-mcp"],
      "environment": { "DEEPSEEK_API_KEY": "{env:DEEPSEEK_API_KEY}" },
      "enabled": true
    }
  }
}

Any stdio client

Most clients (including Antigravity, Cursor and Windsurf) use an mcpServers JSON block. Use the uvx form from the Claude Desktop example, or, if the package is already installed, point the client at the console script:

{
  "mcpServers": {
    "deepseek-search-everywhere": {
      "command": "deepseek-search-everywhere-mcp",
      "env": { "DEEPSEEK_API_KEY": "sk-..." }
    }
  }
}

python -m deepseek_search_everywhere_mcp is equivalent.

Streamable HTTP

For clients that connect over HTTP. A bearer token is always required; the server refuses to start without one.

pip install "deepseek-search-everywhere-mcp[http]"
export DEEPSEEK_API_KEY=sk-...
export MCP_BEARER_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
deepseek-search-everywhere-mcp --transport streamable-http   # http://127.0.0.1:8000/mcp

Options: --host (default 127.0.0.1), --port (default 8000), --path (default /mcp). The token is read from the environment only, never from the command line. The server runs stateless and answers with JSON (no SSE streams). Client entry:

{
  "mcpServers": {
    "deepseek-search-everywhere": {
      "url": "http://127.0.0.1:8000/mcp",
      "headers": { "Authorization": "Bearer <MCP_BEARER_TOKEN>" }
    }
  }
}

Claude Code: claude mcp add --transport http deepseek-search-everywhere http://127.0.0.1:8000/mcp --header "Authorization: Bearer $MCP_BEARER_TOKEN". The server speaks plain HTTP; when binding beyond loopback, put TLS in front of it (see SECURITY.md).

Docker

An official container image is available on GitHub Container Registry (ghcr.io):

docker pull ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest

Stdio mode (Claude Desktop, Cursor, local IDEs):

{
  "mcpServers": {
    "deepseek-search-everywhere": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "DEEPSEEK_API_KEY=sk-...",
        "ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest"
      ]
    }
  }
}

Remote HTTP hosting (Docker Compose, VPS, n8n, Dify, cloud agents):

docker run -d --name deepseek-mcp -p 8000:8000 \
  -e DEEPSEEK_API_KEY="sk-..." \
  -e MCP_BEARER_TOKEN="your-secret-token" \
  ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest \
  --transport streamable-http --host 0.0.0.0 --port 8000

The container runs as an unprivileged non-root user (UID 10001) with dependencies isolated from the host.

Tools

Tool

Purpose

Parameters (defaults)

deepseek_search

Search the web; returns inline page text (default) or snippets and metadata

query, count=5 (1-50), ori_question, need_content=True, lang, max_chars_per_result=4000, max_total_chars=30000, dedupe=True, rewrite=False, after, before, include_domains, exclude_domains, refresh=False, summary_chars, strip_boilerplate=True

deepseek_fetch

Fetch one known URL as Markdown (supports lexical snippet extraction and sectional reading)

url, clean=True, max_chars=20000, query, section, max_snippets=3, refresh=False, strip_boilerplate=True

deepseek_fetch_many

Fetch 1-10 URLs concurrently (up to 5 at a time)

urls, max_chars_per_url=4000, max_total_chars=20000, clean=True, query, refresh=False, strip_boilerplate=True

deepseek_research

Single-pass source gathering: search with content and auto-fetch stub pages (< 200 chars). No iteration, no summary

question, max_pages=5 (1-50), per_page_chars=6000, total_chars=30000, after, before, include_domains, exclude_domains, lang, rewrite=False, dedupe=True, refresh=False, strip_boilerplate=True

deepseek_deep_research

Multi-angle research on a topic; decomposes subqueries, gathers sources, and synthesizes a cited report

topic, max_queries=3 (2-4), max_pages_per_query=3 (1-5), lang, dedupe=True, refresh=False, strip_boilerplate=True

deepseek_extract

Extract structured JSON from a web page conforming to target fields or a schema

url, fields=None, schema=None, instruction=None, clean=True, max_chars=40000, refresh=False, strip_boilerplate=True

deepseek_check_balance

Account balance and session metrics (upstream queries, cache hits, estimated cost)

none

Notes on the parameters:

  • query and question are limited to 128 characters and support site:, -site:, "phrase", lang:, after: and before:. ori_question (max 128 characters) is the natural-language question and improves ranking.

  • after, before, include_domains and exclude_domains are explicit filter parameters for search tools. include_domains compiles to space-separated site: operators, exclude_domains to -site:, and dates to after:YYYY-MM-DD / before:YYYY-MM-DD. Filters and query are budget-guarded together to stay within DeepSeek's 128-character limit.

  • query in deepseek_fetch and deepseek_fetch_many extracts ranked relevant excerpts using a BM25-lite scoring engine without invoking an LLM. section (1-based index) enables sectional reading of long documents with has_more and total_sections pagination metadata. Both operate in-memory on cached pages.

  • deepseek_deep_research decomposes topics into 2-4 subqueries via deepseek-flash, searches concurrently, merges and dedupes candidate sources, and synthesizes a cited report with numbered bracket citations [1], [2] capped at 6 sources / 24,000 characters. If the synthesis deadline is approached, it gracefully falls back to returning the gathered sources.

  • deepseek_extract uses deepseek-flash to extract structured JSON matching either fields: list[str] or a schema: dict without ingesting the full page text into client context. Missing requested fields are populated with null, and pages with no readable text fast-fail with zero LLM token consumption.

  • deepseek_check_balance (and legacy alias deepseek_balance) includes a session block with uptime, total queries handled, cache hit rate, and estimated cost and savings (at $0.00075 per request).

  • lang is an explicit language operator such as es, de, ja or pt-BR. Without it, results for non-English queries may be mixed-language; for named entities, compare with and without it.

  • With dedupe=True, searches ask the upstream for a few extra results (max(2, ceil(count * 0.5)), capped at 50) and trim to count after removing duplicates, so you still get count results when the index returns repeats. With dedupe=False exactly count are requested.

  • Without need_content, each search result carries a short summary instead of page text. It is capped at summary_chars (default 400) and never longer than max_chars_per_result; summary_chars=0 leaves it out. With content, a summary only stands in for a result that came back without content, and summary_chars then defaults to max_chars_per_result. Summaries count towards max_total_chars.

  • rewrite=True (also in deepseek_research) translates the query to English with deepseek-flash before searching. It is skipped when lang is set and falls back silently to the original query if the rewrite fails.

  • clean=True (fetch tools and search content) removes backslash escapes from every ASCII punctuation character (\(, \-, \[, \/, \#...). Fenced code blocks and inline code spans are left untouched.

  • Search results (content, snippet, summary, and so deepseek_research sources) also get JSON string escapes decoded when the search index returns a page's text still JSON-escaped (Kr\u00f3tkie becomes Krótkie, <\/p> becomes </p>), outside code. Simple attribute-less HTML tags left in snippets and summaries (<p>, <br>, </h2>...) are replaced with a space.

  • strip_boilerplate=True (keyword-only, on every tool that returns page content) removes known site-interface lines. DeepSeek returns Reddit threads with the site UI localised to Chinese whatever the thread's language: the comment-sort menu (排序方式:, 最佳, 新...), the # 评论区域 heading, the archived-post banner, [已删除] author lines and the sign-up footer. Rules are per site (Reddit only for now, matched on reddit.com and its subdomains) and only drop lines that consist entirely of a known label, so user text, Chinese included, and code blocks are kept. One rule applies to every site: a cookie-consent (CMP) dialog at the very start of the content ("Informacje o prywatności", "We value your privacy", "Wir verwenden Cookies"...) is removed when its first line opens with a known consent phrase and the run of lines shows a dialog control ("Accept all", "Zarządzaj preferencjami zgody"...). Removal stops at the first line that is not part of the dialog, and text further down is never touched, so an article about privacy is kept. When a fetched page is nothing but the banner, content is empty and a note says so. It runs after clean and before the character caps, so budgets count the cleaned text; it does not change caching. strip_boilerplate=False returns the content as fetched.

  • deepseek_fetch_many skips empty entries, fetches duplicate URLs (same canonical URL) once, keeps the input order, and reports a failing URL as an item with ok: false instead of failing the batch. All fetches share a 120 s deadline; URLs still pending then are reported as deadline_exceeded. Each page gets at most min(max_chars_per_url, max_total_chars // number of URLs) characters.

  • deepseek_research is single-pass source gathering, not an agent: it makes exactly one search plus the gap fetches, never refines the query or searches again, and does no summarising. It takes the same lang, rewrite and dedupe options as search; the envelope's query_used shows the query that was sent. It does no summarising and makes no model call unless rewrite=True: it returns sources for the caller to synthesise. Each source carries title, url, date and site (both null when the upstream gave none), date_source, authority and rerank_score, so stale or off-topic sources are visible without opening them.

  • deepseek_research is for reconnaissance: finding candidate sources. There is no quality filter, so results can include low-quality or secondary pages (student papers, aggregators, clickbait). Verify facts in the primary source before citing them. To reach primary sources, ask in English for the primary study (for example "original study on X, journal article") and use site: for Polish or other local sources (site:cbos.pl ...).

  • authority is passed through from the upstream index as is. Its meaning is not documented and it does not track credibility (a student PDF and a reference database can score alike), so do not use it to judge or filter sources.

Example calls:

deepseek_search(query="rust async runtime comparison", count=5)
deepseek_search(query="gobierno de España presupuestos 2026", lang="es", need_content=False)
deepseek_fetch(url="https://docs.rs/tokio/latest/tokio/", max_chars=15000)
deepseek_fetch_many(urls=["https://example.com/a", "https://example.com/b"], max_total_chars=12000)
deepseek_research(question="how does HTTP/3 connection migration work", max_pages=4)
deepseek_deep_research(topic="comparing Raft vs Paxos consensus mechanisms in distributed systems")
deepseek_extract(url="https://news.ycombinator.com", fields=["top_story", "points", "author"])
deepseek_check_balance()

Response envelope

Every tool returns a JSON object with ok.

Field

Where

Meaning

ok

all

true on success, false on failure

cached

all tools except balance; also per item in deepseek_fetch_many and per source in deepseek_research

true when the response came from the in-memory cache. For deepseek_fetch_many and deepseek_research it is true only when no upstream request was made and at least one response came from the cache

cached_count

deepseek_fetch_many, deepseek_research

how many responses in this call were served from the cache

requests_used

deepseek_fetch_many, deepseek_research

upstream requests actually made (cache hits are free)

elapsed_ms

all, including errors

wall time of the tool call in milliseconds (monotonic clock); a cache hit reports its own, near-zero time

notes

all success envelopes

human-readable remarks: dedupe counts, rewrite applied or failed, lang applied, truncation ("Some page content was truncated to respect the character budget.")

error

failures

{ "code", "message", "status"? }; status is the upstream HTTP status when there was one

partial

deepseek_fetch_many, deepseek_research

true when some items or sources failed; each failed one carries its own error. The top-level ok stays true, so check partial

failed_count

deepseek_fetch_many, deepseek_research

number of failed items or sources

Search results carry title (the URL host without www. when the upstream title is blank; a title repeated around -, such as Reddit's X - X, is collapsed to X), url, date, authority (0-4, -1 unknown; an upstream field, not a credibility score), rerank_score, site, snippet, and content with chars or summary where available. When the upstream gives no date, a YYYY-MM-DD date (a valid calendar date, year 1990 to next year) found in the title or the first 600 characters of the text is used instead. Without one, a full English or Polish month name next to a year (September 2025, wrzesień 2025, PubMed-style 2025 September) gives the first of that month, and a day written with it (15 września 2025, September 15, 2025) gives that day; Polish names are matched in the nominative and genitive, abbreviations and a bare year are ignored; date_source is "upstream", "content" or null (no date), on search results and research sources alike. deepseek_fetch returns url, title, content, chars, truncated. deepseek_deep_research returns topic, subqueries, report (with bracketed citations [1], [2]), synthesized, and sources. deepseek_extract returns url, title, and data (the extracted JSON matching the requested fields or schema). chars is always the length of the content returned, in every tool.

Error codes

Code

Meaning

missing_api_key

no key in DEEPSEEK_API_KEY or the fallback file

ssrf_blocked

URL rejected locally: internal host, literal private/loopback address, or embedded credentials

bad_url, invalid_url, empty_url, url_too_long

malformed or oversized URL

empty_query, query_too_long, bad_count, bad_lang, bad_request

invalid arguments

rate_limited_local

no local rate-limit token became available within the maximum wait

response_too_large

upstream body exceeded the cap (8 MiB search, 32 MiB fetch)

deadline_exceeded

batch item not finished within the shared batch deadline

timeout, network_error, request_failed, invalid_json

transport-level failures

internal_error

unexpected exception while fetching one batch item

other / http_error

upstream API errors keep the code from DeepSeek (or http_error) and set error.status

Response size and cost

Serialized JSON size of one response per mode, measured on 2026-10-28 against the live API with the default parameters of each tool (compact JSON, UTF-8 bytes):

Call

Size

deepseek_search, count=3, need_content=false (default summary_chars)

3.7 KB

deepseek_search, count=3, need_content=false, summary_chars=0

2.3 KB

deepseek_search, count=3, need_content=true (default)

15.1 KB

deepseek_fetch, one documentation page (default max_chars)

20.9 KB

deepseek_fetch_many, 3 documentation pages

13.3 KB

deepseek_research, max_pages=3

20.1 KB

These are single samples, not guarantees: sizes vary with the query and the pages returned, and are bounded by max_chars_per_result, max_total_chars and the other character budgets, not by a fixed number.

Cost: DeepSeek bills Search and Fetch per successful request, not per returned result, so count does not change the price of a call. See the DeepSeek Search & Fetch guide for current prices, billing rules and limits; they may change and this project does not track them. A tool call that needs several upstream requests (for example deepseek_research fetching pages whose search content is missing, or deepseek_fetch_many) is billed for each of them, and rewrite=true additionally uses deepseek-flash tokens. Cache hits are not billed.

Cache and rate limiting

The cache and the limiter live in the server process and are not shared between processes.

Search

Fetch

Query rewrite

Cache TTL

5 min

30 min

24 h

Entry limit

128

128

1024

Size limit

16 MiB

32 MiB

1 MiB

Rate limit (sustained / burst)

10 / s, 20

5 / s, 10

not limited

  • Only successful, non-empty responses are cached. Errors are never cached.

  • Identical concurrent calls share one upstream request (single-flight); only the one that made the request pays a limiter token, and none of them reports cached: true.

  • refresh=true skips the cache read for that call and replaces the stored entry.

  • dedupe changes the upstream request (the search over-fetches), so dedupe=true and dedupe=false calls do not share a cache entry.

  • Cache hits and rewrite calls cost no limiter token. One logical call takes one token, retries included.

  • If a token would take longer than 5 s to become available, the call fails immediately with rate_limited_local rather than queueing indefinitely.

  • Transient failures (HTTP 429 and gateway 5xx) are retried once.

  • DEEPSEEK_MCP_CACHE=0 disables all caches.

Configuration

Variable

Required

Purpose

DEEPSEEK_API_KEY

yes

DeepSeek platform key

DEEPSEEK_BASE_URL

no

API base URL (default https://api.deepseek.com)

MCP_BEARER_TOKEN

HTTP only

token clients must send as Authorization: Bearer ...

DEEPSEEK_MCP_CACHE

no

1 (default) or 0 to disable caching

DEEPSEEK_MCP_LOG_LEVEL

no

stderr log level for the server, the MCP SDK and uvicorn: DEBUG, INFO, WARNING (default), ERROR, CRITICAL

DEEPSEEK_AUTH_JSON

no

path to a JSON file used as the key fallback (see Security)

.env.example lists the same variables. The server does not read .env files itself; export the variables or set them in your MCP client's env.

Security

Full policy and reporting instructions: SECURITY.md.

  • Static SSRF checks only. URLs are validated before the cache, the limiter or the network are touched: non-http(s) schemes, internal hostnames, literal private/loopback/link-local addresses and URLs with embedded credentials return ssrf_blocked. The server does not resolve DNS, and DeepSeek performs the actual fetch, so this is not network isolation.

  • Key handling. The key is sent only in the Authorization header to the configured API base URL. Keys, bearer tokens and similar secrets are redacted from error messages and notes.

  • HTTP transport requires the bearer token on every request (constant-time comparison, never logged).

  • No telemetry. The only outbound destination is the DeepSeek API.

  • Legacy opencode fallback. If DEEPSEEK_API_KEY is unset, the server reads the key from ~/.local/share/opencode/auth.json ({"deepseek": {"key": "..."}}), or from the file named by DEEPSEEK_AUTH_JSON. This exists only for opencode users; prefer the environment variable.

  • Tool inputs (queries, URLs) are sent to DeepSeek to do the work. Do not pass secrets in them.

Limitations

  • deepseek_fetch returns HTTP 404 for PDFs and Reddit and times out on some sites. Use deepseek_search with the page title or a site:-scoped query instead.

  • Fetch returns only title and content: no final URL, status code or publication date.

  • Fetch latency is DeepSeek's page render, not this server: an already rendered page returns in about 0.5 s, others take 3-10 s, and a missing page (HTTP 404) still takes 3-5 s before DeepSeek reports it. A 404 is not retried. deepseek_fetch_many runs up to 5 fetches at once, so a batch takes about as long as its slowest page; plan for that with larger batches.

  • Search and fetch only. No site mapping or crawling, no asynchronous jobs, a single provider (DeepSeek).

  • The cache and rate limiter are per process; running several server processes multiplies the effective rate.

  • Local rate limits are conservative defaults and do not replace DeepSeek's own quotas.

  • The HTTP transport is plain HTTP, stateless and JSON-only; there are no OAuth and no SSE streams.

Development

git clone https://github.com/radoxtech/deepseek-search-everywhere-mcp.git
cd deepseek-search-everywhere-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e ".[test,lint,http]" build twine

pytest -q                     # offline suite; no network, no key needed
ruff check .                  # lint
python -m build               # sdist + wheel in dist/
python -m twine check dist/*  # validate package metadata

The offline tests clear DEEPSEEK_* variables and point the key fallback at a nonexistent file, so they cannot reach the network. CI runs lint, tests and build on Python 3.11, 3.12 and 3.13.

See CONTRIBUTING.md for the contribution workflow and commit conventions.

Live tests

The live suite calls the real DeepSeek API end to end and uses deepseek-flash as an LLM judge to grade whether results are relevant and answer the question. It is excluded from the default run, skips itself without a key, and a full run costs a few cents at most (it also makes deepseek-flash judge calls).

cp .env.example .env          # then put your key in DEEPSEEK_API_KEY=
set -a && . ./.env && set +a  # export the variables; tests do not read .env themselves
pytest -m live

Judge scores and reasons are printed after the run. .env is git-ignored; never commit it.

Releasing

Versions follow Semantic Versioning and are automated with release-please from Conventional Commits. Everything runs in .github/workflows/release.yml:

  1. Every push to main runs release-please. It opens (or updates) a release PR that bumps the version in pyproject.toml, server.json and .release-please-manifest.json and prepends a section to CHANGELOG.md. Standard Semantic Versioning applies: fix bumps the patch version, feat bumps the minor, and breaking changes (feat!:) bump the major version; feat, fix, perf, refactor, docs and deps appear in the changelog.

  2. Merging the release PR makes release-please tag vX.Y.Z and create the GitHub Release.

  3. The same workflow run then builds the tagged commit, checks that the tag equals the versions in pyproject.toml and server.json, runs twine check and a clean-wheel smoke test, publishes to PyPI through Trusted Publishing (OIDC, no tokens), attaches the artifacts to the GitHub Release and updates the MCP Registry.

Publishing happens in the same workflow because tags and PRs created with GITHUB_TOKEN do not trigger other workflows.

Manual fallback: bump the version in pyproject.toml, server.json and .release-please-manifest.json (tests/test_version_sync.py checks the first two agree), update CHANGELOG.md, commit, and push a tag. The workflow then publishes and creates the GitHub Release itself.

git tag -a v2.0.0 -m "v2.0.0" && git push origin v2.0.0
bash scripts/smoke_package.sh   # optional local check: build, install into a clean venv, run the CLI

Running the workflow manually (workflow_dispatch) builds and verifies the package and publishes to TestPyPI only.

One-time repository setup:

  • Settings, Actions, General: enable "Allow GitHub Actions to create and approve pull requests" so release-please can open its PR.

  • Settings, Environments: create a pypi environment (and testpypi for manual runs); adding required reviewers there gates every PyPI publish.

  • On PyPI (and TestPyPI), add a trusted publisher for this repository with workflow release.yml and environment pypi (testpypi on TestPyPI).

Publishing to the MCP Registry manually

server.json describes the PyPI package for the MCP Registry. The README carries an mcp-name comment that the registry uses to verify package ownership. The release workflow does this automatically; to publish by hand:

python scripts/validate_server_json.py   # structural checks; also runs `mcp-publisher validate` if installed
mcp-publisher login github               # the io.github.radoxtech namespace requires GitHub authentication
mcp-publisher publish

Publish to PyPI first: the registry checks that the package version exists. release-please keeps pyproject.toml and server.json in step; tests/test_version_sync.py fails when they drift apart.

Changelog

See CHANGELOG.md for release notes.

License

MIT. Not affiliated with DeepSeek.

Available Tools

7 tools
deepseek_check_balanceA
Read-onlyIdempotent

Check DeepSeek account balance (CNY/USD) and in-memory session telemetry.

Verify account funds and monitor session usage (requests, cache hits, estimated cost). Do not use for search or retrieval (use deepseek_search or deepseek_fetch). Requires DEEPSEEK_API_KEY. Takes no arguments.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds genuinely new operational context: it requires DEEPSEEK_API_KEY and takes no arguments, and that telemetry is in-memory (session-scoped, likely not persisted). It stops short of noting that the balance portion makes an authenticated network call that can fail on missing/invalid keys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the primary verb+resource and kept to three short sentences. The second sentence partially restates the first ("Verify account funds and monitor session usage" vs the opening line), which is mild redundancy but also serves as the usage statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-argument read tool with an output schema, everything essential is present: purpose, auth prerequisite, arity, and routing away from siblings. The only soft spot is "in-memory session telemetry", which leaves ambiguous whose session is measured and when the counters reset.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so the baseline is 4. The description reinforces this with "Takes no arguments", which prevents an agent from hunting for a currency or session-id parameter that does not exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource pair ("Check DeepSeek account balance (CNY/USD)") plus a second explicit capability ("in-memory session telemetry"), and names the sibling tools it is not for. An agent can distinguish it from the deepseek_search/fetch family 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit positive context ("Verify account funds and monitor session usage") and an explicit exclusion with named alternatives: "Do not use for search or retrieval (use deepseek_search or deepseek_fetch)". Both when-to-use and when-not-to-use are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deepseek_deep_researchA
Read-onlyIdempotent

Execute multi-angle research on a topic and generate a cited briefing report.

Decomposes topic into subqueries, retrieves sources concurrently, and synthesizes a cited report [1], [2]. Use for deep topic synthesis. Do not use for simple lookups (use deepseek_search/deepseek_research) or reading known URLs (use deepseek_fetch).

Args: topic: Research subject, max 500 chars. max_queries: Subqueries to run (2-4, default 3). max_pages_per_query: Sources per subquery (1-5, default 3). lang: Language filter (e.g. 'en', 'pl'). dedupe: Collapse duplicates across subqueries (default True). refresh: Bypass response cache (default False). strip_boilerplate: Strip site UI text (default True).

NameRequiredDescriptionDefault
langNo
topicYes
dedupeNo
refreshNo
max_queriesNo
strip_boilerplateNo
max_pages_per_queryNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds real behavioral value beyond that: it discloses the internal pipeline (subquery decomposition, concurrent retrieval, citation markers [1],[2]) and the caching behavior implied by the refresh parameter. It stops short of stating cost, latency, or failure modes for a tool that fans out multiple network calls, which is the one remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a one-line purpose, then usage rules, then a compact Args block. Every line carries information — no restatement of the tool name, no filler prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, and the parameter section compensates fully for the 0% schema coverage. Purpose, routing, and per-argument semantics are all present for a 7-param tool, leaving nothing an agent would need to guess before calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the full burden and it does: all seven params are documented with meaning, ranges (topic max 500 chars, max_queries 2-4, max_pages_per_query 1-5), defaults (3, 3, True, False, True), and an example value for lang ('en', 'pl'). This is information the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: 'Execute multi-angle research on a topic and generate a cited briefing report.' The second sentence explains the mechanism (decompose into subqueries, concurrent retrieval, synthesized cited report), which distinguishes it from the plain search/fetch siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Use for deep topic synthesis. Do not use for simple lookups (use deepseek_search/deepseek_research) or reading known URLs (use deepseek_fetch).' Both exclusions and named alternatives are given, so nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deepseek_extractA
Read-onlyIdempotent

Extract structured JSON from a web page conforming to target fields or a schema.

Extracts specific entities or key-value data without returning full page text. Returns extracted JSON under 'data'. Do not use for general reading (use deepseek_fetch), nor for search or discovery (use deepseek_search).

Args: url: Absolute web page URL to extract from. fields: Target attribute names (e.g. ['price', 'specs']), exclusive with schema. schema: JSON Schema defining target structure, exclusive with fields. instruction: Optional extraction guidance. clean: Remove Markdown backslash escapes (default True). max_chars: Content cap before extraction (default 40000). refresh: Bypass cache and fetch page again (default False). strip_boilerplate: Remove site UI lines from text (default True).

NameRequiredDescriptionDefault
urlYes
cleanNo
fieldsNo
schemaNo
refreshNo
max_charsNo
instructionNo
strip_boilerplateNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld, and non-destructive, so the safety profile is covered. The description adds value beyond that: it states the result is returned under 'data', that full page text is not returned, that caching exists and can be bypassed via refresh, and that escapes/boilerplate are cleaned by default. Missing only rate limits, auth/cost behavior, and extraction failure semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and sibling routing are front-loaded in the first paragraph, followed by a compact Args list where each line carries distinct information. The only waste is echoing defaults already visible in the schema and one near-tautological parameter gloss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is not required, yet the description still tells the agent where the payload lives ('data'). Combined with the field/schema exclusivity rule and the cache/fetch controls, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden and does document all eight parameters with intent, not just names — notably the mutual exclusivity of fields and schema, which the schema does not express at all. Defaults are restated (clean, max_chars, refresh, strip_boilerplate), which is mildly redundant, and a couple of glosses are thin ('schema: JSON Schema defining target structure', 'instruction: Optional extraction guidance').

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb (extract), a specific resource (web page), and a specific output shape (structured JSON conforming to fields or a schema). It further scopes the tool negatively ('without returning full page text'), so an agent can distinguish it from deepseek_fetch and deepseek_search 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit exclusions are given with named alternatives: 'Do not use for general reading (use deepseek_fetch), nor for search or discovery (use deepseek_search).' This is exactly the when-not/alternative routing an agent needs, and it names two of the six siblings directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deepseek_fetchA
Read-onlyIdempotent

Fetch one known URL and return its title and Markdown content.

Retrieves full Markdown content for a known URL. Use when target URL is known. For multiple URLs use deepseek_fetch_many; for structured data use deepseek_extract; for search use deepseek_search. Returns 404 for PDFs/Reddit (use deepseek_search instead).

Args: url: Absolute http(s) URL, max 8192 characters. clean: Remove Markdown backslash escapes (default True). max_chars: Content cap after cleaning (default 20000). query: Query to extract ranked relevant snippets. section: 1-based index to read a specific document section. max_snippets: Max ranked snippets when query is set (default 3, 1-5). refresh: Bypass cache and fetch page again (default False). strip_boilerplate: Remove site UI lines from text (default True).

NameRequiredDescriptionDefault
urlYes
cleanNo
queryNo
refreshNo
sectionNo
max_charsNo
max_snippetsNo
strip_boilerplateNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely new behavioral context beyond them: caching with a refresh bypass, content caps, escape-cleaning, boilerplate stripping, and a concrete failure mode (404 on PDFs/Reddit). It stops short of describing pagination or what 'sections' look like structurally.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose and the routing sentence, then the arg list. The Args block is long but each entry earns its place given 0% schema coverage. Minor duplication between the opening line and the second sentence ('Fetch one known URL' / 'Retrieves full Markdown content for a known URL').

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, and the description states them anyway (title + Markdown). With 8 params, an open-world network dependency, and a known failure mode, the definition gives an agent nearly everything needed to call correctly. It could go slightly further on cache staleness semantics for refresh/section interplay.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it does: every one of the 8 params is documented with defaults and constraints (url absolute http(s) max 8192 chars, max_snippets 1-5, section 1-based, clean removes backslash escapes, max_chars applies after cleaning). That is materially more than the bare titles and defaults in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetch one known URL') and explicitly names the output ('its title and Markdown content'). The pairing with sibling names in the next sentence lets an agent distinguish deepseek_fetch from deepseek_fetch_many 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit selection condition ('Use when target URL is known') plus a per-alternative routing map: fetch_many for multiple URLs, extract for structured data, search for search. It even names a carve-out case (PDFs/Reddit return 404, use deepseek_search instead), which is exactly the kind of when-not guidance that prevents wrong selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deepseek_fetch_manyA
Read-onlyIdempotent

Fetch up to 10 known URLs concurrently and return each page's title and Markdown content.

Fetch multiple known URLs in parallel. Use when target URLs are known. Do not use for a single URL (use deepseek_fetch), nor for search/discovery (use deepseek_search). Skips blanks, deduplicates, and preserves order.

Args: urls: 1-10 absolute http(s) URLs, max 8192 characters each. max_chars_per_url: Content cap per page (default 4000). max_total_chars: Total content budget across all pages (default 20000). clean: Remove Markdown backslash escapes (default True). query: Query to extract ranked snippets across fetched pages. refresh: Bypass cache and fetch pages again (default False). strip_boilerplate: Remove site UI lines from text (default True). deadline: Max seconds before cancelling pending fetches (default 120s).

NameRequiredDescriptionDefault
urlsYes
cleanNo
queryNo
refreshNo
deadlineNo
max_total_charsNo
max_chars_per_urlNo
strip_boilerplateNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld/non-destructive, and the description still adds real behavior: blank-skipping, deduplication, order preservation, cache bypass via refresh, cancellation of pending fetches at the deadline, and per-page plus global content budgets. It stops short of saying what happens when individual URLs fail (partial results vs. whole-call error), which is the main behavioral gap for a concurrent fetch tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core statement and the use/do-not-use routing before the Args block, so an agent gets the decision-relevant information first. The opening two sentences are somewhat redundant ("Fetch up to 10 known URLs concurrently" / "Fetch multiple known URLs in parallel"), costing a little space without adding information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't explain return values, and it covers routing, all 8 parameters, budgets, caching, and timeout behavior for a moderately complex tool. The remaining unknown (per-URL failure semantics) is secondary to correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry all parameter meaning, and it does document all 8 including defaults and constraints (1–10 absolute http(s) URLs, 8192 chars each, default budgets). The weakest entry is `query`, described only as "extract ranked snippets across fetched pages," which doesn't make clear whether it changes the return shape or filters content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (fetch), resource (up to 10 known URLs concurrently), and even the return shape (each page's title and Markdown content). It explicitly contrasts itself with deepseek_fetch and deepseek_search, so an agent can distinguish it from siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit positive condition ("Use when target URLs are known") and two explicit exclusions with the named alternatives to use instead (single URL → deepseek_fetch, search/discovery → deepseek_search). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deepseek_researchA
Read-onlyIdempotent

Single-pass source gathering: search with page content and auto-fetch stub pages.

Gathers candidate sources for research. It does not iterate, refine the query or summarise: there is exactly one search and sources return raw content for the caller to synthesise.

Unlike deepseek_search (index-only), deepseek_research auto-fetches stub results in parallel for deep source gathering. Use when research requires complete documents rather than snippets.

Args: question: Search query, max 128 characters. max_pages: Results to use, 1-50 (default 5). per_page_chars: Cap per source (default 6000). total_chars: Budget across sources (default 30000). after: Date on or after (YYYY-MM-DD/YYYY). before: Date on or before (YYYY-MM-DD/YYYY). include_domains: Restrict domains (e.g. ['arxiv.org']). exclude_domains: Exclude domains (e.g. ['wikipedia.org']). lang: Language filter (e.g. 'pl', 'es', 'ja'). rewrite: Translate query via deepseek-flash (default False). dedupe: Collapse duplicate results (default True). refresh: Bypass response cache (default False). strip_boilerplate: Strip site UI text (default True).

NameRequiredDescriptionDefault
langNo
afterNo
beforeNo
dedupeNo
refreshNo
rewriteNo
questionYes
max_pagesNo
total_charsNo
per_page_charsNo
exclude_domainsNo
include_domainsNo
strip_boilerplateNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description still adds real value beyond that: exactly one search, no query refinement or summarization, raw content returned to the caller, parallel auto-fetch of stub pages, and cache-bypass via refresh. It stops short of anything on rate limits, failure/partial-result behavior, or what happens when stub fetches fail, so it is good but not fully transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The prose is front-loaded and tight — purpose, non-behavior, sibling contrast, then the parameter block. The only waste is mild redundancy in restating defaults (5, 6000, 30000, True/False) already present in the schema, though the added ranges and examples justify most of the repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and annotations cover the safety profile. What remains — single-pass semantics, raw-content contract, cache and dedupe behavior, and full parameter meaning — is all covered, so an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and there are 13 parameters, so the description carries the full burden — and it does, documenting every parameter with units and constraints ('max 128 characters', '1-50 (default 5)', date formats 'YYYY-MM-DD/YYYY', domain list examples, language codes). This is exactly the compensation the low coverage requires.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line gives a specific verb and resource ('Single-pass source gathering: search with page content and auto-fetch stub pages') and the second sentence scopes the behavior ('Gathers candidate sources for research'). It explicitly contrasts itself with the named sibling deepseek_search ('index-only'), so an agent can distinguish the two 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selection condition directly: 'Use when research requires complete documents rather than snippets,' and names the alternative (deepseek_search) that covers the snippet case. The 'does not iterate, refine the query or summarise' clause implicitly routes multi-pass work away from this tool, giving both a when and a when-not.

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.

  1. 10 tool updatesv2.0.1
    • Removeddeepseek_balance
    • Addeddeepseek_check_balance
    • Addeddeepseek_deep_research
    • Addeddeepseek_extract
    • Changeddeepseek_fetch3 fields changed
      • addedInput schema / properties / max_snippets
        Added value: +{
        +  "default": 3,
        +  "title": "Max Snippets",
        +  "type": "integer"
        +}
      • addedInput schema / properties / query
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Query"
        +}
      • addedInput schema / properties / section
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Section"
        +}
    • Changeddeepseek_fetch_many2 fields changed
      • addedInput schema / properties / deadline
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Deadline"
        +}
      • addedInput schema / properties / query
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Query"
        +}
    • Changeddeepseek_research4 fields changed
      • addedInput schema / properties / after
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "After"
        +}
      • addedInput schema / properties / before
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Before"
        +}
      • addedInput schema / properties / exclude_domains
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Exclude Domains"
        +}
      • addedInput schema / properties / include_domains
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Include Domains"
        +}
    • Addeddeepseek_search
    • Removeddeepseek_search_and_read
    • Removeddeepseek_web_search
  2. 5 tool updatesv1.0.0
    • Changeddeepseek_fetch1 field changed
      • addedInput schema / properties / strip_boilerplate
        Added value: +{
        +  "default": true,
        +  "title": "Strip Boilerplate",
        +  "type": "boolean"
        +}
    • Changeddeepseek_fetch_many1 field changed
      • addedInput schema / properties / strip_boilerplate
        Added value: +{
        +  "default": true,
        +  "title": "Strip Boilerplate",
        +  "type": "boolean"
        +}
    • Changeddeepseek_research4 fields changed
      • addedInput schema / properties / dedupe
        Added value: +{
        +  "default": true,
        +  "title": "Dedupe",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / lang
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Lang"
        +}
      • addedInput schema / properties / rewrite
        Added value: +{
        +  "default": false,
        +  "title": "Rewrite",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / strip_boilerplate
        Added value: +{
        +  "default": true,
        +  "title": "Strip Boilerplate",
        +  "type": "boolean"
        +}
    • Changeddeepseek_search_and_read2 fields changed
      • addedInput schema / properties / strip_boilerplate
        Added value: +{
        +  "default": true,
        +  "title": "Strip Boilerplate",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / summary_chars
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Summary Chars"
        +}
    • Changeddeepseek_web_search2 fields changed
      • addedInput schema / properties / strip_boilerplate
        Added value: +{
        +  "default": true,
        +  "title": "Strip Boilerplate",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / summary_chars
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Summary Chars"
        +}
  3. 6 tool updatesv0.2.0
    • First observeddeepseek_balance
    • First observeddeepseek_fetch
    • First observeddeepseek_fetch_many
    • First observeddeepseek_research
    • First observeddeepseek_search_and_read
    • First observeddeepseek_web_search

TDQS

A4.6/5.0

Scored across 7 tools

Disambiguation4/5

Each tool targets a distinct retrieval mode (search, single fetch, batch fetch, structured extraction, research passes, balance check) and descriptions explicitly disambiguate against siblings (e.g. 'Unlike deepseek_research...', 'Do not use for a single URL'). The only residual overlap is deepseek_research vs deepseek_deep_research, which differ mainly in autonomy rather than in surface inputs, so an agent could still hesitate between them.

Naming Consistency5/5

All tools use a uniform deepseek_ prefix followed by clear snake_case verb/noun tokens (search, check_balance, fetch, fetch_many, research, deep_research, extract). The pattern is predictable and scales cleanly.

Tool Count5/5

Seven tools is well within the sweet spot and each maps to a distinct capability tier (recovery/search, read, batch read, extract, research, deep research, account check). No tool feels redundant or bolted on.

Completeness4/5

The surface covers the full lifecycle from discovery through reading, structured extraction, and cited synthesis plus an operational balance check. Minor gap: deepseek_fetch explicitly 404s on PDFs/Reddit with no dedicated document handler, leaving a documented dead end that callers must reroute around.

Maintenance

ActivityNo data
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers