Back to home

labmimors

dsh-mcp-lens

Shrink MCP context in DeepSeek Harness: 1,000 remote tools behind 2 exact-schema interfaces, with a measured V4 Flash cost pilot.

Stars
2
Language
TypeScript
Created
Aug 14, 2026
Updated
Aug 15, 2026

Introduction

MCP Lens for DeepSeek Harness

English | 简体中文

verify release license DeepSeek Harness

Shrink large MCP catalogs to a two-tool model surface.

MCP Lens lets DeepSeek Harness search and call 1,000 remote tools through two stable model-facing interfaces. Instead of sending every tool schema on every turn, it reveals exact schemas only for a small ranked set when a tool is actually needed.

Why users install it:

  • Spend less on input-heavy turns: in the dated three-task pilot, estimated DeepSeek V4 Flash cost fell from $0.0307204 to $0.0034707.
  • Keep more room for the real task: the same pilot reduced request/header.tools JSON from 674,249 B to 27,401 B.
  • Narrow the tool-choice surface: search reveals only a small ranked set of exact schemas, and the final server/tool is still gated by allowTools and denyTools.
  • Preserve completion in the tested pilot: both arms completed 3/3 tasks, while Lens used one extra search step.

Use MCP Lens if you have dozens to thousands of MCP tools, multiple servers, or long-tail tools that are expensive to advertise on every turn. Skip it if you have only a handful of tools that are used almost every request.

Install in 30 seconds

Prerequisites: DeepSeek Harness 0.1.0-rc.6, Node.js ^22.19.0 or >=24.0.0, and pnpm on PATH. The dsh plugin command delegates installation to pnpm.

Install the prebuilt release into your Harness profile:

dsh plugin --profile web add https://github.com/labmimors/dsh-mcp-lens/releases/download/v0.1.0-rc.7/dsh-mcp-lens-0.1.0-rc.7.tgz

Installation takes one command. To make the plugin useful, continue with Connect your first MCP server; its copy-paste block adds both a server and the exact tools you want to allow. Then validate and start the profile:

dsh --profile web --dump-config
dsh --profile web

After that, prompt Harness normally. You do not need to mention mcp_search or mcp_call in your prompt.

Try the local-only catalog calculator to measure your current tool-schema bytes, then copy a schema-free share link or Markdown result. Shared results are always labeled self-reported local measurements and encode only bounded numeric fields—not tool names, descriptions, or schemas. The numeric check catches accidental edits; it is not a signature or proof that a measurement occurred. Prefer a repeatable CI guard? Use the schema budget Action to fail a workflow when tool count or schema bytes drift above your limit.

Need the same measurement in CI? This repository also ships a dependency-free GitHub Action that audits a checked-in tool payload and reports the model-facing tool count, canonical schema bytes, and byte reduction versus the fixed two-tool Lens surface.

- uses: labmimors/dsh-mcp-lens@v0.1.0-rc.7
  with:
    tools-file: fixtures/request-header-tools.json

For an immutable production reference, pin the reviewed rc.7 commit: f21169f921e7ed032a4db5062685afb6f948c2d1.

Live DeepSeek Harness comparison: MCP Lens reduced model-visible tools, request tool JSON, and estimated API cost while both arms completed three of three tasks

Why does the chart show 27 instead of 2? Both arms include the same 25 non-MCP Harness tools: the direct client exposes 25 + 1,000 = 1,025 total tools; Lens exposes 25 + 2 = 27. The MCP surface itself is 1,000 → 2.

What it solves

Your problemWhat MCP Lens changes
API input grows with every MCP toolThe MCP surface always starts with only mcp_search and mcp_call. In our live three-task pilot, estimated V4 Flash cost fell 88.702%.
Large tool lists consume standing contextWith the same 1,000-tool server, complete Harness request-tool JSON fell from 674,249 B to 27,401 B.
You worry routing will reduce task completionIn the tested customer, Chinese-ticket, and GitHub tasks, Lens and the direct client both completed 3/3 with correct arguments and results.
Many similar tools widen the choice setSearch narrows what the model sees at once, returns exact inputSchema values, and calls an explicit server/tool identity.
Every server connects even when unusedConnections are lazy. Activation starts no MCP process and opens no MCP socket.
One server outage should not block the restOther servers keep working, and Lens keeps the previous usable catalog when a refresh fails.
Risky tools should be hidden by defaultNo remote tool appears until it matches allowTools; denyTools always wins in search and calls.

In the live pilot, MCP Lens and the official direct client both completed 3/3 tasks. Lens used one extra search step and more output tokens, so it is designed for large, multi-server, or long-tail catalogs, not a handful of tools used on every turn. See the full pilot report.

The tarball is already built, so no dependency build permission is needed. The MCP documentation server used below requires no additional API key; Harness still needs your configured model provider.

Install reviewed source instead
dsh plugin --profile web add github:labmimors/dsh-mcp-lens#v0.1.0-rc.7

Git installs fetch source and run prepare. With pnpm 10+, add this exact package key to $DSH_HOME/profiles/web/pnpm-workspace.yaml (default ~/.dsh/profiles/web/pnpm-workspace.yaml), then rerun the command:

allowBuilds:
  dsh-mcp-lens: true

Review the source and pin a tag or commit SHA before granting build permission.

Connect your first MCP server

The plugin ships with no servers and allows no remote tools until you opt in. Open:

$DSH_HOME/profiles/web/cordis.patch.yml

If DSH_HOME is unset, the default path is ~/.dsh/profiles/web/cordis.patch.yml. If the file contains only [], replace [] with the block below. If it already contains - id entries, append this as another top-level list item. It connects the public official MCP documentation server but exposes only its two read-only query tools:

- id: mcp-lens
  config:
    servers:
      - name: mcp-docs
        transport: streamable-http
        url: https://modelcontextprotocol.io/mcp

    cachePath: !!js dshHomePath('mcp-lens/catalog.json')
    allowTools:
      - mcp-docs/search_model_context_protocol
      - mcp-docs/query_docs_filesystem_model_context_protocol
    denyTools: ['mcp-docs/submit_feedback']

Verify the assembled profile, then start Harness:

dsh --profile web --dump-config
dsh --profile web

Now ask a normal question:

Use the official MCP documentation server to explain when an MCP client should use Streamable HTTP.

MCP Lens handles the two-step routing internally:

your request
  → mcp_search("search MCP documentation for Streamable HTTP")
  → exact mcp-docs/search_model_context_protocol input schema
  → mcp_call("mcp-docs", "search_model_context_protocol", arguments)
  → tool result

You do not have to mention mcp_search or mcp_call in normal prompts.

Authenticated Streamable HTTP example
- id: mcp-lens
  config:
    servers:
      - name: knowledge
        transport: streamable-http
        url: https://mcp.example.com/rpc
        headers:
          Authorization: !!js '`Bearer ${process.env.MCP_TOKEN}`'
        cacheNamespace: knowledge-acme-readonly

    cachePath: !!js dshHomePath('mcp-lens/catalog.json')
    allowTools: ['knowledge/read_*', 'knowledge/search_*']
    denyTools: ['*/delete_*', '*/destroy_*']

cacheNamespace is a non-secret identity for one tenant and permission scope. Rotate it when the account or scope changes. Never put the credential itself in this field. If a credentialed server omits it, Lens keeps that catalog memory-only and rediscovers it after restart.

Patterns match the exact server/tool identity, support literals plus *, and apply with deny winning. An empty allowTools list allows nothing. A later Cordis patch replaces this row's whole config, so include every non-default field you want to keep.

Is MCP Lens right for you?

ChooseWhen it fits best
Official @deepseek-ai/dsh-mcp-clientYou have a few stable tools that are used on most turns and want the simplest direct path.
MCP LensYou have dozens to thousands of tools, several MCP servers, long-tail capabilities, or repeated context/cost pressure.

Lens trades a search step on first use for a nearly constant standing MCP schema surface. The larger and less frequently used your catalog is, the stronger that trade becomes.

Speed: there is no universal latency win to claim. The first uncached use adds search and connection work; smaller requests may offset that cost on large catalogs, so measure your own workload.

Measured results

Live DeepSeek V4 Flash pilot

Same DeepSeek Harness 0.1.0-rc.6, same 1,000-tool stdio server, and the same three customer/ticket/GitHub tasks:

Metric across three tasksOfficial direct clientMCP LensDifference
Completed tasks3 / 33 / 3Tie
Model-visible tools per request1,0252797.366% fewer
request/header.tools JSON674,249 B27,401 B95.936% smaller
Uncached input tokens199,75121,71389.130% fewer
Cache-read input tokens934,91274,49692.032% fewer
Estimated API cost$0.0307204$0.003470788.702% lower

The cost estimate multiplies provider-reported usage by the official DeepSeek V4 Flash pricing retrieved on August 14, 2026. That pricing page also announces a new peak/off-peak schedule effective at 16:00 UTC on August 16, 2026, so later comparisons should recompute from the recorded usage. The three-task setup, observed calls, formula, and tradeoffs are recorded in docs/LIVE_DEEPSEEK_PILOT.md.

Keyless component benchmark

The checked-in benchmark uses a real Harness Context, SystemPrompt, and ToolRuntime, the official direct client as baseline, and the same local MCP fixture for both arms:

Remote MCP toolsDirect-client schema JSONLens schema JSONReduction
124,862 B1,114 B77.088%
10062,062 B1,114 B98.205%
1,000647,962 B1,114 B99.828%

At 1,000 tools, the official client registers 1,000 remote schemas while Lens still registers two. On the frozen 12-query retrieval fixture, Lens measured Recall@1 / Recall@5 / MRR = 1.0 / 1.0 / 1.0. That fixture was authored for this repository, so treat it as a regression guard—not independent evidence of real-world retrieval quality.

Reproduce the component result without an API key:

npm ci
npm run verify
npm run bench -- --output benchmark.json

The exact metric, fixture, dependency versions, source digest, and measurement limits are in benchmark/README.md.

Keep schema drift out of CI

The dependency-free MCP Lens Schema Audit GitHub Action measures an exported model-facing tool payload inside the runner. It makes no network request, writes numeric metrics plus schema-free share-url / share-markdown outputs, and never copies tool names, descriptions, or schemas into the Step Summary. Optional budgets turn an unexpected schema expansion into a failing check.

Accepted JSON shapes are a tool array, { "tools": [...] }, { "schemas": [...] }, { "header": { "tools": [...] } }, or a recorded { "request": { "header": { "tools": [...] } } } payload.

name: MCP schema budget
on: [pull_request]

permissions:
  contents: read

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
      - uses: labmimors/dsh-mcp-lens@f21169f921e7ed032a4db5062685afb6f948c2d1
        with:
          tools-file: artifacts/request-header.json
          max-tools: 100
          max-schema-bytes: 65536

The action accepts files up to 64 MiB, resolves the input inside GITHUB_WORKSPACE, and rejects symlink escapes. The byte metric is canonical JSON.stringify(tools) UTF-8 size—not tokens, billing, latency, or task quality.

Reliability and resource controls

  • Lazy by default: no MCP process or socket at plugin activation; idle connections close automatically.
  • Failure isolation: catalog refreshes run per server; one failure does not hide healthy servers.
  • Last-good behavior: failed or oversized discovery never replaces a usable catalog generation.
  • Bounded input: deadlines and caps cover pagination, tool count, per-tool bytes, total catalog bytes, cursors, and streamed HTTP responses.
  • Credential-aware cache: the owner-only 0600 cache stores projected tool metadata, never explicit env/header values or URL credentials.
  • Exact policy: search and call share the same allow/deny decision at the final server/tool identity.
  • Clean shutdown: cancellation, HMR, and disposal close transports, children, timers, and in-flight work.

MCP Lens is not a sandbox: stdio servers execute on the host, and HTTP servers receive the headers you configure. The current release bridges MCP Tools; it does not implement OAuth, Resources, Prompts, Elicitation, or task-based tool execution.

Configuration reference

Most users only need servers, cachePath, allowTools, and denyTools. The remaining fields already have bounded defaults:

Show all bounded defaults
FieldDefaultPurpose
catalogTtlMs86400000Refresh a catalog after 24 hours
idleDisconnectMs300000Close an idle server after 5 minutes
connectTimeoutMs30000Connection deadline
callTimeoutMs60000Tool-call deadline
discoveryTimeoutMs30000Whole paginated discovery deadline
maxDiscoveryPages1000Maximum pages per discovery
maxToolsPerServer10000Maximum tools accepted from one server
maxBytesPerTool1048576Maximum projected metadata bytes per tool
maxTotalCatalogBytes67108864Maximum total catalog/cache bytes
maxHttpResponseBytes16777216Maximum streamed HTTP response bytes
maxCursorBytes4096Maximum UTF-8 pagination cursor bytes
searchLimitDefault5Default search results
searchLimitMax10Maximum search results

See the shipped cordis.patch.yml for the canonical defaults.

Security, development, and community

DeepSeek Harness currently discovers community plugins through public GitHub repositories with the dsh-plugin topic and installs them from GitHub, tarballs, or npm packages. See the official plugin publishing guide.

MCP Lens is an independent MIT-licensed community plugin and is not affiliated with or endorsed by DeepSeek AI.