Convert markdown to a JSON-safe string. One command. Zero config.
echo '# Hello
Said "goodbye" and left.' | mdstr
# → "# Hello\n\nSaid \"goodbye\" and left."You have markdown. You need it inside JSON — for an API call, an LLM prompt, a config file. JSON.stringify handles the escaping, but getting there from a file or stdin is friction. mdstr removes it.
Before:
node -e "process.stdout.write(JSON.stringify(require('fs').readFileSync('README.md','utf-8').replace(/\n$/,'')))"After:
mdstr README.mdnpm install -g mdstrOr use directly with npx — no install needed:
npx mdstr README.mdmdstr README.md
mdstr ./docs/guide.mdcat notes.md | mdstr
echo '# "Hello" World' | mdstr
# → "# \"Hello\" World"By default, mdstr strips the trailing newline. To keep it:
mdstr README.md --preserve-newlineThe output is a valid JSON string (with surrounding quotes), ready to drop into any JSON structure:
jq -n --argjson content "$(mdstr instructions.md)" '{prompt: $content}' > payload.json| Flag | Description |
|---|---|
--preserve-newline |
Keep trailing newline in output |
--version |
Show version number |
--help |
Show help with examples |
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Read/conversion error |
2 |
Invalid usage (file not found, no input) |
mdstr is built to work in automated pipelines and agent tool calls. Predictable output, explicit exit codes, no interactive prompts.
SYSTEM_PROMPT=$(mdstr system-prompt.md)
curl -s https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d "$(jq -n --argjson prompt "$SYSTEM_PROMPT" '{
model: "gpt-4o",
messages: [{role: "system", content: $prompt}]
}')"echo '- line 1
- line 2' | mdstr | jq '{content: .}'
# → {"content": "- line 1\n- line 2"}jq -n \
--argjson system "$(mdstr system.md)" \
--argjson user "$(mdstr user-prompt.md)" \
'{messages: [{role: "system", content: $system}, {role: "user", content: $user}]}'The output is always:
- A single JSON string on stdout (with surrounding quotes)
- Errors on stderr
- Deterministic exit codes
No confirmation prompts. No color codes. No spinners.
Node.js >= 20