Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Markit Markdown Converter

ASecurity

Convert files, URLs, and media to markdown using the markit-ai CLI and SDK with pluggable converters and LLM support.

81 stars
0 votes
0 copies
0 views
Added 9/19/2026
ai-agentstypescriptgoshellbashnodegitapi

Works with

cliapi

Security Analysis

A92/100
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add reason-machines/trending-skills --skill markit-markdown-converter --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Markit Markdown Converter?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Markit Markdown Converter
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/reason-machines-markit-markdown-converter/badge)](https://www.skillsdirectory.com/skills/reason-machines-markit-markdown-converter)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: markit-markdown-converter
description: Convert files, URLs, and media to markdown using the markit-ai CLI and SDK with pluggable converters and LLM support.
triggers:
  - convert PDF to markdown
  - turn a DOCX into markdown
  - extract markdown from a URL
  - convert images or audio to markdown with AI
  - use markit to convert files
  - install markit CLI
  - write a markit plugin
  - use markit as a library in TypeScript
---

# markit-markdown-converter

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

markit converts almost anything to markdown: PDFs, Word docs, PowerPoint, Excel, HTML, EPUB, Jupyter notebooks, RSS feeds, CSV, JSON, YAML, images (with EXIF + AI description), audio (with metadata + AI transcription), ZIP archives, URLs, Wikipedia pages, and source code files. It works as a CLI tool and as a TypeScript/Node.js library, supports pluggable converters, and integrates with OpenAI, Anthropic, and any OpenAI-compatible LLM API.

---

## Installation

```bash
# Global CLI
npm install -g markit-ai

# Or as a project dependency
npm install markit-ai
# bun add markit-ai
# pnpm add markit-ai
```

---

## CLI Quick Reference

```bash
# Convert a file
markit report.pdf
markit document.docx
markit slides.pptx
markit data.xlsx
markit notebook.ipynb

# Convert a URL
markit https://example.com/article
markit https://en.wikipedia.org/wiki/Markdown

# Convert media (requires LLM API key for AI features)
markit photo.jpg
markit recording.mp3
markit diagram.png -p "Describe the architecture and data flow"
markit receipt.jpg -p "List all line items with prices as a table"

# Output options
markit report.pdf -o report.md          # Write to file
markit report.pdf -q                    # Raw markdown only (great for piping)
markit report.pdf --json                # Structured JSON output

# Read from stdin
cat file.pdf | markit -

# Pipe output
markit report.pdf | pbcopy
markit data.xlsx -q | some-other-tool

# List supported formats
markit formats

# Configuration
markit init                              # Create .markit/config.json
markit config show                       # Show resolved config
markit config get llm.model
markit config set llm.provider anthropic
markit config set llm.model claude-haiku-4-5

# Plugins
markit plugin install npm:markit-plugin-dwg
markit plugin install git:github.com/user/markit-plugin-ocr
markit plugin install ./my-plugin.ts
markit plugin list
markit plugin remove dwg

# Agent integration
markit onboard                           # Adds usage instructions to CLAUDE.md
```

---

## AI / LLM Configuration

Images and audio always get free metadata extraction. AI-powered description and transcription requires an API key.

```bash
# OpenAI (default)
export OPENAI_API_KEY=sk-...
markit photo.jpg

# Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
markit config set llm.provider anthropic
markit photo.jpg

# OpenAI-compatible APIs (Ollama, Groq, Together, etc.)
markit config set llm.apiBase http://localhost:11434/v1
markit config set llm.model llama3.2-vision
markit photo.jpg
```

`.markit/config.json` (created by `markit init`):

```json
{
  "llm": {
    "provider": "openai",
    "apiBase": "https://api.openai.com/v1",
    "model": "gpt-4.1-nano",
    "transcriptionModel": "gpt-4o-mini-transcribe"
  }
}
```

Environment variables always override config file values. Never store API keys in the config file — use env vars.

| Provider    | Env Vars                              | Default Vision Model  |
|-------------|---------------------------------------|-----------------------|
| `openai`    | `OPENAI_API_KEY`, `MARKIT_API_KEY`    | `gpt-4.1-nano`        |
| `anthropic` | `ANTHROPIC_API_KEY`, `MARKIT_API_KEY` | `claude-haiku-4-5`    |

---

## SDK Usage

### Basic File and URL Conversion

```typescript
import { Markit } from "markit-ai";

const markit = new Markit();

// Convert a file by path
const { markdown } = await markit.convertFile("report.pdf");
console.log(markdown);

// Convert a URL
const { markdown: webMd } = await markit.convertUrl("https://example.com/article");

// Convert a Buffer with explicit type hint
import { readFileSync } from "fs";
const buffer = readFileSync("document.docx");
const { markdown: docMd } = await markit.convert(buffer, { extension: ".docx" });
```

### With OpenAI for Vision + Transcription

```typescript
import OpenAI from "openai";
import { Markit } from "markit-ai";

const openai = new OpenAI(); // reads OPENAI_API_KEY from env

const markit = new Markit({
  describe: async (image: Buffer, mime: string) => {
    const res = await openai.chat.completions.create({
      model: "gpt-4.1-nano",
      messages: [
        {
          role: "user",
          content: [
            { type: "text", text: "Describe this image in detail." },
            {
              type: "image_url",
              image_url: {
                url: `data:${mime};base64,${image.toString("base64")}`,
              },
            },
          ],
        },
      ],
    });
    return res.choices[0].message.content ?? "";
  },

  transcribe: async (audio: Buffer, mime: string) => {
    const res = await openai.audio.transcriptions.create({
      model: "gpt-4o-mini-transcribe",
      file: new File([audio], "audio.mp3", { type: mime }),
    });
    return res.text;
  },
});

const { markdown } = await markit.convertFile("photo.jpg");
```

### With Anthropic for Vision

```typescript
import Anthropic from "@anthropic-ai/sdk";
import OpenAI from "openai";
import { Markit } from "markit-ai";

const anthropic = new Anthropic(); // reads ANTHROPIC_API_KEY from env
const openai = new OpenAI();       // reads OPENAI_API_KEY from env

// Mix providers: Claude for images, OpenAI Whisper for audio
const markit = new Markit({
  describe: async (image: Buffer, mime: string) => {
    const res = await anthropic.messages.create({
      model: "claude-haiku-4-5",
      max_tokens: 1024,
      messages: [
        {
          role: "user",
          content: [
            {
              type: "image",
              source: {
                type: "base64",
                media_type: mime as "image/jpeg" | "image/png" | "image/gif" | "image/webp",
                data: image.toString("base64"),
              },
            },
            { type: "text", text: "Describe this image." },
          ],
        },
      ],
    });
    return (res.content[0] as { text: string }).text;
  },

  transcribe: async (audio: Buffer, mime: string) => {
    const res = await openai.audio.transcriptions.create({
      model: "gpt-4o-mini-transcribe",
      file: new File([audio], "audio.mp3", { type: mime }),
    });
    return res.text;
  },
});
```

### Using Built-in Providers via Config

```typescript
import { Markit, createLlmFunctions, loadConfig, loadAllPlugins } from "markit-ai";

// Reads .markit/config.json and env vars automatically
const config = loadConfig();

// Load any installed plugins
const plugins = await loadAllPlugins();

// Create instance with built-in providers + plugins
const markit = new Markit(createLlmFunctions(config), plugins);

const { markdown } = await markit.convertFile("report.pdf");
```

---

## Writing a Plugin

Plugins let you add new formats or override built-in converters. Plugin converters run before built-ins.

### Basic Converter Plugin

```typescript
// my-plugin.ts
import type { MarkitPluginAPI } from "markit-ai";

export default function (api: MarkitPluginAPI) {
  api.setName("my-format");
  api.setVersion("1.0.0");

  api.registerConverter(
    {
      name: "myformat",
      accepts: (info) => [".myf", ".myfmt"].includes(info.extension ?? ""),
      convert: async (input: Buffer, info) => {
        // info.extension, info.mimeType, info.fileName available
        const text = input.toString("utf-8");
        const markdown = `# Converted\n\n\`\`\`\n${text}\n\`\`\``;
        return { markdown };
      },
    },
    // Optional: declare so it appears in `markit formats`
    { name: "My Format", extensions: [".myf", ".myfmt"] },
  );
}
```

### Override a Built-in Converter

```typescript
// better-pdf-plugin.ts
import type { MarkitPluginAPI } from "markit-ai";

export default function (api: MarkitPluginAPI) {
  api.setName("better-pdf");
  api.setVersion("1.0.0");

  // Runs before built-in PDF converter, effectively replacing it
  api.registerConverter({
    name: "pdf",
    accepts: (info) => info.extension === ".pdf",
    convert: async (input: Buffer, info) => {
      // Custom PDF extraction logic
      const markdown = `# PDF Content\n\n(extracted with custom logic)`;
      return { markdown };
    },
  });
}
```

### Register a Custom LLM Provider

```typescript
import type { MarkitPluginAPI } from "markit-ai";

export default function (api: MarkitPluginAPI) {
  api.setName("gemini-provider");

  api.registerProvider({
    name: "gemini",
    envKeys: ["GOOGLE_API_KEY"],
    defaultBase: "https://generativelanguage.googleapis.com/v1beta",
    defaultModel: "gemini-2.0-flash",
    create: (config, prompt) => ({
      describe: async (image: Buffer, mime: string) => {
        // Call Gemini API here
        return "Image description from Gemini";
      },
    }),
  });
}
```

### Install and Use a Plugin

```bash
# Install from file
markit plugin install ./my-plugin.ts

# Install from npm
markit plugin install npm:markit-plugin-dwg

# Install from git
markit plugin install git:github.com/user/markit-plugin-ocr

# Verify
markit plugin list

# Remove
markit plugin remove my-format
```

---

## Common Patterns

### Batch Convert a Directory

```typescript
import { Markit } from "markit-ai";
import { readdirSync, readFileSync, writeFileSync } from "fs";
import { extname, basename, join } from "path";

const markit = new Markit();
const inputDir = "./docs";
const outputDir = "./docs-md";

const files = readdirSync(inputDir);
for (const file of files) {
  const ext = extname(file);
  if (![".pdf", ".docx", ".html"].includes(ext)) continue;

  const buffer = readFileSync(join(inputDir, file));
  const { markdown } = await markit.convert(buffer, { extension: ext });
  const outName = basename(file, ext) + ".md";
  writeFileSync(join(outputDir, outName), markdown);
  console.log(`Converted: ${file} → ${outName}`);
}
```

### Convert URL List

```typescript
import { Markit } from "markit-ai";

const markit = new Markit();
const urls = [
  "https://example.com/article-1",
  "https://example.com/article-2",
  "https://en.wikipedia.org/wiki/TypeScript",
];

const results = await Promise.all(
  urls.map(async (url) => {
    const { markdown } = await markit.convertUrl(url);
    return { url, markdown };
  })
);

for (const { url, markdown } of results) {
  console.log(`\n## ${url}\n\n${markdown.slice(0, 200)}...`);
}
```

### CLI in Agent/Automation Scripts

```bash
# Structured JSON for programmatic parsing
markit report.pdf --json

# Raw markdown for piping (no spinner, no extra output)
markit report.pdf -q > report.md

# Pipe into another CLI tool
markit https://example.com/article -q | wc -w

# Process multiple files in a shell loop
for f in docs/*.pdf; do
  markit "$f" -o "out/$(basename "$f" .pdf).md"
done
```

---

## Supported Formats Reference

| Format      | Extensions                              |
|-------------|-----------------------------------------|
| PDF         | `.pdf`                                  |
| Word        | `.docx`                                 |
| PowerPoint  | `.pptx`                                 |
| Excel       | `.xlsx`                                 |
| HTML        | `.html`, `.htm`                         |
| EPUB        | `.epub`                                 |
| Jupyter     | `.ipynb`                                |
| RSS/Atom    | `.rss`, `.atom`, `.xml`                 |
| CSV/TSV     | `.csv`, `.tsv`                          |
| JSON        | `.json`                                 |
| YAML        | `.yaml`, `.yml`                         |
| XML/SVG     | `.xml`, `.svg`                          |
| Images      | `.jpg`, `.png`, `.gif`, `.webp`         |
| Audio       | `.mp3`, `.wav`, `.m4a`, `.flac`         |
| ZIP         | `.zip`                                  |
| Code        | `.py`, `.ts`, `.go`, `.rs`, and more    |
| Plain text  | `.txt`, `.md`, `.rst`, `.log`           |
| URLs        | `http://`, `https://`                   |

Run `markit formats` to see the full live list including any installed plugins.

---

## Troubleshooting

**AI description/transcription not working**
- Ensure the correct env var is set: `OPENAI_API_KEY` or `ANTHROPIC_API_KEY`
- Run `markit config show` to verify the resolved provider and model
- For custom API bases (Ollama, etc.), confirm the server is running and the model supports vision

**Plugin not loading**
- Run `markit plugin list` to confirm it's installed
- Check the plugin exports a default function matching `(api: MarkitPluginAPI) => void`
- Try reinstalling: `markit plugin remove <name>` then `markit plugin install <source>`

**PDF returns empty or garbled markdown**
- The built-in converter uses text extraction (not OCR). Scanned PDFs need an OCR plugin.
- Try a custom plugin or pre-process with an OCR tool first.

**Stdin (`markit -`) not working**
- Pipe content directly: `cat file.pdf | markit -`
- Ensure the file type can be detected from content; use explicit hints if needed.

**Config not being read**
- Config is loaded from `.markit/config.json` relative to the current working directory
- Run `markit init` to create it, then `markit config show` to verify

Attribution

reason-machinesreason-machines
View sourceMore from reason-machines →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Caveman

Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.

1023331 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3331 votes

catchup

Recovers prior coding-agent session context by running `catchup <agent> --since-compact`, which extracts a clean summary of a previous Codex, Claude Code, Antigravity, OpenCode, or Pi Agent session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", or asks to recover/summarize a previous session before continuing. Do NOT use for the current conversation, git history, or any non-agent log.

611 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →