deepseek-mcp
Enables Claude Code to delegate bounded repository tasks to DeepSeek as a local sub-agent, handling exploration, routine changes, and test runs within a controlled workspace and budget.
README
deepseek-mcp
An MCP server that lets Claude Code delegate one bounded unit of repository work to DeepSeek as a local sub-agent.
Claude stays the orchestrator: it decides scope, architecture, and correctness. DeepSeek is an execution worker for the token-heavy part — exploring the repository, making routine or repetitive changes, and running the tests — inside a single authorized workspace and under hard budgets.
The point is to stop paying twice for the same context. If Claude reads a subsystem and then DeepSeek reads it again, nothing was saved; so the delegation decision belongs before the broad reads.
User
↓
Claude: plan + define goal/scope
↓
DeepSeek: inspect repo + read code + implement + test
↓
DeepSeek: compact structured summary
↓
Claude: review diff/results + final answer
DeepSeek is the primary repository worker; Claude is the orchestrator. Claude plans, makes the architectural and security calls, reviews the returned diff, and writes the final answer. DeepSeek does the repository work: exploring, Glob/Grep/ Read, understanding the code, implementing, testing, and routine fixes. Claude delegates before broadly reading source files, and DeepSeek discovers the relevant files itself inside the authorized scope and returns a compact structured summary — Claude never sends file contents.
Requires Python 3.11+ and a DeepSeek API key. One runtime dependency: the MCP
SDK. Everything else is the standard library. ripgrep is used for search when
present and a pure-Python scan is used when it is not.
1. Install
The package is not published to PyPI yet, so install it from a checkout. Install it once, globally — it is not a project dependency, and it works across every repository.
git clone https://github.com/giaminhgist/DeepSeek_MCP.git
cd DeepSeek_MCP
uv tool install . # recommended: isolated, and puts deepseek-mcp on PATH
# or
pipx install .
# or, into the current environment
pip install .
Confirm the console script resolves:
deepseek-mcp --version # -> deepseek-mcp 0.1.0
If the command is not found, the install directory is not on your PATH. With
uv, run uv tool update-shell and open a new shell.
deepseek-mcp with no arguments starts the MCP server on stdio. That is what
Claude Code runs; you would not normally invoke it yourself.
2. Set the API key
Get a key from https://platform.deepseek.com/. Never put it in a project repository. Export it from your shell profile:
export DEEPSEEK_API_KEY="sk-your-key-here" # ~/.bashrc, ~/.zshrc, …
# Windows PowerShell
setx DEEPSEEK_API_KEY "sk-your-key-here"
Then check the server can see it:
deepseek-mcp --check # prints a health report as JSON; exits 1 if unusable
--check prints "mode": "enabled" and "status": "ok" when the key is
readable. The key itself never appears in the report.
Three supported key sources, in precedence order:
DEEPSEEK_MCP_API_KEYorDEEPSEEK_API_KEYin the server environment.api_key_envin the user config file, naming a different environment variable to read.api_keyin the user config file — accepted, discouraged, and it produces a startup warning, because it puts the key on disk.
Everything else is optional; see Configuration reference.
The only other variable worth knowing up front is DEEPSEEK_MCP_WORKSPACE, which
pins the authorized project root instead of discovering it (see
Workspace).
3. Add the server to Claude Code
If DEEPSEEK_API_KEY is already exported in the environment Claude Code
inherits:
claude mcp add deepseek --scope user -- deepseek-mcp
If it is not — for example a desktop launch that does not read your shell profile — pass it explicitly:
claude mcp add deepseek --scope user -e DEEPSEEK_API_KEY=sk-your-key-here -- deepseek-mcp
--scope user registers it for every project. Use --scope local for the
current project only.
Equivalent hand-written configuration:
{
"mcpServers": {
"deepseek": {
"command": "deepseek-mcp",
"env": {
"DEEPSEEK_API_KEY": "sk-your-key-here"
}
}
}
}
Omit the env block entirely when the key is already in the inherited
environment. Do not commit a key into any repository file.
4. Verify the connection
claude mcp list # deepseek should be listed and connected
Then, inside Claude Code:
- run
/mcp—deepseekshould appear with its two tools; - ask Claude to call
deepseek_health. A working server answers withstatus: "ok",mode: "enabled", the defaultmodeland theallowed_modelsallowlist, the resolved workspace root, the enabled capabilities, the budget limits, and ausageobject with the worker's running totals for this server process.
With no key configured, the server still starts and still answers
deepseek_health — reporting status: "error", mode: "disabled" — so the
problem is diagnosable from inside Claude Code. It performs no work in that
state.
5. Troubleshooting
| Symptom | Cause and fix |
|---|---|
deepseek-mcp: command not found |
The install directory is not on PATH. uv tool update-shell, then open a new shell. Or point the MCP config command at the absolute path. |
claude mcp list shows the server as failed |
Run deepseek-mcp --check in a terminal. It prints the same diagnosis the server would report. |
deepseek_health returns mode: "disabled" |
No API key reached the server process. Check the errors field. Claude Code does not necessarily inherit your shell profile — pass the key with -e DEEPSEEK_API_KEY=… or an env block. |
Delegation returns status: "blocked" |
Policy refused the request before any API call: a mode asking for capabilities the server does not grant, verification commands in read_only mode, a model outside the allowed_models allowlist, or an invalid request field. The error field says which. |
Delegation returns status: "budget_exceeded" |
The unit of work was too large for the limits deepseek_health reports. Narrow the objective or raise the relevant budget. |
A Run command comes back refused |
The executable policy is an allowlist. See Command policy; add project-specific tools through commands.extra_allowed_executables. |
| The worker cannot read a file | Secret-bearing paths and .git internals are denied to every tool, and everything resolves inside one workspace root. Check workspace in the health report. |
| The workspace root is wrong | It is discovered by walking up from the directory Claude Code launched the server in. Set DEEPSEEK_MCP_WORKSPACE to pin it. |
DEEPSEEK_MCP_CONFIG does not exist at startup |
An explicitly pointed-at config file is missing. Fix the path or unset the variable; the server will not silently fall back to defaults. |
Logs go to stderr as event key=value records, never to stdout. Raise the detail
with DEEPSEEK_MCP_LOG_LEVEL=DEBUG, or send them to a file with
DEEPSEEK_MCP_LOG_FILE=/absolute/path.log.
The tool surface
Two tools, deliberately.
deepseek_health
Configuration and health: status, the default model and the allowed_models
allowlist, the authorized workspace root and how it was resolved, enabled
capabilities, budget limits, and a usage object with the worker's running
totals for this server process. No secrets. Use it to confirm the worker is
usable and to size a delegation before sending one.
delegate_to_deepseek
One bounded unit of work, as a structured contract rather than a prose blob:
| Field | Purpose |
|---|---|
objective |
The outcome required. Required. |
scope |
Workspace-relative globs the work belongs to. Restricts writes. |
constraints |
Only the project rules that matter for this task. |
acceptance_criteria |
Conditions that define success. |
verification |
Commands to run before finishing, as argv arrays. |
mode |
read_only, verify, or write. |
model |
DeepSeek model for this delegation only, e.g. deepseek-reasoner. Omit to use the server's configured model. If the server sets a model allowlist, a name outside it is refused as blocked before any API call. |
analysis |
Also return a repository map — important_files, architecture_notes, dependencies, suggested_scope, and risks — so you can plan a change without reading the repository yourself. Pairs naturally with mode="read_only" for a pure inspection pass. |
{
"objective": "Treat a None row as invalid and cover it with a test.",
"scope": ["src/importer/**", "tests/importer/**"],
"constraints": ["Do not change the public response schema."],
"acceptance_criteria": ["validate_row(None) returns False."],
"verification": [["pytest", "tests/importer", "-q"]],
"mode": "write"
}
The worker then loops on its own — glob, grep, read, edit, run, repair — and returns a compact result, never a transcript:
{
"status": "completed",
"summary": "Treated a None row as invalid and added a regression test.",
"changed_files": ["src/importer/validate.py"],
"created_files": ["tests/importer/test_none.py"],
"deleted_files": [],
"inspected_files": ["src/importer/__init__.py"],
"verification": [
{"argv": ["pytest", "tests/importer", "-q"], "exit_code": 0, "summary": "24 passed"}
],
"warnings": [],
"unresolved": [],
"assumptions": [],
"diff_stat": " src/importer/validate.py | 3 ++-",
"metrics": {
"turns": 7, "tool_calls": 12, "prompt_tokens": 18400,
"completion_tokens": 2100, "duration_seconds": 41.2,
"files_read": 4, "files_changed": 2, "compactions": 0
},
"session_usage": {
"delegations": 3, "turns": 19, "tool_calls": 31,
"prompt_tokens": 51200, "completion_tokens": 6400,
"total_tokens": 57600, "since": "server start"
},
"model": "deepseek-chat",
"analysis": {
"important_files": ["src/importer/validate.py"],
"architecture_notes": ["validate_row is the single entry point for row checks."],
"dependencies": ["src/importer/schema.py"],
"suggested_scope": ["src/importer/**", "tests/importer/**"],
"risks": ["Changing the None handling may affect callers that rely on the old behaviour."]
},
"debug_ledger": ["R src/importer/validate.py", "E src/importer/validate.py", "X pytest tests/importer -q"]
}
model is the model that actually ran the delegation, after per-task override
resolution. analysis is present only when the delegation asked for it, and
carries the five repository-map fields. debug_ledger is the compact
one-line-per-tool-call execution ledger, populated only when the server runs with
debug enabled. metrics reports this delegation's own token usage and shape;
session_usage carries the worker's running totals for this server process,
including this delegation — delegations, turns, tool_calls,
prompt_tokens, completion_tokens, total_tokens, and since (always the
literal "server start").
The counter behind usage and session_usage is in-memory and scoped to the
server process: it resets when the MCP server restarts, which is exactly what the
since field records. It is not persisted to disk. Only delegations that reached
the worker are counted — a request refused earlier (server disabled, an invalid
request field, or a model outside the allowed_models allowlist) never called a
model, so it does not increment delegations or any token count. total_tokens
is computed from its parts rather than stored, so it cannot drift.
Statuses: completed, partial, blocked, failed, budget_exceeded,
disabled. Expected failures — bad configuration, a refused path, a denied
command, an exhausted budget, a provider error — all come back as one of these
with a reason. A Python traceback never does.
Results carry conclusions, never raw Read/Grep/tool transcripts. The debug ledger is the compact ledger — one line per tool call — not tool output, even when debug is enabled.
Modes narrow, never widen
| Mode | Read & search | Run commands | Write files |
|---|---|---|---|
read_only |
yes | no | no |
verify |
yes | yes | no |
write |
yes | yes | yes, inside scope |
A mode is intersected with the server's configured capabilities. A request asking for more than the server grants is refused before any API call — it can never widen policy.
What the worker is not trusted with
Two things in the result do not come from the model:
- The changed-file list comes from watching the tools plus a
git statuscomparison against a snapshot taken before the run, so a user's pre-existing uncommitted edits are never reported as the worker's work. - The status. A claimed
completedis downgraded topartialif requested verification never ran or exited non-zero.failedandbudget_exceededare the server's verdicts and cannot be claimed by the worker at all.
Verify anyway. git status --short, git diff --stat, then read the changed
hunks in proportion to risk. completed is a claim, not proof.
Budgets
Every delegation is bounded, and the run stops with a structured reason rather
than overrunning: turns (24), tool calls (80), wall clock (15 min), output per
tool call (20,000 chars), Read window (250 lines), Grep matches (100), Glob
paths (300), and estimated active context (96,000 tokens).
Context is treated as a budgeted resource rather than a growing transcript. Above a threshold, old tool payloads are replaced by one-line entries from a deterministic execution ledger; if that is not enough, whole old turns are dropped, since the ledger still records what they did. The system prompt, the original task contract, the recent turns, and the ledger are always preserved. No extra model call is ever spent summarizing, and if the worker needs an evicted detail it reads the file again.
All limits are configurable and reported by deepseek_health.
Configuration reference
Settings marked reserved are validated at startup but not yet consumed.
Precedence
environment variable > user config file > built-in default
Model selection has one more level above that: a single delegation may name its own model, so the full order is
per-task model > environment variable > user config file > built-in default
The per-task model is the model parameter on delegate_to_deepseek. When the
server's allowed_models is non-empty it is an allowlist, and a request naming
anything else is refused as blocked before any API call — model choice narrows
to what the operator permitted, exactly like delegation modes narrow to the
server's capabilities.
A missing, malformed, or contradictory setting is an error. The server does not fall back to a broader workspace or a more permissive policy.
If configuration fails to load, the process still starts and still answers
deepseek_health, but reports status: "error", mode: "disabled", and does no
work. Run deepseek-mcp --check to see the same report on the command line.
Config file location
The user config file lives outside any project:
| Platform | Path |
|---|---|
| Linux/BSD | $XDG_CONFIG_HOME/deepseek-mcp/config.json, else ~/.config/deepseek-mcp/config.json |
| macOS | ~/.config/deepseek-mcp/config.json |
| Windows | %APPDATA%\deepseek-mcp\config.json |
DEEPSEEK_MCP_CONFIG overrides the path. If it is set and the file does not
exist, startup fails rather than silently using defaults. An absent config file
at the default location is fine; an empty file is fine; unknown keys are an
error.
Config file schema
Every key is optional.
{
"model": "deepseek-chat",
"allowed_models": ["deepseek-chat", "deepseek-reasoner"],
"base_url": "https://api.deepseek.com/v1",
"api_key_env": "DEEPSEEK_API_KEY",
"workspace": "/absolute/path/to/project",
"tools": {
"enabled": ["Read", "Glob", "Grep", "Edit", "Write", "Run"],
"max_write_bytes": 2000000,
"allow_secret_paths": false,
"secret_path_exceptions": []
},
"provider": {
"timeout_seconds": 120,
"max_retries": 3,
"retry_base_delay": 0.5,
"retry_max_delay": 8.0,
"temperature": 0.0,
"max_output_tokens": 4096
},
"budgets": {
"max_turns": 24,
"max_tool_calls": 80,
"max_wall_seconds": 900,
"max_tool_output_chars": 20000,
"read_window_lines": 250,
"max_grep_matches": 100,
"max_glob_paths": 300,
"max_context_tokens": 96000,
"compaction_threshold_ratio": 0.7
},
"commands": {
"default_timeout_seconds": 120,
"max_timeout_seconds": 600,
"extra_denied_executables": [],
"extra_allowed_executables": [],
"allow_unsafe_shell": false
},
"logging": { "level": "INFO", "file": null, "log_task_text": false },
"debug": false
}
An api_key key is accepted here but discouraged: it puts the key on disk and
produces a startup warning. Prefer api_key_env, which names the environment
variable to read instead.
allowed_models is an optional allowlist of model names a delegation may request.
When non-empty, the configured model must be in it (the settings contradict
each other otherwise), and a per-task model naming anything outside it is
refused as blocked before any API call. Empty means any well-formed model name
is accepted.
Credentials and endpoint
| Variable | Effect |
|---|---|
DEEPSEEK_MCP_API_KEY |
API key, highest precedence |
DEEPSEEK_API_KEY |
API key (default variable name; override with api_key_env) |
DEEPSEEK_MCP_MODEL, DEEPSEEK_MODEL |
Model name. DEEPSEEK_MCP_MODEL is preferred; DEEPSEEK_MODEL is the fallback. Default deepseek-chat |
DEEPSEEK_MCP_ALLOWED_MODELS |
Comma-separated allowlist of model names a delegation may request. Empty means any well-formed name. A per-task model outside it is refused as blocked |
DEEPSEEK_MCP_BASE_URL, DEEPSEEK_BASE_URL |
OpenAI-compatible base URL. Must be http(s). Default https://api.deepseek.com/v1 |
DEEPSEEK_MCP_CONFIG |
Config file path |
No API key means no work: startup reports the server as disabled.
Workspace
| Variable | Effect |
|---|---|
DEEPSEEK_MCP_WORKSPACE |
Absolute path to the authorized project root |
With no explicit workspace, the root is discovered by walking up from the
process working directory looking for .git, .hg, .svn, pyproject.toml,
package.json, go.mod, or Cargo.toml. If none is found, the working
directory itself is used and a warning is recorded.
An explicit workspace that is missing, unreadable, not a directory, relative, or the filesystem root is a startup error. It never degrades to the working directory. The server does not need to live inside your project, and it never modifies a project to activate itself.
Tools
| Variable | Effect |
|---|---|
DEEPSEEK_MCP_ENABLED_TOOLS |
Comma-separated list from Read, Glob, Grep, Edit, Write, Run, NotebookEdit. Case-insensitive. Read is mandatory. Unknown names are an error |
DEEPSEEK_MCP_MAX_WRITE_BYTES |
Write size ceiling, and the largest existing file the worker will overwrite |
DEEPSEEK_MCP_ALLOW_SECRET_PATHS |
Off by default: .env, .env.*, *.pem, *.key, id_rsa, .netrc, .ssh/, .aws/ and similar are denied to every tool |
Default enabled tools are everything except NotebookEdit. NotebookEdit is a
recognised name with no implementation yet, so enabling it is a startup error
rather than a tool the worker is offered and cannot use. Read is mandatory.
.git, .hg and .svn internals are never readable or writable through the
filesystem tools; use a read-only git command through Run instead.
Budget limits
All enforced per delegation, and reported by deepseek_health so Claude can size
a delegation before sending it.
| Variable | Default | Effect |
|---|---|---|
DEEPSEEK_MCP_MAX_TURNS |
24 | Provider calls per delegation |
DEEPSEEK_MCP_MAX_TOOL_CALLS |
80 | Tool executions per delegation |
DEEPSEEK_MCP_MAX_WALL_SECONDS |
900 | Total wall clock; also clamps command timeouts |
DEEPSEEK_MCP_MAX_TOOL_OUTPUT_CHARS |
20000 | Per tool result, keeping head and tail |
DEEPSEEK_MCP_READ_WINDOW_LINES |
250 | Lines per Read, and its hard ceiling |
DEEPSEEK_MCP_MAX_GREP_MATCHES |
100 | Matches per Grep, and its hard ceiling |
DEEPSEEK_MCP_MAX_GLOB_PATHS |
300 | Paths per Glob |
DEEPSEEK_MCP_MAX_CONTEXT_TOKENS |
96000 | Hard ceiling on estimated active context |
DEEPSEEK_MCP_COMPACTION_THRESHOLD_RATIO |
0.7 | Fraction of the ceiling that triggers compaction |
Exceeding a budget ends the delegation with status: "budget_exceeded" and a
reason, after reporting whatever work already landed.
Provider
| Variable | Default | Effect |
|---|---|---|
DEEPSEEK_MCP_REQUEST_TIMEOUT_SECONDS |
120 | Per-request timeout, clamped to the remaining wall budget |
DEEPSEEK_MCP_MAX_RETRIES |
3 | Retries after the first attempt, transient failures only |
DEEPSEEK_MCP_RETRY_BASE_DELAY |
0.5 | Exponential backoff base, with jitter |
DEEPSEEK_MCP_RETRY_MAX_DELAY |
8.0 | Backoff cap |
DEEPSEEK_MCP_TEMPERATURE |
0.0 | Sampling temperature |
DEEPSEEK_MCP_MAX_OUTPUT_TOKENS |
4096 | Per-turn completion cap |
Timeouts, connection failures, 429 and 5xx are retried. A 4xx surfaces
immediately, because retrying a bad key or a bad request only wastes time.
Redirects are refused outright so the Authorization header cannot be replayed
to another host.
Command policy
| Variable | Default | Effect |
|---|---|---|
DEEPSEEK_MCP_COMMAND_TIMEOUT_SECONDS |
120 | Default per-command timeout |
DEEPSEEK_MCP_MAX_COMMAND_TIMEOUT_SECONDS |
600 | Ceiling the worker cannot raise |
DEEPSEEK_MCP_ALLOW_UNSAFE_SHELL |
false | Reserved. Raw shell execution is not implemented; this setting grants nothing |
Run executes an argv array with shell=False. The executable must be on an
allowlist, and dangerous subcommands are refused structurally. Use the config
file's commands.extra_allowed_executables to add a project-specific tool, and
extra_denied_executables to remove one. An extra allow entry cannot re-enable a
hard-denied program.
Refused by default: privilege escalation, package installation, publishing,
network utilities, shells and inline-code interpreters, destructive filesystem
operations, in-place editors, and mutating or remote git subcommands. Read-only
git (status, diff, log, show, ls-files, rev-parse, blame, …) is
allowed.
General-purpose file readers such as cat, head and grep are deliberately
not allowlisted: they would be a one-command bypass of the secret-path deny
list that Read, Glob and Grep enforce. Add one back through
extra_allowed_executables only if you accept that.
Logging
| Variable | Effect |
|---|---|
DEEPSEEK_MCP_LOG_LEVEL |
DEBUG, INFO, WARNING, ERROR, CRITICAL. Default INFO |
DEEPSEEK_MCP_LOG_FILE |
Absolute path. Created with 0600 where the platform supports it |
DEEPSEEK_MCP_LOG_TASK_TEXT |
Reserved. Opt-in task-text logging. Off by default and not yet consumed |
DEEPSEEK_MCP_DEBUG |
Reserved. Debug detail in results. Not yet consumed |
Delegation logging is metadata only: event name, status, mode, turn and tool-call counts, token counts, duration, and file counts. No task text, file contents, command output, or prompt bodies. Logs go to stderr, never stdout — stdout carries MCP protocol traffic only. The API key is scrubbed from every record as a backstop.
Security posture
Read this section before deciding what to point the worker at.
The protections described here are unchanged by the model-selection and analysis features: bounded context with compaction, the workspace sandbox, the command allowlist, no commit or push, no package installation or network access by default, and a structured result carrying token and tool metrics.
What is enforced, in code:
- Every path resolves against one workspace root. Symlinks are followed first and the result is what gets validated, so a link out of the tree is refused. Write targets have their parent directory revalidated immediately before the write.
- An explicitly configured workspace that is missing or unusable is a startup error. It never silently falls back to a broader directory.
- Secret-bearing paths (
.env,.env.*,*.pem,*.key,id_rsa,.netrc,.ssh/,.aws/, and similar) and.git/.hg/.svninternals are denied to every tool, and are omitted from search results rather than merely unreadable. - A delegation's
scoperestricts writes. Reads stay open across the workspace, because the worker has to explore to do its job. Runusesshell=False. There is no shell, so&&,|,$(...)and>arrive as literal argument text and cannot chain a second command. The executable must be on an allowlist, dangerous subcommands are refused structurally over argv, absolute path arguments must land inside the workspace, and an argument naming an existing denied path is refused.- Package installation, publishing, network utilities, privilege escalation, and
mutating or remote git subcommands are refused by default. So are
general-purpose file readers such as
catandgrep, which would otherwise be a one-command bypass of the secret-path deny list. - Subprocesses receive an environment with credentials stripped, so the worker's own API key cannot surface in command output or a log.
- Writes are atomic (temp file, fsync, rename), so an interrupted write leaves the
original file intact.
Editcan require the SHA-256 thatReadreturned, so a stale edit is refused rather than applied. - The system prompt states that repository content is data, not instruction — and the limits above are enforced server-side, so a file that tells the worker to ignore its instructions cannot grant it anything.
- Logs are metadata only by default: event, status, counts, durations. No task text, file contents, command output, or prompt bodies. The API key is scrubbed from every record as a backstop.
What this is not: OS-level adversarial sandboxing.
This is application-level policy. It bounds the category of action a confused, mistaken, or prompt-injected worker can take. It is not a containment boundary against a determined adversary, and the two are not equivalent.
Concretely:
- An allowed test runner executes your project's code.
pytestimports the repository;make testruns whatever the Makefile says. Anything reachable that way is reachable, including files the path policy would have refused. - There is no process, filesystem, or network isolation — no container, no bubblewrap or seccomp, no macOS sandbox profile, no Windows job object, no network namespace. A command that is permitted runs with the same privileges as the server process.
- The deny lists are structural rather than exhaustive. They are the reason the executable policy is an allowlist: unknown programs are refused instead of assumed safe.
Do not point this at a repository you would not run tests from, and do not treat it as a substitute for reviewing the diff.
Known limitations
NotebookEditis a recognised tool name with no implementation. Enabling it is a startup error rather than a tool the worker is offered and cannot use.commands.allow_unsafe_shellis validated but does nothing; there is no raw shell execution.- The worker cannot delete files. There is no delete tool, and
rmis refused. - No OS-level sandbox, as above.
- The context estimate is a character heuristic, calibrated upward by the provider's reported usage. It is deliberately conservative, not exact.
- Search behaviour differs slightly between the
ripgrepand pure-Python engines, because the regex dialects differ. The engine used is named in every result. - Windows is supported and tested in CI, but process-group termination on timeout is best-effort there compared to POSIX.
- One delegation at a time per call. There are no background jobs, no persistent worker memory, and no automatic git commit or push.
Development
uv venv && uv pip install -e ".[dev]"
python -m pytest # the full suite; no API key and no network needed
python -m ruff check .
python -m ruff format --check .
python -m mypy
The test suite never calls a paid API: a scripted fake provider stands in, and the MCP integration tests drive a real server subprocess over stdio against temporary git repositories.
phases/ holds the implementation sequence this server was built from, kept for
reference.
GLOBAL_CLAUDE.md is not part of this codebase. It is a user-level Claude Code
instruction file describing when to delegate — copy it to ~/.claude/CLAUDE.md,
or merge it into the one you already have.
License
MIT.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。