{
  "markdown": "<p align=\"center\">\n  <img src=\"icon.png\" alt=\"DeepSeek MCP Server\" width=\"120\" />\n</p>\n\n<h1 align=\"center\">DeepSeek MCP Server</h1>\n\n<p align=\"center\">\n  MCP server for DeepSeek V4 (v4-flash and v4-pro, 1M context) with multi-turn sessions, function calling, thinking mode, and cost tracking.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/@arikusi/deepseek-mcp-server\"><img src=\"https://img.shields.io/npm/v/@arikusi/deepseek-mcp-server.svg\" alt=\"npm version\" /></a>\n  <a href=\"https://www.npmjs.com/package/@arikusi/deepseek-mcp-server\"><img src=\"https://img.shields.io/npm/dm/@arikusi/deepseek-mcp-server.svg\" alt=\"npm downloads\" /></a>\n  <a href=\"https://opensource.org/licenses/MIT\"><img src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\" /></a>\n  <a href=\"https://nodejs.org/\"><img src=\"https://img.shields.io/node/v/@arikusi/deepseek-mcp-server.svg\" alt=\"Node.js Version\" /></a>\n  <a href=\"https://www.typescriptlang.org/\"><img src=\"https://img.shields.io/badge/TypeScript-7.0-blue.svg\" alt=\"TypeScript\" /></a>\n  <a href=\"https://api-docs.deepseek.com\"><img src=\"https://img.shields.io/badge/DeepSeek-V4-7c3aed.svg\" alt=\"DeepSeek V4\" /></a>\n  <a href=\"https://github.com/arikusi/deepseek-mcp-server/actions\"><img src=\"https://github.com/arikusi/deepseek-mcp-server/workflows/CI/badge.svg\" alt=\"Build Status\" /></a>\n</p>\n\n<p align=\"center\">\n  Compatible with Claude Code, Gemini CLI, Cursor, Windsurf, and any MCP-compatible client.<br />\n  Officially listed on the <a href=\"https://registry.modelcontextprotocol.io/?q=io.github.arikusi\"><strong>MCP Registry</strong></a>, <a href=\"https://smithery.ai/servers/arikusi/deepseek-mcp-server\">Smithery</a>, <a href=\"https://glama.ai/mcp/servers/arikusi/deepseek-mcp-server\">Glama</a>, <a href=\"https://lobehub.com/mcp/arikusi-deepseek-mcp-server\">LobeHub</a>, and <a href=\"https://fronteir.ai/mcp/arikusi-deepseek-mcp-server\">Fronteir AI</a>.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://registry.modelcontextprotocol.io/?q=io.github.arikusi\"><img src=\"https://img.shields.io/badge/Official_MCP_Registry-active-brightgreen\" alt=\"Official MCP Registry\" /></a>\n  <a href=\"https://lobehub.com/mcp/arikusi-deepseek-mcp-server\"><img src=\"https://lobehub.com/badge/mcp/arikusi-deepseek-mcp-server\" alt=\"LobeHub\" /></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://glama.ai/mcp/servers/arikusi/deepseek-mcp-server\">\n    <img width=\"380\" height=\"200\" src=\"https://glama.ai/mcp/servers/arikusi/deepseek-mcp-server/badge\" alt=\"Glama Badge\" />\n  </a>\n</p>\n\n> **v2.0.0 runs on DeepSeek V4.** Two models, `deepseek-v4-flash` (fast and economical) and `deepseek-v4-pro` (top capability), both with a 1M-token context window and optional chain-of-thought thinking. Existing `deepseek-chat` and `deepseek-reasoner` setups keep working through deprecated aliases, so upgrading is drop-in, but new setups should use the V4 names.\n\n## Quick Start\n\n### Remote (No Install)\n\nUse the hosted endpoint directly — no npm install, no Node.js required. Bring your own DeepSeek API key:\n\n**Claude Code:**\n```bash\nclaude mcp add --transport http deepseek \\\n  https://deepseek-mcp.tahirl.com/mcp \\\n  --header \"Authorization: Bearer YOUR_DEEPSEEK_API_KEY\"\n```\n\n**Cursor / Windsurf / VS Code:**\n```json\n{\n  \"mcpServers\": {\n    \"deepseek\": {\n      \"url\": \"https://deepseek-mcp.tahirl.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${DEEPSEEK_API_KEY}\"\n      }\n    }\n  }\n}\n```\n\n### Local (stdio)\n\n**Claude Code:**\n```bash\nclaude mcp add -s user deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-here\n```\n\n**Gemini CLI:**\n```bash\ngemini mcp add deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-here\n```\n\n**Scope options** (Claude Code):\n- `-s user`: Available in all your projects (recommended)\n- `-s local`: Only in current project (default)\n- `-s project`: Project-specific `.mcp.json` file\n\n**Get your API key:** [https://platform.deepseek.com](https://platform.deepseek.com)\n\n---\n\n## Features\n\n- **DeepSeek V4**: `deepseek-v4-flash` and `deepseek-v4-pro`, both with 1M context and optional chain-of-thought thinking mode\n- **Multi-Turn Sessions**: Conversation context preserved across requests via `session_id` parameter\n- **Model Fallback & Circuit Breaker**: Automatic fallback between models with circuit breaker protection against cascading failures\n- **MCP Resources**: `deepseek://models`, `deepseek://config`, `deepseek://usage` — query model info, config, and usage stats\n- **Thinking Mode**: Enable chain-of-thought reasoning on either V4 model with `thinking: {type: \"enabled\"}`\n- **JSON Output Mode**: Structured JSON responses with `json_mode: true`\n- **Schema-Validated JSON**: Pass a `response_schema` and the server validates the output against it, with bounded repair retries and a ReDoS guard on schema patterns\n- **Function Calling**: OpenAI-compatible tool use with up to 128 tool definitions\n- **Fill-in-the-Middle (FIM)**: Code and content completion between a prefix and suffix via the `deepseek_fim` tool\n- **Cache-Aware Cost Tracking**: Automatic cost calculation with cache hit/miss breakdown\n- **Session Management Tool**: List, delete, and clear sessions via `deepseek_sessions` tool\n- **Configurable**: Environment-based configuration with validation\n- **12 Prompt Templates**: Templates for debugging, code review, function calling, and more\n- **Streaming Support**: Real-time response generation\n- **Multimodal Ready**: Content part types for text + image input (enable with `ENABLE_MULTIMODAL=true`)\n- **Remote Endpoint**: Hosted at `deepseek-mcp.tahirl.com/mcp` — BYOK (Bring Your Own Key), no install needed\n- **HTTP Transport**: Self-hosted remote access via Streamable HTTP with `TRANSPORT=http`\n- **Docker Ready**: Multi-stage Dockerfile with health checks for containerized deployment\n- **Tested**: 340 tests, ~92% line coverage\n- **Type-Safe**: Full TypeScript implementation\n- **MCP Compatible**: Works with any MCP-compatible CLI (Claude Code, Gemini CLI, etc.)\n\n## Installation\n\n### Prerequisites\n\n- Node.js 22+\n- A DeepSeek API key (get one at [https://platform.deepseek.com](https://platform.deepseek.com))\n\n### Manual Installation\n\nIf you prefer to install manually:\n\n```bash\nnpm install -g @arikusi/deepseek-mcp-server\n```\n\n### From Source\n\n1. **Clone the repository**\n\n```bash\ngit clone https://github.com/arikusi/deepseek-mcp-server.git\ncd deepseek-mcp-server\n```\n\n2. **Install dependencies**\n\n```bash\nnpm install\n```\n\n3. **Build the project**\n\n```bash\nnpm run build\n```\n\n## Usage\n\nOnce configured, your MCP client will have access to `deepseek_chat`, `deepseek_fim`, and `deepseek_sessions` tools, plus 3 MCP resources.\n\n**Example prompts:**\n```\n\"Use DeepSeek to explain quantum computing\"\n\"Ask DeepSeek Reasoner to solve: If I have 10 apples and buy 5 more...\"\n```\n\nYour MCP client will automatically call the `deepseek_chat` tool.\n\n### Manual Configuration (Advanced)\n\nIf your MCP client doesn't support the `add` command, manually add to your config file:\n\n```json\n{\n  \"mcpServers\": {\n    \"deepseek\": {\n      \"command\": \"npx\",\n      \"args\": [\"@arikusi/deepseek-mcp-server\"],\n      \"env\": {\n        \"DEEPSEEK_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n**Config file locations:**\n- **Claude Code**: `~/.claude.json` (add to `projects[\"your-project-path\"].mcpServers` section)\n- **Other MCP clients**: Check your client's documentation for config file location\n\n## Available Tools\n\n### `deepseek_chat`\n\nChat with DeepSeek AI models with automatic cost tracking and function calling support.\n\n**Parameters:**\n\n- `messages` (required): Array of conversation messages\n  - `role`: \"system\" | \"user\" | \"assistant\" | \"tool\"\n  - `content`: Message text\n  - `tool_call_id` (optional): Required for tool role messages\n- `model` (optional): \"deepseek-v4-flash\" (default) or \"deepseek-v4-pro\". The deprecated \"deepseek-chat\" and \"deepseek-reasoner\" aliases are still accepted and resolve to v4-flash (non-thinking / thinking); prefer the V4 names.\n- `temperature` (optional): 0-2, controls randomness (default: 1.0). Ignored when thinking mode is enabled.\n- `max_tokens` (optional): Maximum tokens to generate (V4 models support up to 384000)\n- `stream` (optional): Enable streaming mode (default: false)\n- `tools` (optional): Array of tool definitions for function calling (max 128)\n- `tool_choice` (optional): \"auto\" | \"none\" | \"required\" | `{type: \"function\", function: {name: \"...\"}}`\n- `thinking` (optional): Toggle thinking mode, `{type: \"enabled\"}` to reason or `{type: \"disabled\"}` for a fast answer (non-thinking is the default)\n- `reasoning_effort` (optional): \"high\" (default) or \"max\", applies only while thinking mode is active\n- `json_mode` (optional): Enable JSON output mode (supported by both models)\n- `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 to `RESPONSE_SCHEMA_MAX_RETRIES` repair 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.\n- `session_id` (optional): Session ID for multi-turn conversations. Previous context is automatically prepended.\n\n**Response includes:**\n- Content with formatting (recovered as clean JSON when JSON output is requested)\n- Function call results (if tools were used)\n- Request information (tokens, model, cost in USD)\n- `structuredContent.request`: a self-contained per-request usage and cost summary (token counts, cache hit/miss, `cost_usd`), aggregated across any repair retries\n- `structuredContent.effective` and `fallback`: what was actually sent after alias/thinking resolution, and any silent model fallback that fired\n- `structuredContent.schema`: when `response_schema` is used, `{valid, attempts, error?}`; `json_parse_error` when JSON output could not be recovered\n\n**Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Explain the theory of relativity in simple terms\"\n    }\n  ],\n  \"model\": \"deepseek-v4-flash\",\n  \"temperature\": 0.7,\n  \"max_tokens\": 1000\n}\n```\n\n**Reasoning Example (v4-flash with thinking enabled):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"If I have 10 apples and eat 3, then buy 5 more, how many do I have?\"\n    }\n  ],\n  \"model\": \"deepseek-v4-flash\",\n  \"thinking\": { \"type\": \"enabled\" }\n}\n```\n\nThinking mode returns the chain-of-thought in `<thinking>` tags followed by the final answer.\n\n**DeepSeek V4 Pro Example (hardest tasks):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Prove that the square root of 2 is irrational.\"\n    }\n  ],\n  \"model\": \"deepseek-v4-pro\",\n  \"thinking\": { \"type\": \"enabled\" }\n}\n```\n\n**Function Calling Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What's the weather in Istanbul?\"\n    }\n  ],\n  \"tools\": [\n    {\n      \"type\": \"function\",\n      \"function\": {\n        \"name\": \"get_weather\",\n        \"description\": \"Get current weather for a location\",\n        \"parameters\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"location\": {\n              \"type\": \"string\",\n              \"description\": \"City name\"\n            }\n          },\n          \"required\": [\"location\"]\n        }\n      }\n    }\n  ],\n  \"tool_choice\": \"auto\"\n}\n```\n\nWhen 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`.\n\n**Thinking Mode Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Analyze the time complexity of quicksort\"\n    }\n  ],\n  \"model\": \"deepseek-v4-flash\",\n  \"thinking\": { \"type\": \"enabled\" }\n}\n```\n\nWhen thinking mode is enabled, `temperature` and `top_p` are automatically ignored.\n\n**JSON Output Mode Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Return a json object with name, age, and city fields for a sample user\"\n    }\n  ],\n  \"model\": \"deepseek-v4-flash\",\n  \"json_mode\": true\n}\n```\n\nJSON mode ensures the model outputs valid JSON. Include the word \"json\" in your prompt for best results. Supported by all models.\n\n**Schema-Validated JSON Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Classify this review sentiment as json: \\\"Absolutely loved it\\\"\"\n    }\n  ],\n  \"model\": \"deepseek-v4-flash\",\n  \"response_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"sentiment\": { \"type\": \"string\", \"enum\": [\"positive\", \"negative\", \"neutral\"] },\n      \"confidence\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 }\n    },\n    \"required\": [\"sentiment\", \"confidence\"],\n    \"additionalProperties\": false\n  }\n}\n```\n\nThe 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.\n\n**Multi-Turn Session Example:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What is the capital of France?\"\n    }\n  ],\n  \"session_id\": \"my-session-1\"\n}\n```\n\nUse 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).\n\n### `deepseek_fim`\n\nFill-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.\n\n**Parameters:**\n\n- `prompt` (required): The prefix text before the gap. For code completion, this is the code up to the cursor.\n- `suffix` (optional): The text after the gap. The model fills the space between `prompt` and `suffix`.\n- `model` (optional): \"deepseek-v4-flash\" (default) or \"deepseek-v4-pro\". The deprecated \"deepseek-chat\" and \"deepseek-reasoner\" aliases are still accepted and resolve to v4-flash (FIM has no thinking mode).\n- `max_tokens` (optional): Maximum tokens to generate, up to 4096.\n- `temperature` (optional): 0-2, controls randomness (default: 1.0).\n- `stop` (optional): A stop string or an array of up to 16 stop strings.\n\n**Response includes:**\n- The completion text\n- Request information (tokens, model, cost in USD)\n- Structured data with `text`, `usage`, `finish_reason`, and `cost_usd` fields\n\n**Example (code completion):**\n\n```json\n{\n  \"prompt\": \"def fib(n):\\n    if n < 2:\\n        return n\\n    return \",\n  \"suffix\": \"\\n\\nprint(fib(10))\",\n  \"model\": \"deepseek-v4-flash\",\n  \"max_tokens\": 64\n}\n```\n\nThe 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.\n\n### `deepseek_sessions`\n\nManage conversation sessions.\n\n**Parameters:**\n- `action` (required): \"list\" | \"clear\" | \"delete\"\n- `session_id` (optional): Required when action is \"delete\"\n\n**Examples:**\n```json\n{\"action\": \"list\"}\n{\"action\": \"delete\", \"session_id\": \"my-session-1\"}\n{\"action\": \"clear\"}\n```\n\n## Available Resources\n\nMCP Resources provide read-only data about the server:\n\n| Resource URI | Description |\n|-------------|-------------|\n| `deepseek://models` | Available models with capabilities, context limits, and pricing |\n| `deepseek://config` | Current server configuration (API key masked) |\n| `deepseek://usage` | Real-time usage statistics (requests, tokens, costs, sessions) |\n\n## Model Fallback & Circuit Breaker\n\nWhen a model fails with a retryable error (429, 503, timeout), the server automatically falls back to the other model:\n- `deepseek-v4-flash` fails → tries `deepseek-v4-pro`\n- `deepseek-v4-pro` fails → tries `deepseek-v4-flash`\n\nThe deprecated aliases (which resolve to v4-flash) fall back to `deepseek-v4-pro`.\n\nThe circuit breaker protects against cascading failures:\n- After `CIRCUIT_BREAKER_THRESHOLD` consecutive failures (default: 5), the circuit **opens** (fast-fail mode)\n- After `CIRCUIT_BREAKER_RESET_TIMEOUT` ms (default: 30000), it enters **half-open** state and sends a probe request\n- If the probe succeeds, the circuit **closes** and normal operation resumes\n\nFallback can be disabled with `FALLBACK_ENABLED=false`.\n\n## Available Prompts\n\nPrompt templates (12 total):\n\n### Core Reasoning\n- **debug_with_reasoning**: Debug code with step-by-step analysis\n- **code_review_deep**: Comprehensive code review (security, performance, quality)\n- **research_synthesis**: Research topics and create structured reports\n- **strategic_planning**: Create strategic plans with reasoning\n- **explain_like_im_five**: Explain complex topics in simple terms\n\n### Advanced\n- **mathematical_proof**: Prove mathematical statements rigorously\n- **argument_validation**: Analyze arguments for logical fallacies\n- **creative_ideation**: Generate creative ideas with feasibility analysis\n- **cost_comparison**: Compare LLM costs for tasks\n- **pair_programming**: Interactive coding with explanations\n\n### Function Calling\n- **function_call_debug**: Debug function calling issues with tool definitions and messages\n- **create_function_schema**: Generate JSON Schema for function calling from natural language\n\nEach prompt is optimized for thinking mode (v4-flash with `thinking: {type: \"enabled\"}`) to provide detailed reasoning.\n\n## Models\n\nBoth V4 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\"}`.\n\n### deepseek-v4-flash (default)\n\n- **Best for**: General conversations, coding, content generation, agent loops\n- **Speed**: Fast and economical\n- **Context**: 1M tokens\n- **Max Output**: 384K tokens\n- **Pricing**: $0.0028/1M cache hit, $0.14/1M cache miss, $0.28/1M output\n\n### deepseek-v4-pro\n\n- **Best for**: Complex reasoning, math, hard multi-step tasks, top-quality output\n- **Speed**: Slower than flash, highest capability\n- **Context**: 1M tokens\n- **Max Output**: 384K tokens\n- **Pricing**: $0.003625/1M cache hit, $0.435/1M cache miss, $0.87/1M output\n\n### Deprecated aliases\n\n`deepseek-chat` and `deepseek-reasoner` are deprecated. They are still accepted and resolve to `deepseek-v4-flash` (chat = non-thinking, reasoner = thinking), so existing configs keep working, but they will be removed in the next major release. The DeepSeek API itself retired those two names on **2026-07-24**; this server keeps translating them to V4 for you in the meantime. New setups should use `deepseek-v4-flash` or `deepseek-v4-pro` directly.\n\n## Configuration\n\nThe server is configured via environment variables. All settings except `DEEPSEEK_API_KEY` are optional.\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DEEPSEEK_API_KEY` | (required) | Your DeepSeek API key |\n| `DEEPSEEK_BASE_URL` | `https://api.deepseek.com` | Custom API endpoint |\n| `DEFAULT_MODEL` | `deepseek-v4-flash` | Default model for requests |\n| `SHOW_COST_INFO` | `true` | Show cost info in responses |\n| `REQUEST_TIMEOUT` | `60000` | Request timeout in milliseconds |\n| `MAX_RETRIES` | `2` | Maximum retry count for failed requests |\n| `SKIP_CONNECTION_TEST` | `false` | Skip startup API connection test |\n| `MAX_MESSAGE_LENGTH` | `100000` | Maximum message content length (characters) |\n| `SESSION_TTL_MINUTES` | `30` | Session time-to-live in minutes |\n| `MAX_SESSIONS` | `100` | Maximum number of concurrent sessions |\n| `FALLBACK_ENABLED` | `true` | Enable automatic model fallback on errors |\n| `CIRCUIT_BREAKER_THRESHOLD` | `5` | Consecutive failures before circuit opens |\n| `CIRCUIT_BREAKER_RESET_TIMEOUT` | `30000` | Milliseconds before circuit half-opens |\n| `MAX_SESSION_MESSAGES` | `200` | Max messages per session (sliding window) |\n| `RESPONSE_SCHEMA_MAX_RETRIES` | `2` | Repair retries when a `response_schema` validation fails (0 disables) |\n| `ENABLE_MULTIMODAL` | `false` | Enable multimodal (image) input support |\n| `TRANSPORT` | `stdio` | Transport mode: `stdio` or `http` |\n| `HTTP_PORT` | `3000` | HTTP server port (when TRANSPORT=http) |\n| `HTTP_HOST` | `127.0.0.1` | Bind address for HTTP transport. Loopback by default so a fresh run is not exposed. Set to `0.0.0.0` to accept remote connections (do this only with auth or a proxy in front) |\n| `HTTP_AUTH_TOKEN` | _(unset)_ | When set, `POST /mcp` requires `Authorization: Bearer <token>`. `/health` stays open. Strongly recommended whenever the port is reachable beyond localhost |\n| `HTTP_ALLOWED_HOSTS` | _(unset)_ | Comma-separated list of allowed `Host` headers for DNS rebinding protection when binding to `0.0.0.0` (e.g. `mcp.example.com,localhost`). The Docker image defaults it to `localhost,127.0.0.1,[::1]` |\n| `HTTP_ALLOW_UNPROTECTED_BIND` | `false` | Set to `true` to bind `0.0.0.0` with neither `HTTP_ALLOWED_HOSTS` nor `HTTP_AUTH_TOKEN`. The server otherwise refuses to start in that combination |\n\n**Example with custom config:**\n```bash\nclaude mcp add -s user deepseek npx @arikusi/deepseek-mcp-server \\\n  -e DEEPSEEK_API_KEY=your-key \\\n  -e SHOW_COST_INFO=false \\\n  -e REQUEST_TIMEOUT=30000\n```\n\n## Development\n\n### Project Structure\n\n```\ndeepseek-mcp-server/\n├── worker/                  # Cloudflare Worker (remote BYOK endpoint)\n│   ├── src/index.ts         # Worker entry point\n│   ├── wrangler.toml        # Cloudflare config\n│   └── package.json\n├── src/\n│   ├── index.ts              # Entry point, bootstrap\n│   ├── server.ts             # McpServer factory (auto-version)\n│   ├── deepseek-client.ts    # DeepSeek API wrapper (circuit breaker + fallback)\n│   ├── config.ts             # Centralized config with Zod validation\n│   ├── cost.ts               # Cost calculation and formatting\n│   ├── schemas.ts            # Zod input validation schemas\n│   ├── types.ts              # TypeScript types + type guards\n│   ├── errors.ts             # Custom error classes\n│   ├── session.ts            # In-memory session store (multi-turn)\n│   ├── circuit-breaker.ts    # Circuit breaker pattern\n│   ├── usage-tracker.ts      # Usage statistics tracker\n│   ├── transport-http.ts     # Streamable HTTP transport (Express)\n│   ├── tools/\n│   │   ├── deepseek-chat.ts  # deepseek_chat tool (sessions + fallback)\n│   │   ├── deepseek-fim.ts   # deepseek_fim tool (fill-in-the-middle)\n│   │   ├── deepseek-sessions.ts # deepseek_sessions tool\n│   │   └── index.ts          # Tool registration aggregator\n│   ├── resources/\n│   │   ├── models.ts         # deepseek://models resource\n│   │   ├── config.ts         # deepseek://config resource\n│   │   ├── usage.ts          # deepseek://usage resource\n│   │   └── index.ts          # Resource registration aggregator\n│   └── prompts/\n│       ├── core.ts           # 5 core reasoning prompts\n│       ├── advanced.ts       # 5 advanced prompts\n│       ├── function-calling.ts # 2 function calling prompts\n│       └── index.ts          # Prompt registration aggregator\n├── dist/                     # Compiled JavaScript\n├── llms.txt                  # AI discoverability index\n├── llms-full.txt             # Full docs for LLM context\n├── vitest.config.ts          # Test configuration\n├── package.json\n├── tsconfig.json\n└── README.md\n```\n\n### Building\n\n```bash\nnpm run build\n```\n\n### Watch Mode (for development)\n\n```bash\nnpm run watch\n```\n\n### Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Watch mode\nnpm run test:watch\n\n# With coverage report\nnpm run test:coverage\n```\n\n### Testing Locally\n\n```bash\n# Set API key\nexport DEEPSEEK_API_KEY=\"your-key\"\n\n# Run the server\nnpm start\n```\n\nThe server will start and wait for MCP client connections via stdio.\n\n### Remote Endpoint (Hosted)\n\nA hosted BYOK (Bring Your Own Key) endpoint is available at:\n\n```\nhttps://deepseek-mcp.tahirl.com/mcp\n```\n\nSend 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).\n\n> **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.\n\n```bash\n# Test health\ncurl https://deepseek-mcp.tahirl.com/health\n\n# Test MCP (requires auth)\ncurl -X POST https://deepseek-mcp.tahirl.com/mcp \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer YOUR_KEY\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"method\":\"initialize\",\"params\":{\"capabilities\":{}},\"id\":1}'\n```\n\n### HTTP Transport (Self-Hosted)\n\nRun your own HTTP endpoint:\n\n```bash\nTRANSPORT=http HTTP_PORT=3000 DEEPSEEK_API_KEY=your-key node dist/index.js\n```\n\nTest the health endpoint:\n```bash\ncurl http://localhost:3000/health\n```\n\nThe MCP endpoint is available at `POST /mcp` (Streamable HTTP protocol).\n\n**Securing the endpoint (read before exposing it).** In self-hosted HTTP mode the\nserver holds your `DEEPSEEK_API_KEY` and uses it for every `deepseek_chat` call.\nAnyone who can reach `POST /mcp` can invoke tools and spend that key, so the\nendpoint must not sit open on a public interface. The defaults are built around\nthis:\n\n1. `HTTP_HOST` defaults to `127.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.\n2. To accept remote connections, set `HTTP_HOST=0.0.0.0` **and** either `HTTP_AUTH_TOKEN` (so `/mcp` requires `Authorization: Bearer <token>`) or `HTTP_ALLOWED_HOSTS`. Binding `0.0.0.0` with neither turns the SDK's `Host`-header check off entirely, which leaves `/mcp` open to DNS rebinding from any web page you visit, so the server refuses to start rather than warn. `HTTP_ALLOW_UNPROTECTED_BIND=true` overrides the refusal if you really want an open endpoint.\n3. For an internet-facing deployment, put an authenticating reverse proxy with TLS in front and set `HTTP_ALLOWED_HOSTS` to your real hostname(s).\n\n```bash\n# Exposed deployment with a bearer token\nTRANSPORT=http HTTP_HOST=0.0.0.0 HTTP_PORT=3000 \\\n  HTTP_AUTH_TOKEN=$(openssl rand -hex 32) \\\n  HTTP_ALLOWED_HOSTS=mcp.example.com \\\n  DEEPSEEK_API_KEY=your-key node dist/index.js\n\n# Calling it\ncurl -X POST http://mcp.example.com:3000/mcp \\\n  -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"method\":\"initialize\",\"params\":{\"capabilities\":{}},\"id\":1}'\n```\n\n`HTTP_AUTH_TOKEN` is a static gateway token for the self-hosted endpoint and is\nunrelated to your DeepSeek key. It is separate from the hosted BYOK endpoint\nabove, where clients pass their own DeepSeek key as the bearer.\n\n**Session isolation (1.7.0+):** In HTTP transport each connected MCP session\ngets its own `McpServer` instance and its own `SessionStore`. Conversation\nhistory, session listings, and deletions are scoped to the MCP session that\ncreated them, so one client cannot read, enumerate, or wipe another client's\nsessions. STDIO transport is single-tenant by nature and unaffected.\n\n### Docker\n\n```bash\n# Build\ndocker build -t deepseek-mcp-server .\n\n# Run, reachable only from the host's loopback, with a bearer token\ndocker run -d -p 127.0.0.1:3000:3000 \\\n  -e DEEPSEEK_API_KEY=your-key \\\n  -e HTTP_AUTH_TOKEN=your-token \\\n  deepseek-mcp-server\n\n# Or use docker-compose\nDEEPSEEK_API_KEY=your-key HTTP_AUTH_TOKEN=your-token docker compose up -d\n```\n\nThe image runs HTTP transport on port 3000 with a health check. Inside the\ncontainer it binds `0.0.0.0` (required for the port mapping to work), so control\nexposure at the publish layer: the example above and the bundled\n`docker-compose.yml` publish to `127.0.0.1` only.\n\nPublishing on loopback is not on its own enough, because DNS rebinding targets\nthe loopback address your own browser can already reach. The image therefore\nships `HTTP_ALLOWED_HOSTS=localhost,127.0.0.1,[::1]`, which keeps the `Host`\ncheck installed. Publishing under a real hostname? Add it to that list, or every\nrequest carrying it gets a 403. Publishing on a public interface? Set\n`HTTP_AUTH_TOKEN` as well.\n\n## Troubleshooting\n\n### \"DEEPSEEK_API_KEY environment variable is not set\"\n\n**Option 1: Use the correct installation command**\n```bash\n# Make sure to include -e flag with your API key\nclaude mcp add deepseek npx @arikusi/deepseek-mcp-server -e DEEPSEEK_API_KEY=your-key-here\n```\n\n**Option 2: Manually edit the config file**\n\nIf you already installed without the API key, edit your config file:\n\n1. **For Claude Code**: Open `~/.claude.json` (Windows: `C:\\Users\\USERNAME\\.claude.json`)\n2. Find the `\"mcpServers\"` section under your project path\n3. Add the `env` field with your API key:\n```json\n\"deepseek\": {\n  \"type\": \"stdio\",\n  \"command\": \"npx\",\n  \"args\": [\"@arikusi/deepseek-mcp-server\"],\n  \"env\": {\n    \"DEEPSEEK_API_KEY\": \"your-api-key-here\"\n  }\n}\n```\n4. Save and restart Claude Code\n\n### \"Failed to connect to DeepSeek API\"\n\n1. Check your API key is valid\n2. Verify you have internet connection\n3. Check DeepSeek API status at [https://status.deepseek.com](https://status.deepseek.com)\n\n### Server not appearing in your MCP client\n\n1. Verify the path to `dist/index.js` is correct\n2. Make sure you ran `npm run build`\n3. Check your MCP client's logs for errors\n4. Restart your MCP client completely\n\n### Permission Denied on macOS/Linux\n\nMake the file executable:\n\n```bash\nchmod +x dist/index.js\n```\n\n## Publishing to npm\n\nTo share this MCP server with others:\n\n1. Run `npm login`\n2. Run `npm publish --access public`\n\nUsers can then install with:\n\n```bash\nnpm install -g @arikusi/deepseek-mcp-server\n```\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) before submitting PRs.\n\n### Reporting Issues\n\nFound a bug or have a feature request? Please [open an issue](https://github.com/arikusi/deepseek-mcp-server/issues/new/choose) using our templates.\n\n### Development\n\n```bash\n# Clone the repo\ngit clone https://github.com/arikusi/deepseek-mcp-server.git\ncd deepseek-mcp-server\n\n# Install dependencies\nnpm install\n\n# Build in watch mode\nnpm run watch\n\n# Run tests\nnpm test\n\n# Lint\nnpm run lint\n```\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history and updates.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details\n\n## Support\n\n- [Documentation](https://github.com/arikusi/deepseek-mcp-server#readme)\n- [Bug Reports](https://github.com/arikusi/deepseek-mcp-server/issues)\n- [Discussions](https://github.com/arikusi/deepseek-mcp-server/discussions)\n- Contact: [GitHub Issues](https://github.com/arikusi/deepseek-mcp-server/issues)\n\n## Resources\n\n- [DeepSeek Platform](https://platform.deepseek.com) - Get your API key\n- [Model Context Protocol](https://modelcontextprotocol.io) - MCP specification\n- [DeepSeek API Documentation](https://api-docs.deepseek.com) - API reference\n\n## Acknowledgments\n\n- Built with [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk)\n- Uses [OpenAI SDK](https://github.com/openai/openai-node) for API compatibility\n- Created for the MCP community\n\n---\n\n**Made by [@arikusi](https://github.com/arikusi)**\n\nAn independent, community-maintained MCP server for the DeepSeek API.\n",
  "bytes": 31907,
  "sha": "3ad1b66154bb69eab929419414196a060bc6179db823a6821b2699353ee40657",
  "repo_slug": "arikusi/deepseek-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_arikusi_deepseek_d8ddea7b/readme"
}