Skip to content

CH 12 · Plug into the MCP Ecosystem

Word count~4,900 wordsTime~20 minPrereqCH 03–05 already runningLevelReproducible

Chapter Goal

dsh's built-in tools (read files, run commands, search the web) are enough for daily use, but the outside world is full of scattered tools — GitHub, databases, memory, browsers, various SaaS — they don't run into your Agent on their own. This chapter plugs the MCP ecosystem in: first explain what MCP is, why dsh uses a "plugin" to connect, then hands-on mount the Firecrawl MCP server, so the model can call its tools as if they were native tools.

First Understand: What Is MCP

MCP (Model Context Protocol) is an open protocol that solves the general problem of "how AI applications connect to external tool servers". You can think of MCP as the USB-C of the tool world: a standard interface, and you can plug any device into it.

The MCP ecosystem already has a large batch of ready-made MCP servers:

MCP serverWhat it does
File systemRead/write subdirectories (expose a local directory to the Agent)
GitHubCreate issues, raise PRs, query repos
DatabaseQuery various databases
MemoryLong-term memory access (you'll see this again in CH 14)
BrowserControl the browser, scrape pages

The way to plug MCP into dsh is right in line with its style — one plugin: @deepseek-ai/dsh-mcp-client. This official plugin's role is pure: connect every MCP server you declare, and register the tools they provide into ctx.tools (the tool registry CH 11 mentioned), so in the model's eyes they're no different from native tools. This once again confirms CH 08's "everything is a plugin" — MCP integration is no exception.

A few points to know upfront:

  • Tool naming is two levels: first there's an MCP server (e.g. Firecrawl), and it has a batch of tools underneath (firecrawl_scrape scrape page, firecrawl_search search page, firecrawl_map list site map...). After being plugged in, each tool appears as mcp__<server-name>__<tool-name> — if the server name is firecrawl, its scrape tool is mcp__firecrawl__firecrawl_scrape. This matches the naming format of Claude Code and Codex. Different servers can share names without conflict (each has its own prefix).
  • No servers are enabled by default: whether the plugin is installed is one thing; which servers to connect to is completely up to your declaration. Without configuration, it connects to nothing. Once declared, the server will connect when dsh starts, and the tools register into the tool list; as for which round calls which tool, the model picks on its own per the current task — it doesn't call every tool every time.
  • Currently only "tools" are bridged: besides "tools" (Tool, callable actions), the MCP protocol also has two other capabilities — "Resources" (Resource, read-only data and files) and "Prompt templates" (Prompt). dsh's bridge plugin currently only brings in "tools"; resources and prompt templates can't be used yet.
  • Many servers require authentication: MCP servers that connect to real services, like GitHub and Firecrawl, usually need an API Key or token. Keys are passed via the headers field in the config (HTTP method), don't hardcode them in the config file — the config section below expands on this.

Hands-on: Connect Your First MCP Server — Firecrawl

Below, Firecrawl (a real web-scraping MCP service, Firecrawl website) walks you through. Its MCP server provides a batch of web tools: firecrawl_scrape (scrape a single page), firecrawl_search (search the web), firecrawl_map (list site map), firecrawl_crawl (crawl an entire site), firecrawl_extract (extract structured fields), etc.

Step 1: Confirm the MCP Client Plugin Is in Place

First confirm whether dsh-mcp-client is there. No need for the command line; check the plugin list directly in the Web UI: open Settings → Plugins, search for mcp. The picture below is my result — after typing mcp in the search box, the plugin list is empty ("no matching plugins"), meaning it's not installed:

Settings → Plugins page search mcp: no matching plugins

If you can't find it in the list, go back to the command line and install it as a dependency of the web profile:

dsh plugin --profile web add @deepseek-ai/dsh-mcp-client

Note: this command only packages it into the profile (dsh plugin list --profile web shows the dependency), it won't start on its own — for the plugin to actually be loaded, you need to insert it in cordis.patch.yml in step 3 and configure the servers. There's a pitfall from real testing: if you only insert the plugin without server config, dsh startup will directly report Cannot read properties of undefined (reading 'serverName') because serverName is a required field.

After configuration and reopening dsh, go back to Settings → Plugins and you'll see mcp-client, status "enabled" (the picture below is after installation, with the search box still showing mcp, plugin list 1 item, status enabled):

Settings → Plugins page shows mcp-client, status enabled

Step 2: Get a Firecrawl API Key

Firecrawl requires authentication. Log in to the Firecrawl website, register and create an API Key — the official usage is to send it as a Bearer token to https://mcp.firecrawl.dev/v2/mcp. The free tier has 1000 credits per month.

The picture below is the page where I created it: on the left you can see the remaining credits, in the middle is the default key listed (fc- prefix, middle redacted), top right has + Create:

Firecrawl console API Keys page: default key + Create button

After getting the key, first set it as a system environment variable (step 3 config will reference it). Let me be clear on one thing: environment variables are not written in a text file; they are a "list" maintained uniformly in the Windows system UI; the settings interface adds an entry to this list. On Windows, use the GUI; no commands needed:

  1. Press the Win key, type "environment variables", open Edit the system environment variables
  2. Click the Environment Variables button at the bottom right

System Properties window "Advanced" tab, with "Environment Variables" button at bottom right

  1. In the User variables section click New: variable name fill FIRECRAWL_API_KEY, variable value fill fc-your-full-key

Environment Variables list, the user variable section has FIRECRAWL_API_KEY added (value redacted)

  1. Click OK all the way to close the windows

Note: after setting, open a new terminal to start dsh — already-open windows won't auto-read newly set environment variables.

Step 3: Declare Firecrawl in the Profile Config

The MCP server's config is written in the web profile's patch file (the cordis.patch.yml from CH 08):

  • Windows: C:\Users\<your-username>\.dsh\profiles\web\cordis.patch.yml
  • macOS / Linux: ~/.dsh/profiles/web/cordis.patch.yml

Add a server to the insert list, using the official-recommended streamable-http method (connect to a remote endpoint):

In each insert entry, serverName is required (the startup error in step 1 was caused by it being empty) — it's the namespace for tool names, and decides what mcp__<here>__tool looks like.

Firecrawl's official remote endpoint is https://mcp.firecrawl.dev/v2/mcp, authenticated with a Bearer token:

yaml
- insert:
    - id: mcp-firecrawl
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: firecrawl
        transport: streamable-http
        url: https://mcp.firecrawl.dev/v2/mcp
        headers:
          Authorization: !!js '`Bearer ${process.env.FIRECRAWL_API_KEY}`'

The key is referenced through the environment variable (process.env.FIRECRAWL_API_KEY), not directly hardcoded in the file (see step 2 for how to set the environment variable) — once the file is committed to Git it could leak. To plug in other MCP servers later, just add another insert entry in this format.

A few common field descriptions:

FieldMeaning
serverNameThe tool-name namespace (mcp__<here>__tool), 1–32 alphanumeric underscores, unique within a scope
transportstdio (local program) or streamable-http (remote service)
command / args / envThe executable, arguments, extra environment variables for stdio
url / headersThe HTTP endpoint address and extra request headers (auth token goes here)
toolCallTimeoutMsPer-tool-call timeout (default 60 seconds)
reconnectAuto-reconnect policy on disconnect (default enabled, 500ms initial backoff doubling, 30s cap, give up after 10 consecutive failures)

After editing and saving, the file looks like this — the newly added insert section is highlighted:

cordis.patch.yml new mcp-firecrawl server config (highlighted yellow)

Step 4: Restart, Let the Model Call

Reopen dsh, and wait for it to finish starting. Firecrawl's tools don't have a dedicated "tool list page" for you to look at; the most direct way to confirm is let the model use it once:

  1. In the session, send: Use Firecrawl to scrape the main content of deepseek.com
  2. Watch the model's reply and the Trajectory: if the connection is successful, the model will call mcp__firecrawl__firecrawl_scrape, a TOOL row appears in the Trajectory, and the right-side panel shows the url parameter and the markdown result scraped back

Have the model call Firecrawl to scrape a web page: first search to locate the official pricing page, then scrape it, and give the result

In the Trajectory, a TOOL row for mcp__firecrawl__firecrawl_search / firecrawl_scrape appears, right-side panel shows Schema / Payload / Result

  1. If the tool doesn't come in, the model will explicitly say "I don't have this scraping tool here", or simply fall back to the built-in web search — both indicate the server is not connected; go back to the previous section to troubleshoot

Want to Save Trouble? Install Two Community Plugins

The official build has neither a "tool list" page nor a "browse plugins" entry; the community has filled in these two, both needing just one command:

① Plugin market dsh-market (987 stars): after installation, Settings has a new "Plugin Market" where you can browse by category, search, and one-click install community plugins. Most plugins installed via the market take effect just by refreshing the page, no need to restart dsh:

bash
dsh plugin --profile web add dshmarket

Settings → Plugin Market: Discover / Topics / Installed tabs, top search box + category bar + plugin cards

② MCP visualization panel DSH Skill & MCP Panel (108 stars): after installation, Settings has a new "MCP Management"; each server's status and tool count are directly visible, add/remove/edit, start/stop can all be done in the UI without editing cordis.patch.yml. No need to type commands — search for dsh-skill-mcp-panel directly in the market ①, one-click install, takes effect after refreshing the page (some host-level plugins will say "restart required", just follow the instructions):

Settings → MCP Management: firecrawl server, HTTP type, 26 tools

These two plugins are exactly the footnote to that line at the start of this chapter — everything is a plugin: official UI capabilities that don't exist, community plugins fill in, and once installed they become part of dsh.

There's a lot more to plugin installation and management — command-line installation, bundle auto-mounting, global vs Profile. This chapter just opens a window on it in the MCP scenario; later, a whole chapter will systematically cover plugin installation, then move on to plugin development, and connect all the way to scenario practice.

Common Questions

ProblemHow to handle
Connected but don't see the tool?First check the logs for connection/discovery errors; confirm the server itself is reachable (use a browser or curl to test the endpoint directly); confirm serverName doesn't collide with another server; for auth-required servers, check whether the key is passed correctly (401/403 is usually this)
Where do keys for services like Firecrawl go?Pass via headers in the config (HTTP method), set the key as an environment variable before starting (step 2), don't hardcode in cordis.patch.yml — once the file is committed to Git it could leak
What if the server crashes?The plugin auto-reconnects (500ms initial backoff doubling), tools are still listed during reconnect but calls will fail; after 10 consecutive failures the tools are removed until config reload or restart. Editing config will reload server connections in place, unchanged names stay unchanged
Will it consume too many tokens?Every server's tool description and input schema enters each request. Connect only what you actually use; don't hoard a pile

What you learned in this chapter

You pass if you can complete the items below:

  • [ ] Explain what MCP does, and how dsh plugs into it (one plugin dsh-mcp-client)
  • [ ] Know that tool naming is two levels: one MCP server has multiple tools, after plugging in they appear as mcp__server-name__tool-name
  • [ ] Know how keys for auth-required MCP servers (like Firecrawl) are passed, and why they aren't hardcoded in the config file
  • [ ] Be able to declare an MCP server in cordis.patch.yml (at least one of stdio or streamable-http)
  • [ ] Have the model actually call an MCP tool, and see the mcp__ prefixed call in the Trajectory
  • [ ] When the server fails to connect or crashes, know where to look for errors and how to troubleshoot
  • [ ] Know that for convenience, you can install two community plugins: dsh-market (Plugin Market) and DSH Skill & MCP Panel (MCP visualization)

Open Source · MIT · Community Driven