Skip to content

Instantly share code, notes, and snippets.

@markomitranic
Created February 2, 2026 13:27
Show Gist options
  • Select an option

  • Save markomitranic/3f82f4421d9f458f4d5e117217eb07db to your computer and use it in GitHub Desktop.

Select an option

Save markomitranic/3f82f4421d9f458f4d5e117217eb07db to your computer and use it in GitHub Desktop.
Converts OpenAPI spec to Markdown format. Useful for generating LLM docs out of OpenAPI specs.
import { readFileSync, writeFileSync } from 'fs';
/**
* Converts OpenAPI spec to Markdown format. Useful for generating LLM docs out of OpenAPI specs.
* @example node openapi-to-md.mjs openapi.json
* @example node openapi-to-md.mjs openapi.json --no-params
*/
const stripHtml = (str) => str.replace(/<[^>]*>/g, '').replace(/\s+/g, ' ').trim();
const args = process.argv.slice(2);
const includeParams = !args.includes('--no-params');
const inputFile = args.find((a) => !a.startsWith('--'));
const outputFile = args.find((a, i) => !a.startsWith('--') && args[i - 1] === inputFile);
const spec = JSON.parse(readFileSync(inputFile, 'utf-8'));
const lines = [`# ${spec.info?.title || 'API Reference'}\n`];
for (const [path, methods] of Object.entries(spec.paths || {})) {
for (const [method, op] of Object.entries(methods)) {
if (['get', 'post', 'put', 'patch', 'delete'].includes(method)) {
const summary = stripHtml(op.summary || op.operationId || '');
const desc = op.description ? ` - ${stripHtml(op.description.split('\n')[0])}` : '';
let line = `- ${method.toUpperCase()} \`${path}\` ${summary}${desc}`;
if (includeParams) {
const paramNames = [];
// Path/query/header parameters
for (const param of op.parameters || []) {
if (param?.name) paramNames.push(param.name);
}
// Request body schema properties
const schema = op.requestBody?.content?.['application/json']?.schema;
for (const name of Object.keys(schema?.properties || {})) {
if (name) paramNames.push(name);
}
if (paramNames.length) {
line += `|Params:${paramNames.join(',')}`;
}
}
lines.push(line);
}
}
}
const output = outputFile || inputFile.replace('.json', '.md');
writeFileSync(output, lines.join('\n'));
console.log(`Written to ${output}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment