Read-only Linux port, service and Caddy route map: listening sockets with their owning unit or container, a reverse service view, and reverse_proxy liveness checks. Requires iproute2 (ss); docker and a Caddyfile are optional.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-port-map
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:ozanstn1-stack/dsh-port-map
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Port, service and Caddy route map for DeepSeek Harness.
dsh-port-map answers the questions a busy server keeps asking: what is on
9094? which unit owns this port? is every Caddy route still pointing at
something alive? what is exposed to the internet?
Every tool is read-only. Nothing is opened, closed or reconfigured.
Tools
| Tool | Kind | What it does |
|---|---|---|
listening_ports |
read-only | TCP listening sockets: port, bound address, reachability scope (public / localhost / interface), process, and the systemd unit or docker container that owns it. Filters: scope, port. |
service_map |
read-only | The reverse view: every unit/container with the ports it listens on, plus the ports nothing claims. |
caddy_routes |
read-only | Parses the Caddyfile into site → path → reverse_proxy upstream, then checks each upstream against the listening sockets. |
url_check |
read-only | HTTP status, latency and content type for an allow-listed host. A redirect is reported, not followed. |
Example output
Listening TCP sockets (39):
port address scope owner
8790 127.0.0.1 localhost dsh-web.service
1933 127.0.0.1 localhost docker:openviking
9090 0.0.0.0 public map-service.service
Bound to all interfaces: 22, 443, 8642, 8799, 9090, 9091, 9094, 11434
Caddy routes (11) from /etc/caddy/Caddyfile:
example.org /panel → 127.0.0.1:8788 · up (vps-panel.service)
example.org /gone → 127.0.0.1:9999 · DOWN
Install
dsh plugin --profile web add dsh-port-map
systemctl restart dsh-web # or restart your DSH process
- id: port-map
config:
caddyfile: /etc/caddy/Caddyfile
urlCheck:
hosts:
- 127.0.0.1
- localhost
- example.org
timeoutMs: 10000
docker: true
safety:
timeoutMs: 15000
maxOutputBytes: 65536
Configuration
| Key | Default | Meaning |
|---|---|---|
caddyfile |
/etc/caddy/Caddyfile |
File parsed by caddy_routes. |
urlCheck.hosts |
["127.0.0.1", "localhost"] |
Hosts url_check may request; everything else is refused. |
urlCheck.timeoutMs |
10000 |
Per-request timeout. |
docker |
true |
Resolve container names for published ports. |
safety.timeoutMs |
15000 |
Default command timeout. |
safety.maxOutputBytes |
65536 |
Output cap per call. |
How the owner is resolved
ss -tlnpHgives the socket, its bound address and the owning PID.- The PID's cgroup gives the systemd unit (
/proc/<pid>/cgroup). - A
docker-proxysocket is matched to its container through the published port (docker ps --format '{{.Names}}\t{{.Ports}}'), so the map showsdocker:openvikingrather thandocker.service.
Nothing is guessed: an unclaimed socket is reported as unowned:<process>.
Honest limits
- Read-only: it reports, it does not fix. No firewall changes, no restarts.
- The Caddyfile parser understands site blocks,
handle/handle_pathandreverse_proxy(with or without an options block).!!jsexpressions, imported snippets orphp_fastcgi-style directives are not modelled and are simply not reported. - Docker name resolution needs
docker psto work for the current user; without it the socket is still listed with itsdocker:<id>marker. url_checknever follows a redirect, so a redirect chain is reported as one hop, not resolved to the final page.
Requirements
- DSH
>= 0.2.1-rc.4(Node^22.19.0 || >=24.0.0). ss(iproute2) for the socket tools;dockeroptional; the Caddyfile optional.
Development
npm run link-peers
node --test
License
MIT
Links
More in this category
DayuanJiang/next-ai-draw-io#dsh-plugin★ 36548
Draws draw.io diagrams in DeepSeek Harness through the next-ai-drawio MCP server: the link in the reply opens a live preview in the right sidebar, you can edit the diagram by hand, and each AI change is a version you can restore. Node.js 18+; npx downloads the MCP server on first use.
Tencent/WeKnora#dsh-weknora★ 36201
Four read-only tools over a WeKnora knowledge base: list knowledge bases, hybrid passage search, reassemble one document's chunks in order, and WeKnora's own cited RAG or ReAct-agent answer with a resumable session id.
superdesigndev/treg★ 6962
Tool catalog for agents: search ~2,600 external endpoints (SEO and SERP, backlinks, social, people and company enrichment, ad libraries, scraping) by the task you want done, read each one's parameters and per-call price, then call it with the credential injected server-side. Ships the skill plus an MCP row that stays disabled until TREG_TOKEN is set.
T-Auto/dsh-ops★ 5011
Provides bash, PowerShell 7, and high-performance Rust tools for DSH on Windows to reduce token usage.
sixtysevenlf/dsh-blender-plugin★ 1536
Lets a DSH agent drive a local Blender over a direct TCP channel with 15 tools: viewport frames, custom-angle renders, Python execution, headless and job offload, transaction rollback, and a planning layer of 228 ops across 34 families.
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1153
Tencent CloudBase backend for DeepSeek Harness — scaffold and deploy full-stack apps from chat, render query results as table cards with paging, sorting and CSV export, preview a deployment on its domain, and call the CloudBase MCP toolset (`mcp__cloudbase__*`) with device-code login.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.