Deepseek MCP Server
Summary: Use DeepSeek models through MCP for chat, code/content completion, multi-turn sessions, structured outputs, and cost/usage tracking.
Chat with
deepseek-flashordeepseek-v4-prousing 1M context, optional thinking mode, streaming, JSON mode, and schema-validated JSON.Use function calling with up to 128 tool definitions and send tool results back in conversations.
Continue conversations across requests with
session_id, and list, delete, or clear sessions viadeepseek_sessions.Run fill-in-the-middle code/content completion with
deepseek_fim, including optional suffix and stop sequences.Benefit from automatic cost tracking with peak/off-peak pricing, token/cache breakdowns, model fallback, and circuit-breaker resilience.
Query server resources for available models, configuration, and real-time usage statistics.
Use 12 built-in prompt templates for debugging, code review, research, planning, proofs, function calling, and more.
Connect via local stdio, self-hosted HTTP, Docker, or the hosted BYOK remote endpoint.
2.4.0 follows DeepSeek's V4.1 rename. The default model is now
deepseek-flash(V4.1 Flash), next todeepseek-v4-pro. Both have a 1M-token context window and optional chain-of-thought thinking.deepseek-v4-flash,deepseek-chatanddeepseek-reasonerkeep working as legacy names and are sent asdeepseek-flash, so existing configs need no change.
Quick Start
Remote (No Install)
Use the hosted endpoint directly — no npm install, no Node.js required. Bring your own DeepSeek API key:
Claude Code:
claude mcp add --transport http deepseek \
https://deepseek-mcp.tahirl.com/mcp \
--header "Authorization: Bearer YOUR_DEEPSEEK_API_KEY"Cursor / Windsurf / VS Code:
{
"mcpServers": {
"deepseek": {
"url": "https://deepseek-mcp.tahirl.com/mcp",
"headers": {
"Authorization": "Bearer ${DEEPSEEK_API_KEY}"
}
}
}
}Local (stdio)
Claude Code:
claude mcp add -s user deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-hereGemini CLI:
gemini mcp add deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-hereScope options (Claude Code):
-s user: Available in all your projects (recommended)-s local: Only in current project (default)-s project: Project-specific.mcp.jsonfile
Get your API key: https://platform.deepseek.com
Related MCP server: DeepSeek MCP Sample
Features
DeepSeek V4.1 Flash and V4 Pro:
deepseek-flashanddeepseek-v4-pro, both with 1M context and optional chain-of-thought thinking modeMulti-Turn Sessions: Conversation context preserved across requests via
session_idparameterModel Fallback & Circuit Breaker: Automatic fallback between models with circuit breaker protection against cascading failures
MCP Resources:
deepseek://models,deepseek://config,deepseek://usage— query model info, config, and usage statsThinking Mode: Enable chain-of-thought reasoning on either model with
thinking: {type: "enabled"}JSON Output Mode: Structured JSON responses with
json_mode: trueSchema-Validated JSON: Pass a
response_schemaand the server validates the output against it, with bounded repair retries and a ReDoS guard on schema patternsFunction Calling: OpenAI-compatible tool use with up to 128 tool definitions
Fill-in-the-Middle (FIM): Code and content completion between a prefix and suffix via the
deepseek_fimtoolCache-Aware Cost Tracking: Automatic cost calculation with cache hit/miss breakdown, priced at the peak or off-peak rate that applied when the request ran
Session Management Tool: List, delete, and clear sessions via
deepseek_sessionstoolConfigurable: Environment-based configuration with validation
12 Prompt Templates: Templates for debugging, code review, function calling, and more
Streaming Support: Real-time response generation
Multimodal Ready: Content part types for text + image input (enable with
ENABLE_MULTIMODAL=true)Remote Endpoint: Hosted at
deepseek-mcp.tahirl.com/mcp— BYOK (Bring Your Own Key), no install neededHTTP Transport: Self-hosted remote access via Streamable HTTP with
TRANSPORT=httpDocker Ready: Multi-stage Dockerfile with health checks for containerized deployment
Tested: 366 tests, ~92% line coverage
Type-Safe: Full TypeScript implementation
MCP Compatible: Works with any MCP-compatible CLI (Claude Code, Gemini CLI, etc.)
Installation
Prerequisites
Node.js 22+
A DeepSeek API key (get one at https://platform.deepseek.com)
Manual Installation
If you prefer to install manually:
npm install -g @arikusi/deepseek-mcp-serverFrom Source
Clone the repository
git clone https://github.com/arikusi/deepseek-mcp-server.git
cd deepseek-mcp-serverInstall dependencies
npm installBuild the project
npm run buildUsage
Once configured, your MCP client will have access to deepseek_chat, deepseek_fim, and deepseek_sessions tools, plus 3 MCP resources.
Example prompts:
"Use DeepSeek to explain quantum computing"
"Ask DeepSeek Reasoner to solve: If I have 10 apples and buy 5 more..."Your MCP client will automatically call the deepseek_chat tool.
Manual Configuration (Advanced)
If your MCP client doesn't support the add command, manually add to your config file:
{
"mcpServers": {
"deepseek": {
"command": "npx",
"args": ["@arikusi/deepseek-mcp-server"],
"env": {
"DEEPSEEK_API_KEY": "your-api-key-here"
}
}
}
}Config file locations:
Claude Code:
~/.claude.json(add toprojects["your-project-path"].mcpServerssection)Other MCP clients: Check your client's documentation for config file location
Available Tools
deepseek_chat
Chat with DeepSeek AI models with automatic cost tracking and function calling support.
Parameters:
messages(required): Array of conversation messagesrole: "system" | "user" | "assistant" | "tool"content: Message texttool_call_id(optional): Required for tool role messages
model(optional): "deepseek-flash" (default) or "deepseek-v4-pro". The legacy names "deepseek-v4-flash", "deepseek-chat" and "deepseek-reasoner" are still accepted and resolve to deepseek-flash (reasoner always thinks); prefer "deepseek-flash".temperature(optional): 0-2, controls randomness (default: 1.0). Ignored when thinking mode is enabled.max_tokens(optional): Maximum tokens to generate (both models support up to 384000)stream(optional): Enable streaming mode (default: false)tools(optional): Array of tool definitions for function calling (max 128)tool_choice(optional): "auto" | "none" | "required" |{type: "function", function: {name: "..."}}thinking(optional): Toggle thinking mode,{type: "enabled"}to reason or{type: "disabled"}for a fast answer (non-thinking is the default)reasoning_effort(optional): "high" (default) or "max", applies only while thinking mode is activejson_mode(optional): Enable JSON output mode (supported by both models)response_schema(optional): A JSON Schema to validate the model output against. Implies JSON output. The server validates the parsed result and, on failure, issues up toRESPONSE_SCHEMA_MAX_RETRIESrepair retries (default 2, set 0 to disable) that feed the validation error back to the model. Schema regex patterns are screened for ReDoS and an unsafe pattern is rejected up front.session_id(optional): Session ID for multi-turn conversations. Previous context is automatically prepended.
Response includes:
Content with formatting (recovered as clean JSON when JSON output is requested)
Function call results (if tools were used)
Request information (tokens, model, cost in USD)
structuredContent.request: a self-contained per-request usage and cost summary (token counts, cache hit/miss,cost_usd, and thepricing_tierit was priced at), aggregated across any repair retriesstructuredContent.effectiveandfallback: what was actually sent after alias/thinking resolution, and any silent model fallback that firedstructuredContent.schema: whenresponse_schemais used,{valid, attempts, error?};json_parse_errorwhen JSON output could not be recovered
Example:
{
"messages": [
{
"role": "user",
"content": "Explain the theory of relativity in simple terms"
}
],
"model": "deepseek-flash",
"temperature": 0.7,
"max_tokens": 1000
}Reasoning Example (deepseek-flash with thinking enabled):
{
"messages": [
{
"role": "user",
"content": "If I have 10 apples and eat 3, then buy 5 more, how many do I have?"
}
],
"model": "deepseek-flash",
"thinking": { "type": "enabled" }
}Thinking mode returns the chain-of-thought in <thinking> tags followed by the final answer.
DeepSeek V4 Pro Example (hardest tasks):
{
"messages": [
{
"role": "user",
"content": "Prove that the square root of 2 is irrational."
}
],
"model": "deepseek-v4-pro",
"thinking": { "type": "enabled" }
}Function Calling Example:
{
"messages": [
{
"role": "user",
"content": "What's the weather in Istanbul?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
}
},
"required": ["location"]
}
}
}
],
"tool_choice": "auto"
}When the model decides to call a function, the response includes tool_calls with the function name and arguments. You can then send the result back using a tool role message with the matching tool_call_id.
Thinking Mode Example:
{
"messages": [
{
"role": "user",
"content": "Analyze the time complexity of quicksort"
}
],
"model": "deepseek-flash",
"thinking": { "type": "enabled" }
}When thinking mode is enabled, temperature and top_p are automatically ignored.
JSON Output Mode Example:
{
"messages": [
{
"role": "user",
"content": "Return a json object with name, age, and city fields for a sample user"
}
],
"model": "deepseek-flash",
"json_mode": true
}JSON mode ensures the model outputs valid JSON. Include the word "json" in your prompt for best results. Supported by all models.
Schema-Validated JSON Example:
{
"messages": [
{
"role": "user",
"content": "Classify this review sentiment as json: \"Absolutely loved it\""
}
],
"model": "deepseek-flash",
"response_schema": {
"type": "object",
"properties": {
"sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"] },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 }
},
"required": ["sentiment", "confidence"],
"additionalProperties": false
}
}The server validates the parsed output against the schema. If it does not match, it retries up to RESPONSE_SCHEMA_MAX_RETRIES times (default 2), feeding the validation error back to the model, and returns the first schema-valid object. A persistent mismatch is surfaced as structuredContent.schema.valid = false rather than a silently coerced answer. Regex patterns in the schema are screened for catastrophic backtracking (ReDoS); an unsafe pattern is rejected up front as an invalid schema.
Multi-Turn Session Example:
{
"messages": [
{
"role": "user",
"content": "What is the capital of France?"
}
],
"session_id": "my-session-1"
}Use the same session_id across requests to maintain conversation context. Messages are stored in memory and prepended automatically. In HTTP transport each connected MCP session has its own isolated session store — a session_id created by one HTTP client is not visible to another (see HTTP Transport below).
deepseek_fim
Fill-in-the-Middle completion. You give a prompt (the prefix) and an optional suffix, and the model completes the text in between. It is built for code completion and content infilling rather than conversation. FIM runs on DeepSeek's Beta endpoint in non-thinking mode, and the API caps output at 4096 tokens.
Parameters:
prompt(required): The prefix text before the gap. For code completion, this is the code up to the cursor.suffix(optional): The text after the gap. The model fills the space betweenpromptandsuffix.model(optional): "deepseek-flash" (default) or "deepseek-v4-pro". The legacy names "deepseek-v4-flash", "deepseek-chat" and "deepseek-reasoner" are still accepted and resolve to deepseek-flash (FIM has no thinking mode).max_tokens(optional): Maximum tokens to generate, up to 4096.temperature(optional): 0-2, controls randomness (default: 1.0).stop(optional): A stop string or an array of up to 16 stop strings.
Response includes:
The completion text
Request information (tokens, model, cost in USD)
Structured data with
text,usage,finish_reason,cost_usdandpricing_tierfields
Example (code completion):
{
"prompt": "def fib(n):\n if n < 2:\n return n\n return ",
"suffix": "\n\nprint(fib(10))",
"model": "deepseek-flash",
"max_tokens": 64
}The model returns the missing middle, e.g. fib(n-1) + fib(n-2), using both the prefix and the suffix as context. Available on both the npm/stdio server and the hosted worker endpoint.
deepseek_sessions
Manage conversation sessions.
Parameters:
action(required): "list" | "clear" | "delete"session_id(optional): Required when action is "delete"
Examples:
{"action": "list"}
{"action": "delete", "session_id": "my-session-1"}
{"action": "clear"}Available Resources
MCP Resources provide read-only data about the server:
Resource URI | Description |
| Available models with capabilities, context limits, and pricing |
| Current server configuration (API key masked) |
| Real-time usage statistics (requests, tokens, costs, sessions) |
Model Fallback & Circuit Breaker
When a model fails with a retryable error (429, 503, timeout), the server automatically falls back to the other model:
deepseek-flashfails → triesdeepseek-v4-prodeepseek-v4-profails → triesdeepseek-flash
The legacy names (which resolve to deepseek-flash) fall back to deepseek-v4-pro.
The circuit breaker protects against cascading failures:
After
CIRCUIT_BREAKER_THRESHOLDconsecutive failures (default: 5), the circuit opens (fast-fail mode)After
CIRCUIT_BREAKER_RESET_TIMEOUTms (default: 30000), it enters half-open state and sends a probe requestIf the probe succeeds, the circuit closes and normal operation resumes
Fallback can be disabled with FALLBACK_ENABLED=false.
Available Prompts
Prompt templates (12 total):
Core Reasoning
debug_with_reasoning: Debug code with step-by-step analysis
code_review_deep: Comprehensive code review (security, performance, quality)
research_synthesis: Research topics and create structured reports
strategic_planning: Create strategic plans with reasoning
explain_like_im_five: Explain complex topics in simple terms
Advanced
mathematical_proof: Prove mathematical statements rigorously
argument_validation: Analyze arguments for logical fallacies
creative_ideation: Generate creative ideas with feasibility analysis
cost_comparison: Compare LLM costs for tasks
pair_programming: Interactive coding with explanations
Function Calling
function_call_debug: Debug function calling issues with tool definitions and messages
create_function_schema: Generate JSON Schema for function calling from natural language
Each prompt is optimized for thinking mode (deepseek-flash with thinking: {type: "enabled"}) to provide detailed reasoning.
Models
Both models have a 1M-token context window, up to 384K output tokens, and support function calling, JSON mode, and optional chain-of-thought thinking. They are non-thinking by default here for fast responses; enable reasoning with thinking: {type: "enabled"}.
DeepSeek bills by time of day. Peak is 01:00-04:00 and 06:00-10:00 UTC, Monday to Friday, and costs twice the off-peak rate; every other hour, including weekends, is off-peak. The cost this server reports uses whichever rate applied when the request ran. Prices below are USD per 1M tokens, from DeepSeek's pricing page as of 2026-10-23.
deepseek-flash (default)
Model: DeepSeek-V4.1-Flash-1017
Best for: General conversations, coding, content generation, agent loops
Context: 1M tokens
Max Output: 384K tokens
Off-peak: $0.003 cache hit, $0.15 cache miss, $0.60 output
Peak: $0.006 cache hit, $0.30 cache miss, $1.20 output
deepseek-v4-pro
Model: DeepSeek-V4-Pro-0813
Best for: Hard multi-step tasks where you want the larger model
Context: 1M tokens
Max Output: 384K tokens
Off-peak: $0.022 cache hit, $0.66 cache miss, $1.98 output
Peak: $0.044 cache hit, $1.32 cache miss, $3.96 output
DeepSeek's own benchmarks put V4.1 Flash ahead of V4 Pro, so Flash is the better default for most work.
Legacy names
deepseek-v4-flash, deepseek-chat and deepseek-reasoner are still accepted and resolve to deepseek-flash (chat = non-thinking, reasoner = thinking). DeepSeek retired the models behind them and serves those names with V4.1 Flash anyway, so this server sends deepseek-flash on the wire. deepseek-chat and deepseek-reasoner will be removed in the next major release. New setups should use deepseek-flash or deepseek-v4-pro.
Configuration
The server is configured via environment variables. All settings except DEEPSEEK_API_KEY are optional.
Variable | Default | Description |
| (required) | Your DeepSeek API key |
|
| Custom API endpoint |
|
| Default model for requests |
|
| Show cost info in responses |
|
| Request timeout in milliseconds |
|
| Maximum retry count for failed requests |
|
| Skip startup API connection test |
|
| Maximum message content length (characters) |
|
| Session time-to-live in minutes |
|
| Maximum number of concurrent sessions |
|
| Enable automatic model fallback on errors |
|
| Consecutive failures before circuit opens |
|
| Milliseconds before circuit half-opens |
|
| Max messages per session (sliding window) |
|
| Repair retries when a |
|
| Enable multimodal (image) input support |
|
| Transport mode: |
|
| HTTP server port (when TRANSPORT=http) |
|
| Bind address for HTTP transport. Loopback by default so a fresh run is not exposed. Set to |
| (unset) | When set, |
| (unset) | Comma-separated list of allowed |
|
| Set to |
Example with custom config:
claude mcp add -s user deepseek npx @arikusi/deepseek-mcp-server \
-e DEEPSEEK_API_KEY=your-key \
-e SHOW_COST_INFO=false \
-e REQUEST_TIMEOUT=30000Development
Project Structure
deepseek-mcp-server/
├── worker/ # Cloudflare Worker (remote BYOK endpoint)
│ ├── src/index.ts # Worker entry point
│ ├── wrangler.toml # Cloudflare config
│ └── package.json
├── src/
│ ├── index.ts # Entry point, bootstrap
│ ├── server.ts # McpServer factory (auto-version)
│ ├── deepseek-client.ts # DeepSeek API wrapper (circuit breaker + fallback)
│ ├── config.ts # Centralized config with Zod validation
│ ├── cost.ts # Cost calculation and formatting
│ ├── schemas.ts # Zod input validation schemas
│ ├── types.ts # TypeScript types + type guards
│ ├── errors.ts # Custom error classes
│ ├── session.ts # In-memory session store (multi-turn)
│ ├── circuit-breaker.ts # Circuit breaker pattern
│ ├── usage-tracker.ts # Usage statistics tracker
│ ├── transport-http.ts # Streamable HTTP transport (Express)
│ ├── tools/
│ │ ├── deepseek-chat.ts # deepseek_chat tool (sessions + fallback)
│ │ ├── deepseek-fim.ts # deepseek_fim tool (fill-in-the-middle)
│ │ ├── deepseek-sessions.ts # deepseek_sessions tool
│ │ └── index.ts # Tool registration aggregator
│ ├── resources/
│ │ ├── models.ts # deepseek://models resource
│ │ ├── config.ts # deepseek://config resource
│ │ ├── usage.ts # deepseek://usage resource
│ │ └── index.ts # Resource registration aggregator
│ └── prompts/
│ ├── core.ts # 5 core reasoning prompts
│ ├── advanced.ts # 5 advanced prompts
│ ├── function-calling.ts # 2 function calling prompts
│ └── index.ts # Prompt registration aggregator
├── dist/ # Compiled JavaScript
├── llms.txt # AI discoverability index
├── llms-full.txt # Full docs for LLM context
├── vitest.config.ts # Test configuration
├── package.json
├── tsconfig.json
└── README.mdBuilding
npm run buildWatch Mode (for development)
npm run watchTesting
# Run all tests
npm test
# Watch mode
npm run test:watch
# With coverage report
npm run test:coverageTesting Locally
# Set API key
export DEEPSEEK_API_KEY="your-key"
# Run the server
npm startThe server will start and wait for MCP client connections via stdio.
Remote Endpoint (Hosted)
A hosted BYOK (Bring Your Own Key) endpoint is available at:
https://deepseek-mcp.tahirl.com/mcpSend your DeepSeek API key as Authorization: Bearer <key>. No server-side API key stored — your key is used directly per request. Powered by Cloudflare Workers (global edge, zero cold start).
Note: Thinking mode may take over 30 seconds for complex queries. Some MCP clients (e.g. Claude Code) have built-in tool call timeouts that may interrupt long-running requests. When latency matters, the default non-thinking mode is recommended.
# Test health
curl https://deepseek-mcp.tahirl.com/health
# Test MCP (requires auth)
curl -X POST https://deepseek-mcp.tahirl.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":1}'HTTP Transport (Self-Hosted)
Run your own HTTP endpoint:
TRANSPORT=http HTTP_PORT=3000 DEEPSEEK_API_KEY=your-key node dist/index.jsTest the health endpoint:
curl http://localhost:3000/healthThe MCP endpoint is available at POST /mcp (Streamable HTTP protocol).
Securing the endpoint (read before exposing it). In self-hosted HTTP mode the
server holds your DEEPSEEK_API_KEY and uses it for every deepseek_chat call.
Anyone who can reach POST /mcp can invoke tools and spend that key, so the
endpoint must not sit open on a public interface. The defaults are built around
this:
HTTP_HOSTdefaults to127.0.0.1, so a plain run only listens on loopback and the SDK's DNS rebinding protection is active. Nothing off the machine can reach it.To accept remote connections, set
HTTP_HOST=0.0.0.0and eitherHTTP_AUTH_TOKEN(so/mcprequiresAuthorization: Bearer <token>) orHTTP_ALLOWED_HOSTS. Binding0.0.0.0with neither turns the SDK'sHost-header check off entirely, which leaves/mcpopen to DNS rebinding from any web page you visit, so the server refuses to start rather than warn.HTTP_ALLOW_UNPROTECTED_BIND=trueoverrides the refusal if you really want an open endpoint.For an internet-facing deployment, put an authenticating reverse proxy with TLS in front and set
HTTP_ALLOWED_HOSTSto your real hostname(s).
# Exposed deployment with a bearer token
TRANSPORT=http HTTP_HOST=0.0.0.0 HTTP_PORT=3000 \
HTTP_AUTH_TOKEN=$(openssl rand -hex 32) \
HTTP_ALLOWED_HOSTS=mcp.example.com \
DEEPSEEK_API_KEY=your-key node dist/index.js
# Calling it
curl -X POST http://mcp.example.com:3000/mcp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":1}'HTTP_AUTH_TOKEN is a static gateway token for the self-hosted endpoint and is
unrelated to your DeepSeek key. It is separate from the hosted BYOK endpoint
above, where clients pass their own DeepSeek key as the bearer.
Session isolation (1.7.0+): In HTTP transport each connected MCP session
gets its own McpServer instance and its own SessionStore. Conversation
history, session listings, and deletions are scoped to the MCP session that
created them, so one client cannot read, enumerate, or wipe another client's
sessions. STDIO transport is single-tenant by nature and unaffected.
Docker
# Build
docker build -t deepseek-mcp-server .
# Run, reachable only from the host's loopback, with a bearer token
docker run -d -p 127.0.0.1:3000:3000 \
-e DEEPSEEK_API_KEY=your-key \
-e HTTP_AUTH_TOKEN=your-token \
deepseek-mcp-server
# Or use docker-compose
DEEPSEEK_API_KEY=your-key HTTP_AUTH_TOKEN=your-token docker compose up -dThe image runs HTTP transport on port 3000 with a health check. Inside the
container it binds 0.0.0.0 (required for the port mapping to work), so control
exposure at the publish layer: the example above and the bundled
docker-compose.yml publish to 127.0.0.1 only.
Publishing on loopback is not on its own enough, because DNS rebinding targets
the loopback address your own browser can already reach. The image therefore
ships HTTP_ALLOWED_HOSTS=localhost,127.0.0.1,[::1], which keeps the Host
check installed. Publishing under a real hostname? Add it to that list, or every
request carrying it gets a 403. Publishing on a public interface? Set
HTTP_AUTH_TOKEN as well.
Troubleshooting
"DEEPSEEK_API_KEY environment variable is not set"
Option 1: Use the correct installation command
# Make sure to include -e flag with your API key
claude mcp add deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-hereOption 2: Manually edit the config file
If you already installed without the API key, edit your config file:
For Claude Code: Open
~/.claude.json(Windows:C:\Users\USERNAME\.claude.json)Find the
"mcpServers"section under your project pathAdd the
envfield with your API key:
"deepseek": {
"type": "stdio",
"command": "npx",
"args": ["@arikusi/deepseek-mcp-server"],
"env": {
"DEEPSEEK_API_KEY": "your-api-key-here"
}
}Save and restart Claude Code
"Failed to connect to DeepSeek API"
Check your API key is valid
Verify you have internet connection
Check DeepSeek API status at https://status.deepseek.com
Server not appearing in your MCP client
Verify the path to
dist/index.jsis correctMake sure you ran
npm run buildCheck your MCP client's logs for errors
Restart your MCP client completely
Permission Denied on macOS/Linux
Make the file executable:
chmod +x dist/index.jsPublishing to npm
To share this MCP server with others:
Run
npm loginRun
npm publish --access public
Users can then install with:
npm install -g @arikusi/deepseek-mcp-serverContributing
Contributions are welcome! Please read our Contributing Guidelines before submitting PRs.
Reporting Issues
Found a bug or have a feature request? Please open an issue using our templates.
Development
# Clone the repo
git clone https://github.com/arikusi/deepseek-mcp-server.git
cd deepseek-mcp-server
# Install dependencies
npm install
# Build in watch mode
npm run watch
# Run tests
npm test
# Lint
npm run lintChangelog
See CHANGELOG.md for version history and updates.
License
MIT License - see LICENSE file for details
Support
Resources
DeepSeek Platform - Get your API key
Model Context Protocol - MCP specification
DeepSeek API Documentation - API reference
Acknowledgments
Built with Model Context Protocol SDK
Uses OpenAI SDK for API compatibility
Created for the MCP community
Made by @arikusi
An independent, community-maintained MCP server for the DeepSeek API.
Available Tools
3 toolsdeepseek_chatDeepSeek Chat CompletionB
Chat with DeepSeek models. deepseek-flash (V4.1 Flash, fast and economical) and deepseek-v4-pro (V4 Pro), both 1M context with optional chain-of-thought thinking mode. deepseek-v4-flash, deepseek-chat and deepseek-reasoner are legacy names, still accepted for backward compatibility (they resolve to deepseek-flash); prefer deepseek-flash. Features: multi-turn sessions (session_id), function calling (tools parameter), thinking mode, JSON output mode, multimodal input (when enabled), automatic cost tracking, and model fallback with circuit breaker resilience.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Model to use. deepseek-flash (default, V4.1 Flash, fast/economical) or deepseek-v4-pro (V4 Pro), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:"enabled"} to reason. Legacy names (still accepted, prefer deepseek-flash): deepseek-v4-flash -> deepseek-flash, deepseek-chat -> deepseek-flash non-thinking, deepseek-reasoner -> deepseek-flash thinking. | deepseek-flash |
| tools | No | Array of tool definitions for function calling. Each tool has type "function" and a function object with name, description, and parameters (JSON Schema). | |
| stream | No | Enable streaming mode. Returns full response after streaming completes. | |
| messages | Yes | Array of conversation messages. Each message has role (system/user/assistant/tool) and content (string or array of content parts for multimodal). Tool messages require tool_call_id. | |
| thinking | No | Toggle chain-of-thought thinking mode. Use {type: "enabled"} to reason, {type: "disabled"} for a fast direct answer (the default here). When enabled, temperature/top_p are ignored. | |
| json_mode | No | Enable JSON output mode. The model will output valid JSON. Include the word "json" in your prompt for best results. Supported by both models. | |
| max_tokens | No | Maximum tokens to generate. V4 models support up to 384000 output tokens. | |
| session_id | No | Session ID for multi-turn conversations. When provided, previous messages from this session are prepended to the current messages. If the session does not exist, it is created automatically. Omit for stateless single-turn requests. | |
| temperature | No | Sampling temperature (0-2). Higher = more random. Default: 1.0. Ignored when thinking mode is enabled. | |
| tool_choice | No | Controls which tool the model calls. "auto" (default), "none", "required", or {type:"function",function:{name:"..."}} | |
| response_schema | No | JSON Schema to validate the model output against. Implies JSON output mode. The server validates the parsed result and, on failure, issues up to RESPONSE_SCHEMA_MAX_RETRIES repair retries (feeding the validation error back). The returned content is the first schema-valid object, or the last attempt with schema.valid=false and schema.error set. | |
| reasoning_effort | No | Reasoning effort while thinking mode is active: "high" (default) or "max". Only applies when thinking is enabled. |
Output Schema
| Name | Required | Description |
|---|---|---|
| model | Yes | |
| usage | Yes | |
| schema | No | |
| content | Yes | |
| request | Yes | |
| cost_usd | No | |
| fallback | No | |
| effective | No | |
| session_id | No | |
| tool_calls | No | |
| routed_from | No | |
| finish_reason | Yes | |
| json_parse_error | No | |
| reasoning_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It does disclose genuinely behavioral traits beyond the schema — automatic cost tracking and model fallback with circuit-breaker resilience — which is real added value. However, it presents these as a feature list and omits operational concerns an agent would want (that each call is a billable external API call, latency, failure/error surface).
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?
The core purpose is front-loaded, which is good, but the second half degenerates into a long comma-separated feature list that largely re-states parameter descriptions already in the schema (thinking mode, JSON output, tools, session_id). It's serviceable but not tight.
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?
With 12 parameters at 100% schema coverage and an output schema present, the description only needs to frame the tool and its modes, which it does: model tiers, legacy aliases, thinking mode, and session support are all covered. The main gap is routing guidance against the two siblings.
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%, and the schema already documents model, thinking, json_mode, session_id, tools, response_schema and the rest in detail. The description merely gestures at the same parameters (session_id, tools, thinking mode, JSON output, multimodal) without adding syntax or semantics the schema lacks, so baseline 3 is right.
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 concrete verb+resource ('Chat with DeepSeek models') and enumerates the two current models with their tradeoffs (fast/economical vs Pro) plus 1M context. It's clear what the tool does, but it never names the siblings deepseek_fim or deepseek_sessions to say what this is *not*.
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?
There is useful guidance inside the description for model selection ('prefer deepseek-flash', legacy name resolution) and it mentions session_id for multi-turn use. But it never says when to reach for this tool versus deepseek_fim or deepseek_sessions, so the when-to-use-vs-alternatives question 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_fimDeepSeek FIM CompletionA
Fill-in-the-Middle (FIM) completion with DeepSeek. Provide a prompt (prefix) and an optional suffix; the model completes the text in between. Ideal for code completion and content infilling. Runs in non-thinking mode on the Beta endpoint; output is capped at 4K tokens. The legacy names deepseek-v4-flash, deepseek-chat and deepseek-reasoner are still accepted and resolve to deepseek-flash (FIM has no thinking mode). Includes automatic cost tracking and model fallback with circuit breaker resilience.
| Name | Required | Description | Default |
|---|---|---|---|
| stop | No | Optional stop sequence(s). Generation stops when any is produced. A single string or an array of up to 16 strings. | |
| model | No | Model to use. deepseek-flash (default, V4.1 Flash, fast/economical) or deepseek-v4-pro (V4 Pro). Legacy names deepseek-v4-flash / deepseek-chat / deepseek-reasoner are still accepted and resolve to deepseek-flash. FIM is always non-thinking. | deepseek-flash |
| prompt | Yes | The prefix text that comes before the content to generate. Required. For code completion, this is the code up to the cursor. | |
| suffix | No | Optional suffix text that comes after the content to generate. The model fills the gap between prompt and suffix. | |
| max_tokens | No | Maximum tokens to generate. FIM completions are capped at 4096 tokens by the API. | |
| temperature | No | Sampling temperature (0-2). Higher = more random. Default: 1.0. |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | |
| model | Yes | |
| usage | Yes | |
| cost_usd | No | |
| routed_from | No | |
| pricing_tier | No | |
| finish_reason | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does substantial work: non-thinking mode only, Beta endpoint, hard 4K output cap, legacy model aliases resolving to deepseek-flash, plus cost tracking and fallback/circuit-breaker behavior. It omits auth requirements, rate limits, and error/failure semantics, which is the 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core mechanic before operational constraints (endpoint, cap) and then the alias/fallback details. Only minor redundancy exists, since the legacy-model note is repeated in the model enum description.
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?
An output schema exists, so return values need no explanation, and the description covers the operational traits an agent needs (cap, endpoint, non-thinking constraint, fallback). Only the alias repetition and absent failure/auth notes keep it from full marks.
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 schema already defines prompt, suffix, stop, model, max_tokens and temperature in detail. The description only restates the prompt/suffix prefix-and-gap semantics, adding no syntax, formatting, or edge-case guidance beyond structured fields — baseline 3.
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/resource ('Fill-in-the-Middle (FIM) completion') and the exact mechanics (prompt prefix + optional suffix, model fills the gap). The code-completion/content-infilling framing implicitly separates it from the conversational deepseek_chat sibling, but no sibling is ever named.
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?
'Ideal for code completion and content infilling' gives clear context for when to reach for this tool. There are no explicit exclusions or pointers to deepseek_chat for conversational turns, so the agent must infer the boundary itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deepseek_sessionsDeepSeek Session ManagementA
Manage multi-turn conversation sessions. List active sessions, delete a specific session, or clear all sessions. Sessions store conversation history for use with the session_id parameter in deepseek_chat.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform. "list": show all active sessions, "clear": remove all sessions, "delete": remove a specific session (requires session_id) | |
| session_id | No | Session ID to delete (required when action is "delete") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description alone must convey behavioral traits. It lists actions but does not mention impacts like data loss on deletion, authentication needs, or rate limits. Basic transparency but insufficient for a management tool with destructive potential.
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?
The description is concise with two sentences, front-loading the purpose. Could be slightly more structured but is efficient and avoids unnecessary words.
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?
No output schema is provided, yet the description does not specify what the 'list' action returns (e.g., session IDs). The tool is fairly complete given the schema and context signals, but missing output details and error conditions.
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 coverage is 100% with both parameters described. The description adds useful context about sessions used with deepseek_chat, but adds no new details beyond what the schema already provides for parameters.
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?
The description clearly states the tool manages multi-turn conversation sessions with specific actions (list, delete, clear), and distinguishes from the sibling tool deepseek_chat by noting sessions are used with that tool's session_id parameter.
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?
The description explains that sessions store history used by deepseek_chat, providing context for when to use this management tool. However, it lacks explicit when-not-to-use guidance or alternative conditions.
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
v2.4.0- Changed
deepseek_chat4 fields changed- changed
Input schema / properties / model / defaultPrevious value: -"deepseek-v4-flash"New value: +"deepseek-flash" - changed
Input schema / properties / model / descriptionPrevious value: -"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:\"enabled\"} to reason. Deprecated aliases (still accepted, prefer v4 names): deepseek-chat -> v4-flash non-thinking, deepseek-reasoner -> v4-flash thinking."New value: +"Model to use. deepseek-flash (default, V4.1 Flash, fast/economical) or deepseek-v4-pro (V4 Pro), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:\"enabled\"} to reason. Legacy names (still accepted, prefer deepseek-flash): deepseek-v4-flash -> deepseek-flash, deepseek-chat -> deepseek-flash non-thinking, deepseek-reasoner -> deepseek-flash thinking." - changed
Input schema / properties / model / enumPrevious value: -[ - "deepseek-v4-flash", - "deepseek-v4-pro", - "deepseek-chat", - "deepseek-reasoner" -]New value: +[ + "deepseek-flash", + "deepseek-v4-pro", + "deepseek-v4-flash", + "deepseek-chat", + "deepseek-reasoner" +] - added
Output schema / properties / request / properties / pricing_tierAdded value: +{ + "enum": [ + "peak", + "off-peak" + ], + "type": "string" +}
- Changed
deepseek_fim4 fields changed- changed
Input schema / properties / model / defaultPrevious value: -"deepseek-v4-flash"New value: +"deepseek-flash" - changed
Input schema / properties / model / descriptionPrevious value: -"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable). Deprecated aliases deepseek-chat / deepseek-reasoner are still accepted and resolve to v4-flash. FIM is always non-thinking."New value: +"Model to use. deepseek-flash (default, V4.1 Flash, fast/economical) or deepseek-v4-pro (V4 Pro). Legacy names deepseek-v4-flash / deepseek-chat / deepseek-reasoner are still accepted and resolve to deepseek-flash. FIM is always non-thinking." - changed
Input schema / properties / model / enumPrevious value: -[ - "deepseek-v4-flash", - "deepseek-v4-pro", - "deepseek-chat", - "deepseek-reasoner" -]New value: +[ + "deepseek-flash", + "deepseek-v4-pro", + "deepseek-v4-flash", + "deepseek-chat", + "deepseek-reasoner" +] - added
Output schema / properties / pricing_tierAdded value: +{ + "enum": [ + "peak", + "off-peak" + ], + "type": "string" +}
2 tool updates
v2.3.0- Changed
deepseek_chat8 fields changed- changed
Input schema / properties / model / descriptionPrevious value: -"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:\"enabled\"} to reason. Aliases: deepseek-chat -> v4-flash non-thinking, deepseek-reasoner -> v4-flash thinking."New value: +"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:\"enabled\"} to reason. Deprecated aliases (still accepted, prefer v4 names): deepseek-chat -> v4-flash non-thinking, deepseek-reasoner -> v4-flash thinking." - added
Input schema / properties / response_schemaAdded value: +{ + "additionalProperties": {}, + "description": "JSON Schema to validate the model output against. Implies JSON output mode. The server validates the parsed result and, on failure, issues up to RESPONSE_SCHEMA_MAX_RETRIES repair retries (feeding the validation error back). The returned content is the first schema-valid object, or the last attempt with schema.valid=false and schema.error set.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / effectiveAdded value: +{ + "additionalProperties": false, + "properties": { + "model": { + "type": "string" + }, + "temperature": { + "type": "number" + }, + "thinking": { + "type": "boolean" + } + }, + "required": [ + "model", + "thinking" + ], + "type": "object" +} - added
Output schema / properties / fallbackAdded value: +{ + "additionalProperties": false, + "properties": { + "fallbackModel": { + "type": "string" + }, + "originalModel": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "originalModel", + "fallbackModel", + "reason" + ], + "type": "object" +} - added
Output schema / properties / json_parse_errorAdded value: +{ + "type": "string" +} - added
Output schema / properties / requestAdded value: +{ + "additionalProperties": false, + "properties": { + "cache_hit_tokens": { + "type": "number" + }, + "cache_miss_tokens": { + "type": "number" + }, + "completion_tokens": { + "type": "number" + }, + "cost_usd": { + "type": "number" + }, + "fallback_used": { + "type": "boolean" + }, + "finish_reason": { + "type": "string" + }, + "model": { + "type": "string" + }, + "prompt_tokens": { + "type": "number" + }, + "temperature": { + "type": "number" + }, + "thinking": { + "type": "boolean" + }, + "total_tokens": { + "type": "number" + }, + "wire_model": { + "type": "string" + } + }, + "required": [ + "model", + "wire_model", + "thinking", + "fallback_used", + "finish_reason", + "prompt_tokens", + "completion_tokens", + "total_tokens", + "cache_hit_tokens", + "cache_miss_tokens", + "cost_usd" + ], + "type": "object" +} - added
Output schema / properties / schemaAdded value: +{ + "additionalProperties": false, + "properties": { + "attempts": { + "type": "number" + }, + "error": { + "type": "string" + }, + "valid": { + "type": "boolean" + } + }, + "required": [ + "valid", + "attempts" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "content", - "model", - "usage", - "finish_reason" -]New value: +[ + "content", + "model", + "usage", + "request", + "finish_reason" +]
- Changed
deepseek_fim1 field changed- changed
Input schema / properties / model / descriptionPrevious value: -"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable). Aliases deepseek-chat / deepseek-reasoner resolve to v4-flash. FIM is always non-thinking."New value: +"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable). Deprecated aliases deepseek-chat / deepseek-reasoner are still accepted and resolve to v4-flash. FIM is always non-thinking."
1 tool update
v2.1.0- Added
deepseek_fim
1 tool update
v2.0.0- Changed
deepseek_chat9 fields changed- changed
Input schema / properties / max_tokens / descriptionPrevious value: -"Maximum tokens to generate. deepseek-chat: max 8192, deepseek-reasoner: max 65536"New value: +"Maximum tokens to generate. V4 models support up to 384000 output tokens." - changed
Input schema / properties / max_tokens / maximumPrevious value: -65536New value: +384000 - changed
Input schema / properties / model / defaultPrevious value: -"deepseek-chat"New value: +"deepseek-v4-flash" - changed
Input schema / properties / model / descriptionPrevious value: -"Model to use. Both run DeepSeek V3.2 (128K context). deepseek-chat: non-thinking mode (max 8K output), deepseek-reasoner: thinking mode (max 64K output)"New value: +"Model to use. deepseek-v4-flash (default, fast/economical) or deepseek-v4-pro (most capable), both 1M context, up to 384K output. Non-thinking by default for speed; pass thinking:{type:\"enabled\"} to reason. Aliases: deepseek-chat -> v4-flash non-thinking, deepseek-reasoner -> v4-flash thinking." - changed
Input schema / properties / model / enumPrevious value: -[ - "deepseek-chat", - "deepseek-reasoner" -]New value: +[ + "deepseek-v4-flash", + "deepseek-v4-pro", + "deepseek-chat", + "deepseek-reasoner" +] - added
Input schema / properties / reasoning_effortAdded value: +{ + "description": "Reasoning effort while thinking mode is active: \"high\" (default) or \"max\". Only applies when thinking is enabled.", + "enum": [ + "high", + "max" + ], + "type": "string" +} - changed
Input schema / properties / thinking / descriptionPrevious value: -"Enable thinking mode. When enabled, temperature/top_p/frequency_penalty/presence_penalty are automatically ignored. Use {type: \"enabled\"} to activate."New value: +"Toggle chain-of-thought thinking mode. Use {type: \"enabled\"} to reason, {type: \"disabled\"} for a fast direct answer (the default here). When enabled, temperature/top_p are ignored." - added
Output schema / properties / cost_usdAdded value: +{ + "type": "number" +} - added
Output schema / properties / routed_fromAdded value: +{ + "type": "string" +}
2 tool updates
v1.5.0- First observed
deepseek_chat - First observed
deepseek_sessions
TDQS
Scored across 3 tools
deepseek_chat and deepseek_fim both produce model completions, which could be confused, but the descriptions clearly distinguish conversational/multi-turn use from prefix-suffix infilling. deepseek_sessions is clearly separate as a management utility.
All three tools use a consistent deepseek_<noun/verb> snake_case pattern (chat, fim, sessions) with no style mixing.
Three tools is on the thin side, but each covers a distinct capability (chat, FIM, session management) and earns its place for a chat API wrapper. Slight deduction because deepseek_sessions bundles list/delete/clear operations rather than exposing them separately.
Core chat and completion workflows are covered, and sessions can be listed/deleted/cleared, but there's no explicit session creation and no embeddings or model-listing tool, which are typical gaps for an LLM API server. Agents can mostly work around this since sessions appear to auto-create via session_id.
Maintenance
Related MCP Connectors
MCP server for AI dialogue using various LLM models via AceDataCloud
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
MCP server for building and testing AI agents with multi-model experimentation and insights.
Chat, image, video, and audio models from many vendors behind one remote MCP server and one key.
Related MCP Servers
- AlicenseDqualityDmaintenanceAllows seamless integration of DeepSeek's language models with MCP-compatible applications like Claude Desktop, supporting features such as model selection, temperature control, and multi-turn conversations with automatic model fallback.2327 npm2MIT
- AlicenseNot gradedqualityDmaintenanceA Node.js + TypeScript MCP server that proxies to DeepSeek's Chat, Image, and TTS APIs for conversation, image generation, and text-to-speech.MIT
- AlicenseAqualityDmaintenanceMCP server that wraps DeepSeek's AI capabilities into standard MCP tools, supporting three authentication modes including free web-based usage without API keys.6327 npm3MIT
- AlicenseNot gradedqualityDmaintenanceMulti-model MCP server enabling code generation, visual analysis, and complex reasoning via Qwen3 models.MIT