--- tags: - docs - api --- # API Documentation Publish, update, and manage markdown documents via REST API or MCP. ## Contents - [Authentication](#authentication) - [POST /v1/docs — Publish](#publish-a-document) - [PUT /v1/docs/:slug — Update](#update-a-document) - [DELETE /v1/docs/:slug — Delete](#delete-a-document) - [GET /v1/docs/:slug/status — Status](#get-document-status) - [GET /v1/docs — List](#list-documents) - [MCP Endpoint](#mcp-endpoint) - [Rate Limits](#rate-limits) - [Error Codes](#error-codes) ## Authentication mdlib supports three authentication methods: ### API Key (account-wide) Get an API key from your [dashboard settings](https://mdlib.dev/dashboard/settings). Send it in the Authorization header: ``` Authorization: Bearer mdlib_your_api_key_here ``` ### Edit Key (per-document) Every published document receives an edit key. Use it to update or delete that specific document: ``` X-Edit-Key: ek_abc123... ``` ### Anonymous No authentication required. Anonymous documents expire in 7 days. Claim them from your dashboard to make them permanent. ## Publish a document **`POST /v1/docs`** Publish a markdown document. Returns a public URL and edit key. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `markdown` | string | Yes | Markdown content | | `title` | string | No | Document title (extracted from first H1 if omitted) | | `slug` | string | No | Custom URL slug (auto-generated if omitted) | | `project` | string | No | Project name (requires API key) | | `tags` | string[] | No | Tags for categorization | | `notify` | string | No | Email to send the document link to | | `images` | object | No | Inline images as `{"filename": "data:image/png;base64,..."}` | | `is_public` | boolean | No | Whether the document appears in public listings (default: true) | ```bash # Anonymous publish curl -X POST https://mdlib.dev/v1/docs \ -H "Content-Type: application/json" \ -d '{"markdown": "# Hello World\nMy first document."}' # Authenticated publish with project curl -X POST https://mdlib.dev/v1/docs \ -H "Authorization: Bearer mdlib_your_key" \ -H "Content-Type: application/json" \ -d '{"markdown": "# Sprint Report\nAll tasks complete.", "project": "acme", "tags": ["weekly"]}' ``` **Response:** ```json { "url": "https://mdlib.dev/d/hello-world-a3x", "slug": "hello-world-a3x", "edit_key": "ek_abc123...", "created_at": "2026-01-15T10:30:00Z", "expires_at": "2026-01-22T10:30:00Z" } ``` ## Update a document **`PUT /v1/docs/:slug`** Replace a document's content. Requires API key or edit key. Fields not provided are preserved from the existing document. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `markdown` | string | Yes | New markdown content (replaces entire document) | | `title` | string | No | New title (preserved if omitted) | | `tags` | string[] | No | New tags — `[]` clears, omit to preserve existing | | `is_public` | boolean | No | Update visibility (preserved if omitted) | ```bash curl -X PUT https://mdlib.dev/v1/docs/hello-world-a3x \ -H "X-Edit-Key: ek_abc123..." \ -H "Content-Type: application/json" \ -d '{"markdown": "# Hello World v2\nUpdated content."}' ``` ## Delete a document **`DELETE /v1/docs/:slug`** Permanently delete a document. Requires API key or edit key. ```bash curl -X DELETE https://mdlib.dev/v1/docs/hello-world-a3x \ -H "X-Edit-Key: ek_abc123..." ``` ## Get document status **`GET /v1/docs/:slug/status`** Get metadata about a public document. No authentication required. ```bash curl https://mdlib.dev/v1/docs/hello-world-a3x/status ``` **Response:** ```json { "slug": "hello-world-a3x", "title": "Hello World", "word_count": 42, "created_at": "2026-01-15T10:30:00Z", "updated_at": "2026-01-15T12:00:00Z", "expires_at": null } ``` ## List documents **`GET /v1/docs`** List your documents. Requires API key. Supports filtering and search. | Query param | Description | |-------------|-------------| | `project` | Filter by project name | | `tag` | Filter by tag | | `q` | Full-text search query | | `page` | Page number (default: 1) | | `limit` | Results per page (default: 20, max: 100) | | `sort` | `created` (default) or `updated` | ```bash curl https://mdlib.dev/v1/docs \ -H "Authorization: Bearer mdlib_your_key" # With filters curl "https://mdlib.dev/v1/docs?project=acme&tag=weekly&q=sprint" \ -H "Authorization: Bearer mdlib_your_key" ``` ## MCP Endpoint mdlib provides a [Model Context Protocol](https://modelcontextprotocol.io) endpoint for AI agents. **`POST /mcp`** JSON-RPC 2.0 Streamable HTTP endpoint. Supports `initialize`, `tools/list`, and `tools/call`. ### Available tools | Tool | Description | |------|-------------| | `publish_document` | Publish markdown to mdlib | | `update_document` | Update an existing document | | `delete_document` | Delete a document (requires confirmation) | | `list_documents` | List your documents (requires API key) | | `get_document` | Get raw markdown and metadata | ### Configure in Claude Code Add to your MCP settings (`.claude/settings.json` or project settings): ```json { "mcpServers": { "mdlib": { "url": "https://mdlib.dev/mcp", "headers": { "Authorization": "Bearer mdlib_your_key" } } } } ``` ### Claude.ai Web Connector mdlib is also available as a Claude.ai web connector. Add the MCP server URL `https://mdlib.yeetit.workers.dev/mcp` in Claude.ai's MCP integration settings. ### Discovery Discovery document: [`/mcp.json`](https://mdlib.dev/mcp.json) Protected resource metadata: [`/.well-known/oauth-protected-resource`](https://mdlib.dev/.well-known/oauth-protected-resource) ## Rate Limits | Tier | Burst (per minute) | Hourly | |------|-------------------|--------| | Anonymous | 5 | 5 | | Free | 20 | 20 | | Pro | 100 | 100 | | Team | 100 | 100 | MCP calls: 30 per hour per IP. Rate-limited responses return `429 Too Many Requests` with a `Retry-After` header. ## Error Codes | Status | Meaning | |--------|---------| | 400 | Bad request — invalid parameters | | 401 | Unauthorized — invalid or missing API key | | 403 | Forbidden — invalid edit key or tier limit reached | | 404 | Not found — document doesn't exist | | 409 | Conflict — slug already in use | | 413 | Payload too large — document exceeds size limit | | 422 | Content policy violation | | 429 | Rate limit exceeded | | 500 | Internal server error | Error responses always return JSON: `{"error": "description"}`