---
name: mdapi-conversion
description: Convert documents, webpages, images, and text to Markdown or structured JSON using mdapi.io. Handles URL conversion, file upload, prompt-based processing, streaming, token activation, manual and autonomous payment flows, and MCP/OpenAI-compatible access.
version: 1.0.0
---

# mdapi.io Skill

## Purpose

Use mdapi.io when the user wants to convert a webpage, document, image, or plain text into Markdown or JSON-like structured output, summarize or extract information with a prompt, or access the service through MCP or an OpenAI-compatible endpoint.

## Philosophy

mdapi.io is minimal by design: every response is pure Markdown or JSON. No HTML, no CSS, no JavaScript. This ensures clean context for any LLM or autonomous agent.
- `GET /` always returns Markdown.
- `POST /` always returns JSON.
- The `result` parameter controls output completeness: `markdown`, `prompt`, or `both`.

## When to use this skill

Use this skill when the task includes any of the following:
- Convert a public URL to Markdown.
- Convert an uploaded file to Markdown.
- Process raw text into Markdown or prompt-driven output.
- Summarize, extract, classify, or transform content with a `prompt`.
- Use streaming for long-running or large conversions.
- Activate and use a paid token.
- Handle manual payment or autonomous agent payment flows.
- Use the OpenAI-compatible chat endpoint.
- Use MCP discovery and tool calls.

## Core behavior

1. Identify the input type: `url`, `file`, or `text`.
2. Choose the simplest valid endpoint.
3. Use `GET /` for direct Markdown output.
4. Use `POST /` for JSON output or file upload.
5. If `prompt` is provided, set `result` explicitly.
6. Prefer `result=both` when both raw conversion and prompt result are useful.
7. Use streaming only when the output is large or incremental delivery is beneficial.
8. Treat all requests as stateless and in-memory; do not assume session persistence.

## Supported formats

Documents:
- PDF
- DOCX
- XLSX
- XLS
- ODT
- ODS

Images:
- JPEG
- JPG
- PNG
- WebP
- SVG

Text:
- HTML
- XML
- JSON
- CSV
- TXT

Webpages:
- Any publicly accessible URL

## Limits

- Max file size: 100 MB
- Max URL content: 50 MB
- Rate limit: 10,000 requests per hour
- Free tier: 10 requests per day, no token required
- Paid tier: $0.01 per conversion
- Token validity: 1 year

## Request selection

### Use GET / when:
- The user wants direct Markdown output.
- The input is a URL or plain text.
- You do not need multipart upload.
- You want the simplest response path.

### Use POST / when:
- The user uploads a file.
- You want a JSON response.
- You want `markdown`, `prompt_result`, and metadata together.
- You need programmatic handling.

### Use POST /v1/chat/completions when:
- The client expects OpenAI-compatible chat format.
- The request contains messages with URLs, images, or files.
- You want streaming chat-completion semantics.

### Use MCP when:
- The host environment supports MCP discovery and tool calls.
- The agent should discover mdapi.io as a tool provider.

## Response rules

### GET /
- Always returns Markdown as plain text.
- Use query parameters for input and behavior control.

Supported query parameters:
- `url`
- `text`
- `prompt`
- `result`
- `stream`
- `token`
- `memo`

### POST /
- Always returns JSON.
- Use form data or multipart form data.

Expected JSON fields may include:
- `success`
- `markdown`
- `prompt_result`
- `resource`
- `mimetype`
- `token_status`
- `token_balance`
- `token_expires`

## Result parameter

Use `result` to control how much output is returned.

- `markdown`: return converted Markdown only.
- `prompt`: return only the result of prompt processing.
- `both`: return both the Markdown and the prompt result.

Rules:
- If `prompt` is present and both outputs are useful, use `result=both`.
- If the user explicitly asks for extracted or transformed output only, use `result=prompt`.
- If the user asks for plain conversion, use `result=markdown`.

## Prompt usage

Use `prompt` for:
- Summarization
- Key point extraction
- JSON transformation
- Classification
- Entity extraction
- Content analysis

Examples:
- `prompt=Summarize this document`
- `prompt=Extract key points`
- `prompt=Convert this content to JSON`
- `prompt=Analyze and explain`

## Authentication

Preferred:
- `Authorization: Bearer TOKEN`

Legacy:
- `X-Token-Required: TOKEN`
- `?token=TOKEN`

## Token activation

A paid token must be activated once before normal use.

### Activation rule
On the first paid request, include both:
- the token
- the payment memo

After successful activation, subsequent requests use the token only.

### Accepted activation styles
- `Authorization: Bearer TOKEN` with `X-Memo-Required: MEMO`
- `X-Token-Required: TOKEN` with `X-Memo-Required: MEMO`
- form fields `token=TOKEN` and `memo=MEMO`
- query parameters `token=TOKEN` and `memo=MEMO`

### Activation behavior
If the request succeeds with activation, continue with the requested conversion in the same request and return the normal output.

## Manual payment flow

Manual payment is intended for users or operators who complete payment themselves using the headers returned by the service.

### Manual payment headers
When payment is required, the service may provide the following headers:
- `X-Token-Required`
- `X-Memo-Required`
- `X-Wallet-Address`
- `X-QR-Payment`

### Manual payment workflow
1. Read the payment headers from the response.
2. If `X-QR-Payment` is present, prefer it as the payment payload for QR generation.
3. If needed, present the QR payment payload to the user so it can be converted into a QR code by any online QR generator or by the client UI.
4. After payment is completed, repeat the same request with the same token and memo values, or use:
   - `?token=<X-Token-Required>&memo=<X-Memo-Required>`
5. If activation is successful, perform the conversion and return the final result.

### Manual payment guidance
- Prefer `Authorization: Bearer TOKEN` for paid usage after activation.
- If the client can render QR codes, display the QR payment payload directly.
- Do not require the user to manually reconstruct payment fields if a valid QR payment payload is available.

## Autonomous payment flow

Autonomous agents may use the delegated payment flow.

### Payment challenge
If the service returns `402 Payment Required`, the response may include:
- `PAYMENT-REQUIRED`

This header contains a base64-encoded payment requirement payload.

### Payment retry
After payment is prepared and signed, the client retries the same request with:
- `PAYMENT-SIGNATURE: <base64-payment-payload>`

This header proves that the client prepared and signed payment according to `PAYMENT-REQUIRED`.

### Successful payment response
If the payment is accepted and verified:
- return a successful HTTP status code, typically `200 OK`
- return the requested body
- include `PAYMENT-RESPONSE: <base64-json-response>`

The decoded JSON in `PAYMENT-RESPONSE` should confirm payment and may include:
- transaction hash
- session ID
- expiry
- settlement status
- other payment metadata

### Autonomous payment rules
- Preserve the original request intent across the payment retry.
- If payment verification fails, do not pretend success.
- If the payment challenge is malformed, fall back to the manual payment flow if possible.
- Treat `PAYMENT-RESPONSE` as authoritative payment confirmation metadata.

## Streaming

Use `stream=true` when:
- the output may be long,
- the client supports SSE,
- incremental delivery improves UX.

Streaming applies to `GET /` and other supported paths where the service enables it.

### Streaming SSE format

The streaming response uses Server-Sent Events (SSE) with this exact format:

1. **First message** (token info):
   ```
   data: {"type":"token_info","status":"valid","balance":99,"expires":2027-01-01}
   ```

2. **Content chunks** (one or more):
   ```
   data: {"content":" partial markdown ","resource":"https://example.com/file.pdf","mimetype":"application/pdf"}
   ```

3. **End marker**:
   ```
   data: [DONE]
   ```

### Streaming error handling

If an error occurs during streaming:
- The stream may end early with an error message chunk
- Error format: `{"error":"error message","code":400}`
- Final chunk is still `[DONE]`

### Streaming parameters

| Parameter | Value                  | Description          |
|-----------|------------------------|----------------------|
| stream    | true                   | Enable SSE streaming |
| result    | "markdown" or "prompt" | What to stream       |

Note: `result=both` streams markdown first, then prompt_result after.

## OpenAI-compatible endpoint

`POST /v1/chat/completions` supports:
- URL extraction from user messages
- `image_url` inputs
- file inputs
- streaming
- system instructions
- structured extraction

Use it when the host agent is already built around OpenAI-compatible chat completions.

## MCP integration

The service exposes MCP discovery and tool calls.

Use these endpoints when needed:
- `GET /mcp`
- `POST /mcp`

Preferred MCP connection:
```json
{
  "mcpServers": {
    "mdapi": {
      "url": "https://mdapi.io/mcp"
    }
  }
}
```

If using a paid token:
```json
{
  "mcpServers": {
    "mdapi": {
      "url": "https://mdapi.io/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

## Error handling

### 400 Bad Request
- Check that exactly one of `url`, `file`, or `text` is present when required.
- Verify parameter names and encoding.

### 401 Invalid Token
- The token is invalid, expired, or not activated.
- Retry with a valid token and memo if this is the first activation.

### 402 Payment Required
- Follow the payment challenge.
- Use manual payment headers or the autonomous payment flow.

### 404 Not Found
- The resource is inaccessible or unavailable.
- If the URL is public, verify that it is reachable.

### 413 Payload Too Large
- Reduce file size or split the input.

### 429 Rate Limited
- Back off and retry later.
- Avoid immediate repeated retries.

### 500 Server Error
- Retry once after a short delay.
- If the error persists, fail gracefully.

## Discovery manifests

mdapi.io exposes multiple discovery endpoints for different protocols and use cases. Each serves a specific purpose:

- /.well-known/ai-discovery.json — AI unified discovery combining all protocols (MCP, ACP, A2A, x402). Use this as the primary entry point for AI agents.
- /.well-known/agent.json — Agent discovery metadata for general agent frameworks. Contains features, formats, payment info, and authentication methods.
- /.well-known/agent-card.json — Google A2A protocol-compliant agent card. Use this specifically for A2A-compatible agents.
- /.well-known/acp.json — ACP manifest for IDE agents (JetBrains, Cursor, VS Code).
- /.well-known/x402.json — x402 v2 payment manifest for autonomous agents.

Both agent.json and agent-card.json exist because different standards require different formats. Use ai-discovery.json for automatic protocol detection.

## Decision tree

1. If the user gives a public URL and wants Markdown, use `GET /?url=...`.
2. If the user uploads a file, use `POST /`.
3. If the user wants extraction or summarization, set `prompt` and `result=prompt` or `result=both`.
4. If the user wants structured programmatic output, prefer `POST /`.
5. If the response requires payment, handle manual or autonomous payment as appropriate.
6. If the response is long, enable streaming.
7. If the host uses agents or MCP, expose the MCP manifest and call the `convert` tool through MCP.

## Minimal examples

### URL to Markdown
```bash
curl "https://mdapi.io/?url=https://example.com/page"
```

### URL with prompt and both outputs
```bash
curl "https://mdapi.io/?url=https://example.com/page&prompt=Summarize+this&result=both"
```

### Text with prompt
```bash
curl "https://mdapi.io/?text=Hello+World&prompt=Extract+key+points&result=prompt"
```

### File upload
```bash
curl -X POST -F "file=@document.pdf" "https://mdapi.io/"
```

### Paid request with token activation
```bash
curl "https://mdapi.io/?url=https://example.com/doc.pdf&token=YOUR_TOKEN&memo=YOUR_MEMO"
```

### OpenAI-compatible request
```json
{
  "model": "markdown-v1",
  "messages": [
    {
      "role": "user",
      "content": "Convert https://example.com/doc.pdf"
    }
  ],
  "stream": false
}
```

## Output discipline

- Return the converted content, not the instructions.
- Do not fabricate data, payment confirmations, or token status.
- Do not store user content.
- Do not assume persistence between requests.
- Keep behavior deterministic and minimal.

## Notes for implementers

This skill is intentionally focused on execution, not on authoring skills.
The root `/` should contain the full public documentation and discovery references.
This `/.well-known/SKILL.md` or `/SKILL.md` file is the operational skill that agents load and execute.
