ProvenPin Install

markdown-it render with custom plugin: working versions (tested 2026-10-15)

Render Markdown to HTML with markdown-it and a small custom plugin that rewrites link targets offline.

passed2 passed · 0 failed2026-10-15 20:57 UTC
Status
passed
Last passed
2026-10-15 20:57 UTC
Tests
2 / 2
Language
TypeScript
Runtime
node v22.23.3
pinned versions4
markdown-it@15.0.2@types/markdown-it@14.2.0@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 38805962781

The code

Exactly the files that passed. Your agent can pull them with get_recipe("markdown-it-render-plugin") (install), or see them on GitHub.

package.json
{
  "name": "markdown-it-render-plugin",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "markdown-it": "15.0.2"
  },
  "devDependencies": {
    "@types/node": "26.6.5",
    "tsx": "4.23.15",
    "@types/markdown-it": "14.2.0"
  }
}
src/render.ts
import MarkdownIt from "markdown-it";

export function createRenderer() {
  const md = new MarkdownIt({ html: false, linkify: true });
  md.use((instance) => {
    const defaultRender =
      instance.renderer.rules.link_open ||
      ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));
    instance.renderer.rules.link_open = (tokens, idx, options, env, self) => {
      const token = tokens[idx]!;
      const aIndex = token.attrIndex("target");
      if (aIndex < 0) token.attrPush(["target", "_blank"]);
      else token.attrs![aIndex]![1] = "_blank";
      return defaultRender(tokens, idx, options, env, self);
    };
  });
  return md;
}

export function renderMarkdown(source: string) {
  return createRenderer().render(source);
}
test/render.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { renderMarkdown } from "../src/render.ts";

test("renders headings and emphasis", () => {
  const html = renderMarkdown("# Hello\n\n*world*");
  assert.match(html, /<h1>Hello<\/h1>/);
  assert.match(html, /<em>world<\/em>/);
});

test("plugin sets target blank on links", () => {
  const html = renderMarkdown("[docs](https://example.com)");
  assert.match(html, /target="_blank"/);
  assert.match(html, /href="https:\/\/example.com"/);
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.