Skill: karmanverma/markitdown-skill (version 1.0.1)

--- name: markitdown-skill description: OpenClaw agent skill for converting documents to Markdown. Documentation and utilities for Microsoft's MarkItDown library. Supports PDF, Word, PowerPoint, Excel, images (OCR), audio (transcription), HTML, YouTube. metadata: openclaw: emoji: "📄" homepage: https://github.com/karmanverma/markitdown-skill requires: bins: ["python3", "pip", "markitdown"] install: - id: "markitdown" kind: "pip" package: "markitdown[all]" bins: ["markitdown"] label: "Install MarkItDown CLI (pip)" --- # MarkItDown Skill Documentation and utilities for converting documents to Markdown using Microsoft's [MarkItDown](https://github.com/microsoft/markitdown) library. > **Note:** This skill provides documentation and a batch script. The actual conversion is done by the `markitdown` CLI/library installed via pip. ## When to Use **Use markitdown for:** - 📄 Fetching documentation (README, API docs) - 🌐 Converting web pages to markdown - 📝 Document analysis (PDFs, Word, PowerPoint) - 🎬 YouTube transcripts - 🖼️ Image text extraction (OCR) - 🎤 Audio transcription ## Quick Start ```bash # Convert file to markdown markitdown document.pdf -o output.md # Convert URL markitdown https://example.com/docs -o docs.md ``` ## Supported Formats | Format | Features | |--------|----------| | PDF | Text extraction, structure | | Word (.docx) | Headings, lists, tables | | PowerPoint | Slides, text | | Excel | Tables, sheets | | Images | OCR + EXIF metadata | | Audio | Speech transcription | | HTML | Structure preservation | | YouTube | Video transcription | ## Installation The skill requires Microsoft's `markitdown` CLI: ```bash pip install 'markitdown[all]' ``` Or install specific formats only: ```bash pip install 'markitdown[pdf,docx,pptx]' ``` ## Common Patterns ### Fetch Documentation ```bash markitdown https://github.com/user/repo/blob/main/README.md -o readme.md ``` ### Convert PDF ```bash markitdown document.pdf -o document.md ``` ### Batch Convert ```bash # Using included script python ~/.openclaw/skills/markitdown/scripts/batch_convert.py docs/*.pdf -o markdown/ -v # Or shell loop for file in docs/*.pdf; do markitdown "$file" -o "${file%.pdf}.md" done ``` ## Python API ```python from markitdown import MarkItDown md = MarkItDown() result = md.convert("document.pdf") print(result.text_content) ``` ## Troubleshooting ### "markitdown not found" ```bash pip install 'markitdown[all]' ``` ### OCR Not Working ```bash # Ubuntu/Debian sudo apt-get install tesseract-ocr # macOS brew install tesseract ``` ## What This Skill Provides | Component | Source | |-----------|--------| | `markitdown` CLI | Microsoft's pip package | | `markitdown` Python API | Microsoft's pip package | | `scripts/batch_convert.py` | This skill (utility) | | Documentation | This skill | ## See Also - [USAGE-GUIDE.md](USAGE-GUIDE.md) - Detailed examples - [reference.md](reference.md) - Full API reference - [Microsoft MarkItDown](https://github.com/microsoft/markitdown) - Upstream library

path: POST_INSTALL.md
content: # Post-Install Setup

MarkItDown skill installed! Here's how to get started.

## 1. Verify Installation

```bash
markitdown --version
```

If not found, install the CLI:
```bash
pip install 'markitdown[all]'
```

## 2. Test It

```bash
# Convert a PDF
markitdown document.pdf -o output.md

# Convert a URL
markitdown https://example.com -o page.md
```

## 3. Add to Agent Instructions (Recommended)

Add to your `AGENTS.md`:

```markdown
## Document Conversion
When fetching documentation or converting files:
- Use `markitdown <url>` instead of curl/wget for web docs
- Use `markitdown <file>` to convert PDFs, Word, Excel, etc.
- Output is clean markdown optimized for LLM analysis
```

## 4. Install Format-Specific Dependencies

Only install what you need:

```bash
pip install 'markitdown[pdf]'      # PDF support
pip install 'markitdown[docx]'     # Word documents
pip install 'markitdown[pptx]'     # PowerPoint
pip install 'markitdown[xlsx]'     # Excel
pip install 'markitdown[audio-transcription]'   # Audio
pip install 'markitdown[youtube-transcription]' # YouTube
```

Or install everything:
```bash
pip install 'markitdown[all]'
```

## 5. System Dependencies (Optional)

### OCR (for images)
```bash
# Ubuntu/Debian
sudo apt-get install tesseract-ocr

# macOS
brew install tesseract
```

## Quick Reference

```bash
# File conversion
markitdown file.pdf -o output.md

# URL conversion
markitdown https://example.com -o page.md

# Batch conversion
python ~/.openclaw/skills/markitdown/scripts/batch_convert.py docs/*.pdf -o markdown/ -v
```

## Troubleshooting

**"markitdown not found"**
```bash
pip install 'markitdown[all]'
```

**"No module named 'xxx'"**
```bash
pip install 'markitdown[pdf]'  # or docx, pptx, etc.
```

**OCR not working**
```bash
sudo apt-get install tesseract-ocr
```


path: README.md
content: # markitdown-skill

📄 OpenClaw agent skill for converting documents to Markdown.

**Documentation and utilities** for Microsoft's [MarkItDown](https://github.com/microsoft/markitdown) library.

**Author:** Karman Verma

## What This Skill Is

This skill provides:
- ✅ Documentation for using MarkItDown
- ✅ A batch conversion script (`scripts/batch_convert.py`)
- ✅ Usage examples and API reference

The actual document conversion is done by Microsoft's `markitdown` CLI, installed separately via pip.

## Install

### Via ClawHub
```bash
clawhub install markitdown-skill
pip install 'markitdown[all]'  # Install the CLI
```

### Manual
```bash
cd ~/.openclaw/skills
git clone https://github.com/karmanverma/markitdown-skill.git markitdown
pip install 'markitdown[all]'
```

## Quick Start

```bash
# Convert PDF
markitdown document.pdf -o output.md

# Fetch web docs
markitdown https://example.com/docs -o docs.md

# Batch convert
python ~/.openclaw/skills/markitdown/scripts/batch_convert.py docs/*.pdf -o markdown/
```

## Supported Formats

| Format | Features |
|--------|----------|
| PDF | Text extraction |
| Word (.docx) | Headings, lists, tables |
| PowerPoint | Slides, text |
| Excel | Tables, sheets |
| Images | OCR + metadata |
| Audio | Speech transcription |
| HTML | Structure preservation |
| YouTube | Video transcription |

## Documentation

- [SKILL.md](SKILL.md) - Main documentation
- [USAGE-GUIDE.md](USAGE-GUIDE.md) - Detailed examples
- [reference.md](reference.md) - Full API reference
- [POST_INSTALL.md](POST_INSTALL.md) - Setup guide

## Credits

- **Upstream library:** [Microsoft MarkItDown](https://github.com/microsoft/markitdown) by AutoGen Team
- **This skill:** Karman Verma

## License

MIT


path: USAGE-GUIDE.md
content: # MarkItDown Usage Guide

Detailed examples and patterns for document conversion.

## CLI Usage

### Basic Conversion

```bash
# To stdout
markitdown document.pdf

# To file
markitdown document.pdf -o output.md

# From stdin
cat document.pdf | markitdown > output.md
```

### Web Content

```bash
# Fetch and convert URL
markitdown https://example.com/docs -o docs.md

# GitHub README
markitdown https://raw.githubusercontent.com/user/repo/main/README.md
```

### Batch Processing

```bash
# Convert all PDFs
for file in *.pdf; do
  markitdown "$file" -o "${file%.pdf}.md"
done

# Using the included script
python scripts/batch_convert.py docs/*.pdf -o markdown/ -v
```

### Advanced Options

```bash
# Enable plugins
markitdown --use-plugins file.pdf

# List plugins
markitdown --list-plugins

# Azure Document Intelligence (complex PDFs)
markitdown file.pdf -d -e "<endpoint>" -o output.md
```

---

## Python API

### Basic Usage

```python
from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("document.pdf")
print(result.text_content)
```

### With LLM Image Descriptions

```python
from markitdown import MarkItDown
from openai import OpenAI

client = OpenAI()
md = MarkItDown(
    llm_client=client,
    llm_model="gpt-4o",
    llm_prompt="Describe this image in detail"
)
result = md.convert("image.jpg")
print(result.text_content)
```

### Azure Document Intelligence

```python
from markitdown import MarkItDown

md = MarkItDown(docintel_endpoint="https://your-endpoint.cognitiveservices.azure.com/")
result = md.convert("complex-layout.pdf")
print(result.text_content)
```

### Batch Processing

```python
from markitdown import MarkItDown
from pathlib import Path

md = MarkItDown()

for pdf_file in Path("docs/").glob("*.pdf"):
    result = md.convert(str(pdf_file))
    output_path = pdf_file.with_suffix(".md")
    output_path.write_text(result.text_content)
```

### Error Handling

```python
from markitdown import MarkItDown

md = MarkItDown()

try:
    result = md.convert("file.pdf")
    print(result.text_content)
except ImportError as e:
    print(f"Missing dependency: {e}")
    print("Install with: pip install 'markitdown[pdf]'")
except Exception as e:
    print(f"Conversion failed: {e}")
```

---

## Format-Specific Examples

### PDF Documents

```bash
# Simple extraction
markitdown document.pdf -o document.md

# Complex layouts (Azure)
markitdown document.pdf -d -e "<endpoint>" -o document.md
```

### PowerPoint Presentations

```bash
markitdown presentation.pptx -o slides.md
```

```python
# With LLM image descriptions
from openai import OpenAI
md = MarkItDown(llm_client=OpenAI(), llm_model="gpt-4o")
result = md.convert("presentation.pptx")
```

### Excel Spreadsheets

```bash
markitdown spreadsheet.xlsx -o data.md
```

Output format:
```markdown
## Sheet1

| Column A | Column B | Column C |
|----------|----------|----------|
| Data 1   | Data 2   | Data 3   |
```

### Images (OCR)

```bash
# Requires Tesseract OCR
markitdown scanned-document.jpg -o extracted.md
```

### Audio Transcription

```bash
pip install 'markitdown[audio-transcription]'
markitdown recording.mp3 -o transcript.md
```

### YouTube Videos

```bash
pip install 'markitdown[youtube-transcription]'
markitdown "https://youtube.com/watch?v=VIDEO_ID" -o transcript.md
```

### ZIP Archives

```bash
# Iterates over all files inside
markitdown archive.zip -o contents.md
```

---

## Integration Patterns

### LLM Document Analysis

```python
from markitdown import MarkItDown
from openai import OpenAI

md = MarkItDown()
client = OpenAI()

# Convert document
result = md.convert("contract.pdf")

# Analyze with LLM
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "Analyze this contract for key terms"},
        {"role": "user", "content": result.text_content}
    ]
)
print(response.choices[0].message.content)
```

### RAG Pipeline

```python
from markitdown import MarkItDown

md = MarkItDown()

# Convert knowledge base
documents = []
for file in ["doc1.pdf", "doc2.docx", "doc3.pptx"]:
    result = md.convert(file)
    documents.append({
        "source": file,
        "content": result.text_content
    })

# Feed to vector database...
```

### LangChain Integration

```python
from markitdown import MarkItDown
from langchain.docstore.document import Document

md = MarkItDown()

def load_document(file_path):
    result = md.convert(file_path)
    return Document(
        page_content=result.text_content,
        metadata={"source": file_path}
    )
```

### FastAPI Endpoint

```python
from fastapi import FastAPI, UploadFile
from markitdown import MarkItDown

app = FastAPI()
md = MarkItDown()

@app.post("/convert")
async def convert_file(file: UploadFile):
    content = await file.read()
    result = md.convert(content)
    return {"markdown": result.text_content}
```

---

## Performance Tips

1. **Reuse MarkItDown instance** for batch processing
2. **Reduce image resolution** if OCR speed matters
3. **Use Azure Document Intelligence** for complex PDF layouts
4. **Audio transcription** is roughly real-time

## Output Format

MarkItDown preserves:
- Headings (H1-H6)
- Lists (ordered/unordered)
- Tables
- Links
- Code blocks
- Images (as markdown syntax)

**Note:** Optimized for LLM consumption, not pixel-perfect reproduction.


path: package.json
content: {
  "name": "markitdown-skill",
  "version": "1.0.1",
  "description": "OpenClaw agent skill - documentation and utilities for Microsoft's MarkItDown library",
  "author": "Karman Verma",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/karmanverma/markitdown-skill.git"
  },
  "keywords": [
    "openclaw",
    "skill",
    "markitdown",
    "markdown",
    "pdf",
    "document",
    "conversion"
  ]
}


path: reference.md
content: # MarkItDown API Reference

## MarkItDown Class

### Constructor

```python
class MarkItDown:
    def __init__(
        self,
        enable_plugins: bool = False,
        llm_client = None,
        llm_model: str = None,
        llm_prompt: str = None,
        docintel_endpoint: str = None
    )
```

**Parameters:**
- `enable_plugins` (bool): Enable 3rd-party plugins (default: False)
- `llm_client`: OpenAI-compatible client for image descriptions
- `llm_model` (str): Model name for image descriptions (e.g., "gpt-4o")
- `llm_prompt` (str): Custom prompt for image descriptions
- `docintel_endpoint` (str): Azure Document Intelligence endpoint

**Example:**
```python
from markitdown import MarkItDown

# Basic usage
md = MarkItDown()

# With plugins
md = MarkItDown(enable_plugins=True)

# With LLM image descriptions
from openai import OpenAI
client = OpenAI()
md = MarkItDown(llm_client=client, llm_model="gpt-4o")

# With Azure Document Intelligence
md = MarkItDown(docintel_endpoint="https://your-endpoint.cognitiveservices.azure.com/")
```

### convert() Method

```python
def convert(
    self,
    source: str | Path | bytes | BinaryIO
) -> ConversionResult
```

**Parameters:**
- `source`: File path (str/Path), bytes, or file-like object (binary mode)

**Returns:**
- `ConversionResult` object with `text_content` attribute

**Example:**
```python
# From file path
result = md.convert("document.pdf")

# From bytes
with open("document.pdf", "rb") as f:
    result = md.convert(f.read())

# From file-like object
with open("document.pdf", "rb") as f:
    result = md.convert(f)

print(result.text_content)
```

### convert_stream() Method

```python
def convert_stream(
    self,
    stream: BinaryIO,
    file_extension: str = None
) -> ConversionResult
```

**Parameters:**
- `stream` (BinaryIO): Binary file-like object (e.g., open file, io.BytesIO)
- `file_extension` (str): Optional file extension hint

**Returns:**
- `ConversionResult` object

**Example:**
```python
import io

# From BytesIO
data = io.BytesIO(pdf_bytes)
result = md.convert_stream(data, file_extension=".pdf")
```

## ConversionResult

```python
class ConversionResult:
    text_content: str  # Markdown output
```

**Attributes:**
- `text_content` (str): The converted markdown content

## CLI Usage

### Basic Commands

```bash
# Convert to stdout
markitdown <file>

# Convert to file
markitdown <file> -o <output.md>

# Pipe input
cat <file> | markitdown
```

### Options

```bash
markitdown --help
markitdown --list-plugins
markitdown --use-plugins <file>
markitdown <file> -d -e <endpoint>  # Azure Doc Intelligence
```

## Format-Specific Details

### PDF
- **Best for:** Text-based PDFs
- **Limitations:** Complex layouts may need Azure Document Intelligence
- **Dependencies:** `pip install 'markitdown[pdf]'`

### PowerPoint (.pptx)
- **Extracts:** Slide text, structure
- **Enhanced with:** LLM image descriptions
- **Dependencies:** `pip install 'markitdown[pptx]'`

### Word (.docx)
- **Preserves:** Headings, lists, tables, links
- **Dependencies:** `pip install 'markitdown[docx]'`

### Excel (.xlsx, .xls)
- **Extracts:** Tables, multiple sheets
- **Format:** Markdown tables
- **Dependencies:** `pip install 'markitdown[xlsx]'` or `'markitdown[xls]'`

### Images (jpg, png, etc.)
- **Extracts:** EXIF metadata + OCR text
- **Requires:** Tesseract OCR system dependency
- **Enhanced with:** LLM descriptions

### Audio (wav, mp3)
- **Extracts:** EXIF metadata + speech transcription
- **Dependencies:** `pip install 'markitdown[audio-transcription]'`
- **Note:** System audio libraries may be required

### YouTube
- **Extracts:** Video transcription (if available)
- **Dependencies:** `pip install 'markitdown[youtube-transcription]'`
- **Usage:** `markitdown "https://youtube.com/watch?v=VIDEO_ID"`

### HTML
- **Preserves:** Document structure
- **No extra dependencies**

### CSV/JSON/XML
- **Converts:** To readable markdown format
- **No extra dependencies**

### ZIP
- **Behavior:** Iterates over all files inside
- **No extra dependencies**

### EPUB
- **Extracts:** eBook content
- **No extra dependencies**

## Environment Requirements

### Python Version
- **Required:** Python 3.10 or higher
- **Recommended:** Python 3.12

### Virtual Environment (Recommended)

```bash
# Standard Python
python -m venv .venv
source .venv/bin/activate

# uv
uv venv --python=3.12 .venv
source .venv/bin/activate

# Conda
conda create -n markitdown python=3.12
conda activate markitdown
```

### System Dependencies

**Tesseract OCR** (for image text extraction):
```bash
# Ubuntu/Debian
sudo apt-get install tesseract-ocr

# macOS
brew install tesseract

# Windows
# Download installer from: https://github.com/UB-Mannheim/tesseract/wiki
```

**Audio libraries** (for audio transcription):
- Platform-specific dependencies for speech_recognition library
- Check: https://github.com/Uberi/speech_recognition

## Azure Document Intelligence

For high-quality PDF conversion with complex layouts:

### Setup

1. Create Azure Document Intelligence resource
2. Get endpoint and API key
3. Set environment variable: `AZURE_DOCUMENT_INTELLIGENCE_KEY=<your-key>`

### Usage

**CLI:**
```bash
markitdown document.pdf -d -e "<endpoint>" -o output.md
```

**Python:**
```python
md = MarkItDown(docintel_endpoint="<endpoint>")
result = md.convert("document.pdf")
```

### More Info
https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/

## Plugin System

### Finding Plugins
Search GitHub for: `#markitdown-plugin`

### Using Plugins

**CLI:**
```bash
markitdown --list-plugins
markitdown --use-plugins file.pdf
```

**Python:**
```python
md = MarkItDown(enable_plugins=True)
```

### Creating Plugins
See: `packages/markitdown-sample-plugin` in the repository

## Error Handling

### Common Issues

**Missing dependencies:**
```python
try:
    result = md.convert("file.pdf")
except ImportError as e:
    print(f"Missing dependency: {e}")
    print("Install with: pip install 'markitdown[pdf]'")
```

**File format not supported:**
```python
try:
    result = md.convert("file.unknown")
except ValueError as e:
    print(f"Unsupported format: {e}")
```

**Conversion errors:**
```python
try:
    result = md.convert("file.pdf")
except Exception as e:
    print(f"Conversion failed: {e}")
```

## Performance Tips

1. **Batch processing:** Reuse MarkItDown instance
2. **Large files:** Consider chunking or streaming
3. **OCR:** Reduce image resolution if speed matters
4. **Audio:** Expect real-time or slower transcription
5. **Azure Doc Intel:** Best for complex PDFs, costs apply

## Output Format Notes

- **Goal:** LLM-friendly markdown, not pixel-perfect reproduction
- **Structure:** Preserves headings, lists, tables, links
- **Images:** Converted to markdown image syntax
- **Tables:** Converted to markdown tables (may lose complex formatting)
- **Styling:** Bold, italic preserved when possible
- **Layout:** Linear document structure (no multi-column preservation)

## Integration Examples

### LangChain Document Loader

```python
from markitdown import MarkItDown
from langchain.docstore.document import Document

md = MarkItDown()

def load_document(file_path):
    result = md.convert(file_path)
    return Document(
        page_content=result.text_content,
        metadata={"source": file_path}
    )
```

### LlamaIndex Document

```python
from markitdown import MarkItDown
from llama_index import Document

md = MarkItDown()

def create_llama_doc(file_path):
    result = md.convert(file_path)
    return Document(text=result.text_content)
```

### FastAPI Endpoint

```python
from fastapi import FastAPI, UploadFile
from markitdown import MarkItDown

app = FastAPI()
md = MarkItDown()

@app.post("/convert")
async def convert_file(file: UploadFile):
    content = await file.read()
    result = md.convert(content)
    return {"markdown": result.text_content}
```

## Breaking Changes (v0.0.1 → v0.1.0)

1. **Dependencies:** Now organized into feature groups
   - Use `pip install 'markitdown[all]'` for backward compatibility

2. **convert_stream():** Now requires binary file-like objects
   - Changed from text (io.StringIO) to binary (io.BytesIO)

3. **DocumentConverter:** Interface changed to streams instead of paths
   - No temporary files created anymore
   - Plugin authors need to update code

## Resources

- **GitHub:** https://github.com/microsoft/markitdown
- **PyPI:** https://pypi.org/project/markitdown/
- **Issues:** https://github.com/microsoft/markitdown/issues
- **Contributing:** See CONTRIBUTING.md in repository


path: scripts/batch_convert.py
content: #!/usr/bin/env python3
"""
Batch convert multiple files to markdown using MarkItDown
"""

import sys
import argparse
from pathlib import Path
from markitdown import MarkItDown


def convert_file(md_converter, input_path, output_dir=None, verbose=False):
    """Convert a single file to markdown"""
    input_path = Path(input_path)
    
    if not input_path.exists():
        print(f"Error: {input_path} not found", file=sys.stderr)
        return False
    
    # Determine output path
    if output_dir:
        output_dir = Path(output_dir)
        output_dir.mkdir(parents=True, exist_ok=True)
        output_path = output_dir / f"{input_path.stem}.md"
    else:
        output_path = input_path.with_suffix(".md")
    
    try:
        if verbose:
            print(f"Converting: {input_path}")
        
        result = md_converter.convert(str(input_path))
        output_path.write_text(result.text_content)
        
        if verbose:
            print(f"Saved to: {output_path}")
        
        return True
    
    except Exception as e:
        print(f"Error converting {input_path}: {e}", file=sys.stderr)
        return False


def main():
    parser = argparse.ArgumentParser(
        description="Batch convert files to markdown using MarkItDown"
    )
    parser.add_argument(
        "files",
        nargs="+",
        help="Files to convert (supports glob patterns)"
    )
    parser.add_argument(
        "-o", "--output-dir",
        help="Output directory (default: same as input file)"
    )
    parser.add_argument(
        "-p", "--plugins",
        action="store_true",
        help="Enable plugins"
    )
    parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="Verbose output"
    )
    parser.add_argument(
        "--llm-model",
        help="LLM model for image descriptions (e.g., gpt-4o)"
    )
    parser.add_argument(
        "--docintel-endpoint",
        help="Azure Document Intelligence endpoint"
    )
    
    args = parser.parse_args()
    
    # Initialize MarkItDown
    md_kwargs = {"enable_plugins": args.plugins}
    
    if args.llm_model:
        try:
            from openai import OpenAI
            client = OpenAI()
            md_kwargs["llm_client"] = client
            md_kwargs["llm_model"] = args.llm_model
        except ImportError:
            print("Error: openai package required for LLM features", file=sys.stderr)
            print("Install with: pip install openai", file=sys.stderr)
            sys.exit(1)
    
    if args.docintel_endpoint:
        md_kwargs["docintel_endpoint"] = args.docintel_endpoint
    
    md = MarkItDown(**md_kwargs)
    
    # Process files
    success_count = 0
    total_count = 0
    
    for file_pattern in args.files:
        # Handle glob patterns
        if "*" in file_pattern or "?" in file_pattern:
            files = list(Path(".").glob(file_pattern))
        else:
            files = [Path(file_pattern)]
        
        for file_path in files:
            total_count += 1
            if convert_file(md, file_path, args.output_dir, args.verbose):
                success_count += 1
    
    # Summary
    if args.verbose or total_count > 1:
        print(f"\nConverted {success_count}/{total_count} files")
    
    sys.exit(0 if success_count == total_count else 1)


if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)