borgez/dsh-project-mcp ↗★ 0

dsh-project-mcp

将项目声明的 MCP 服务器挂载至对应会话中 适合需要在不同项目中自动加载和使用特定 MCP 工具服务器的开发者。

套件
dsh-project-mcp
相容性
待驗證
Harness 依賴範圍
>=0.1.5-rc.2
Cordis 依賴範圍
>=4.0.2
版本
0.2.0
授權
MIT
最近更新
2026年9月26日

同名套件的其他儲存庫

安裝

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:borgez/dsh-project-mcp

Configuration

Plugin config is the cordis.patch.yml row (defaults shown):

- id: project-mcp
  config:
    enabled: true          # master switch
    localFiles: ['.dsh/mcp.json']   # project documents, lowest priority first
    globalFiles: []        # documents read before a project's own; [] reads none
    envFiles: true         # read 
/.env and 
/.dsh/.env for ${...}
    inputs: {}             # explicit ${input:NAME} values, e.g. COVERAGE_MCP_ALLOWED_ROOT: /repo
    toolCallTimeoutMs: 60000
    failOnStartupError: false   # true = a dead server fails its mount instead of reconnecting
    connectTimeoutMs: 60000     # a mount with no tool after this window becomes an error row; 0 disables
    lazy: true             # mount a session's project on its first turn, not at session creation
    idleTimeoutMs: 300000  # release a session's mounts after this much inactivity; 0 disables
    activationWaitMs: 2000 # how long the first step of a turn may wait for a pending mount; 0 never waits
    profileWins: true      # a profile-level serverName wins; the project row becomes `conflict`
    watch: true            # watch project documents for edits
    debounceMs: 300
    rescanIntervalMs: 10000
    credentialsFile: ''    # default: $DSH_HOME/.credentials.yaml
    allowGlobalWrite: false # let the editor write the documents of globalFiles
    activationEnabled: true   # offer MCP tools through `mcp_search_tools` + activation
    activationSeeded: 8       # counter-seeded tools that are always offered
    activationMinCalls: 5     # calls one tool needs before it is seeded
    toolIdleMs: 1800000       # drop a session-activated tool after this long without a call; 0 disables
    guidanceEnabled: true     # one short project-MCP guidance section in the session system prompt
    activationAutoLimit: 12   # names the task-context tier may offer at once; 0 disables that tier
    activationAutoStickySteps: 2  # extra user messages a context offer stays offered
    activationToolBudgetChars: 40000  # serialized MCP surface above which tools are deferred; 0 defers always
    projectMarkers: ['.git', '.dsh', '.kimi-code', 'package.json']
    fileMarkers: ['.sln', '.slnx', '.csproj']

Live editing

On DSH ≥ 0.1.7 the keys below are volatile: the host serves them as a config form, an edit commits into the running plugin without a restart, and the runtime picks the new value up on the loader's loader/volatile-update event. Every other key — enabled, localFiles, globalFiles, projectMarkers, fileMarkers, inputs, credentialsFile, watch, rescanIntervalMs, failOnStartupError — is structural and still needs a remount (restart or config reload) to take effect. An older host just hands over plain values, and nothing about the boot path changes.

Volatile keys: activationEnabled, activationSeeded, activationMinCalls, toolIdleMs, guidanceEnabled, activationAutoLimit, activationAutoStickySteps, activationToolBudgetChars, allowGlobalWrite, envFiles, lazy, localPrefix, profileWins, connectTimeoutMs, toolCallTimeoutMs, idleTimeoutMs, debounceMs, activationWaitMs.

profileWins

  • true (default) — a project entry whose serverName is already live in the profile is not mounted; its row reads conflict with the hint to remove the profile entry. Safe: no duplicate processes, no shadowing.
  • false — the project instance is mounted too. Nearer scopes shadow the profile's tools for that session, so the project's own configuration (for example a project-specific IJ_MCP_SERVER_PROJECT_PATH) wins. Costs one server process/connection per server for as long as a session of that project holds it.

Usage counters

The host half counts every tool call whose server this plugin mounted, keyed by project root and serverName, so a project's numbers outlive the sessions that produced them:

ctx.get('projectMcp').snapshot().projects[0].usage
// { alpha: { calls: 12, errors: 1, tools: { search: 9, fetch: 3 },
//            lastUsedAt: '2024-05-06T07:08:09.000Z' } }
  • calls counts every dispatched call, errors those whose result carried an error, and lastUsedAt (ISO) moves on success only. tools keys the tool name as the server declares it, without the mcp____ prefix.
  • Attribution never parses the prefix blindly: only tool names belonging to a server this plugin mounted for the calling agent's project are counted, so a profile-level mcp__* server never lands in a project's counters, and a registry name truncated to the function-name budget still resolves to its own server.
  • The counters live in $DSH_HOME/dsh-project-mcp-usage.json, a versioned document ({ version: 1, projects: … }) written atomically (temp file + rename) on a debounce — never on the tool-call path. A missing, unparsable or older-version document starts clean, and a failed write is logged and dropped: counting is never a reason for a tool call or the plugin to fail.
  • usage is absent for a project with no counted calls yet.