DeepSeek has an official agent harness called dsh (npm: @deepseek-ai/dsh, source at deepseek-ai/deepseek-harness). It speaks MCP, which means you can hand it tools. We wired it to Nullprint, a multi-profile browser, so a plain-language request turns into: create a browser profile, launch it, open a page, read it, close it.
This is the short version of what it took. Tested with dsh 0.2.1-rc.2 and nullprint-mcp 0.1.3; dsh is still a pre-release, so check its own docs if anything below has moved.
The dsh package on PyPI is not DeepSeek's. Install from npm.
You need Node.js, a DeepSeek API key, and Nullprint running and signed in on the same machine.
npm install -g @deepseek-ai/dsh
export DEEPSEEK_API_KEY=sk-your-key
pipx install nullprint-mcp
dsh has two modes: web (a chat page in your browser) and headless (one task from the command line, then exit). Each is a separate profile with its own config, and the config folder only appears after the profile has run once, so start the one you want (dsh web, or any small headless task) before editing anything.
Add Nullprint to ~/.dsh/profiles/<web or headless>/cordis.patch.yml:
- insert:
- id: mcp-nullprint
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: nullprint
transport: stdio
command: nullprint-mcp
args: []
It has to be wrapped in - insert:. A bare - id: mcp-nullprint only modifies an entry that already exists, so a new entry written that way is ignored, and dsh starts normally without the tools. Check with:
dsh --profile headless --dump-config
If mcp-nullprint is in the output, it loaded. The tools show up as mcp__nullprint__<tool>, e.g. mcp__nullprint__profile_start and mcp__nullprint__session_goto.
No port or key is needed on the same machine: nullprint-mcp reads Nullprint's local connection file by itself.
dsh --profile headless "Use Nullprint to create a new profile, open example.com, tell me the page title, then close the profile."
dsh creates the profile, starts it, navigates, reads the title through eval, and closes it. The new profile appears in the Nullprint app afterwards. After that, requests like "list my profiles and which are running" or "open shop-01 and go to example.com" work the same way. Profile names are case-sensitive.
Set NULLPRINT_DAEMON_URL and NULLPRINT_API_KEY. One gotcha: when dsh launches an MCP server it drops inherited environment variables whose names contain KEY, TOKEN, SECRET or PASSWORD. Exporting NULLPRINT_API_KEY in your shell isn't enough; pass it explicitly in the config:
env:
NULLPRINT_DAEMON_URL: !!js process.env.NULLPRINT_DAEMON_URL
NULLPRINT_API_KEY: !!js process.env.NULLPRINT_API_KEY
Don't paste the key itself into the file.
Full guide: https://nullprint.ai/docs/mcp/dsh/
This post was drafted with AI assistance and reviewed by the Nullprint team.