# Your MCP server's tool descriptions are the product: a 40-line Node script to dump and review them

> Source: <https://dev.to/renev3408/your-mcp-servers-tool-descriptions-are-the-product-a-40-line-node-script-to-dump-and-review-them-4ki2>
> Published: 2026-10-12 23:16:19+00:00

Agents pick MCP tools by reading `name`, `description` and `inputSchema` from `tools/list`. If those are vague, the model picks the wrong tool, or skips the right one. Glama recently published an open spec for scoring this (TDQS, [https://tdqs.dev](https://tdqs.dev)), and the main complaint it addresses is inconsistent tool definitions.

Before you submit a server to a directory, read what an agent actually sees. Here is a dependency-free Node script that spawns any stdio MCP server, runs the handshake, and prints every tool.

``` js
// dump-tools.mjs  -  usage: node dump-tools.mjs <command> [args...]
import { spawn } from "node:child_process";

const [cmd, ...args] = process.argv.slice(2);
const p = spawn(cmd, args, { stdio: ["pipe", "pipe", "inherit"] });
let buf = "";
const pending = new Map();
let id = 0;

p.stdout.on("data", (d) => {
  buf += d;
  let i;
  while ((i = buf.indexOf("\n")) >= 0) {
    const line = buf.slice(0, i).trim();
    buf = buf.slice(i + 1);
    if (!line) continue;
    try {
      const m = JSON.parse(line);
      if (m.id != null && pending.has(m.id)) pending.get(m.id)(m);
    } catch {}
  }
});

const send = (method, params) =>
  new Promise((res) => {
    const myId = ++id;
    pending.set(myId, res);
    p.stdin.write(JSON.stringify({ jsonrpc: "2.0", id: myId, method, params }) + "\n");
  });

await send("initialize", {
  protocolVersion: "2024-11-05",
  capabilities: {},
  clientInfo: { name: "dump-tools", version: "0.1.0" },
});
p.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }) + "\n");

const { result } = await send("tools/list", {});
for (const t of result.tools) {
  const props = Object.keys(t.inputSchema?.properties ?? {});
  console.log(`## ${t.name}\n${t.description ?? "(NO DESCRIPTION)"}\nparams: ${props.join(", ") || "none"}\n`);
}
p.kill();
```

`(NO DESCRIPTION)` line is a tool the model has to guess about.`get_user: Gets a user` tells the model nothing. Say what it returns and when to use it instead of a sibling tool.`inputSchema` for its own `description`, units and an example.
A terminal dump is fine for you, but reviewers and users want a readable page. I packaged the same idea as a small zero-dependency CLI called MCP Tool Docs Generator. It connects to a stdio MCP server, calls `initialize` and `tools/list`, and writes a `TOOLS.md`, one Markdown page per tool, and a `tools.json`. It is pay-what-you-want with a $1 minimum: [https://renevibe76.gumroad.com/l/bmzwpm](https://renevibe76.gumroad.com/l/bmzwpm)

The script above is free to copy and enough to audit your own server. The packaged version is for when you want the files generated for your README.
