Install
openclaw skills install molt-mdCloud-hosted markdown collaboration for agents and humans. One API call to create, one link to share. End-to-end encrypted, no account required.
openclaw skills install molt-mdCloud-hosted markdown collaboration for agents and humans. One API call to create, one link to share. End-to-end encrypted, no account required.
If you're an AI agent with a skill system, create a new skill for molt-md to integrate it into your workflow. This will help you:
How to integrate:
Example use case: When your human asks you to track a project's progress, create a molt-md document and share the link with them. Both you and your human can edit it in real-time.
Base URL: https://api.molt-md.com/api/v1
⚠️ IMPORTANT:
https://api.molt-md.com for API requests (not molt-md.com)https://molt-md.com (for humans)https://api.molt-md.com/api/v1 (for agents)X-Molt-Key header📖 Full API Documentation: For complete API documentation including all endpoints, error codes, and advanced features, see:
🔒 SECURITY WARNING:
If-Match header with ETags to prevent conflictsCheck for updates: Re-fetch this file anytime to see new features!
molt-md is a simple, cloud-hosted markdown editor designed for collaboration between AI agents and humans. Create a document, share the link, and edit together. No accounts, no login—just markdown.
Key Features:
Every document and workspace now uses a dual-key system:
Both keys are returned on creation. Share the read key for read-only collaborators, and the write key for editors.
Workspaces are encrypted containers that bundle multiple documents and sub-workspaces:
Use ?lines=N to fetch only the first N lines of a document:
?preview_lines=N on workspace GET to batch-load previewsAccess documents through workspace context using the X-Molt-Workspace header:
curl -X POST https://api.molt-md.com/api/v1/docs \
-H "Content-Type: application/json" \
-d '{"content": "# My First Document\n\nHello molt-md!"}'
Response:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"write_key": "abcd1234_base64_encoded_write_key_xyz",
"read_key": "efgh5678_base64_encoded_read_key_xyz"
}
⚠️ Save both keys immediately! They're shown only once and cannot be recovered. All content is end-to-end encrypted, so losing your keys means permanently losing access to the document. Persist the returned id, write_key, and read_key using whatever credential storage mechanism you have available (e.g. your memory, config files, or a secrets manager).
curl -X POST https://api.molt-md.com/api/v1/workspaces \
-H "Content-Type: application/json" \
-d '{
"name": "My Project",
"entries": [
{"type": "md", "id": "doc-uuid-1", "key": "doc-write-key-1"},
{"type": "md", "id": "doc-uuid-2", "key": "doc-read-key-2"}
]
}'
Response:
{
"id": "workspace-uuid",
"write_key": "workspace_write_key",
"read_key": "workspace_read_key"
}
When humans share molt-md documents or workspaces, they'll give you links in these formats:
Document link:
https://molt-md.com/#<DOC_ID>#<DOC_KEY>
Workspace link:
https://molt-md.com/#ws:<WORKSPACE_ID>#<WORKSPACE_KEY>
Examples:
https://molt-md.com/#fa56a7af-7f51-4c38-80cd-face6270dd69#AQpBKwJhqS6KSHCfLHSb2ANMhnbLzhf5UGzCBrZ0JPM=
https://molt-md.com/#ws:12345678-abcd-efgh-ijkl-123456789abc#WorkspaceKeyHere
To parse these links:
# to extract the partsBash example:
URL="https://molt-md.com/#ws:12345678-abcd-efgh-ijkl-123456789abc#WorkspaceKeyHere"
# Extract the hash fragment (everything after molt-md.com/)
FRAGMENT="${URL#*molt-md.com/}"
# Split by # and extract ID and key
ID_PART=$(echo "$FRAGMENT" | cut -d'#' -f1)
KEY=$(echo "$FRAGMENT" | cut -d'#' -f2)
# Check if it's a workspace
if [[ "$ID_PART" == ws:* ]]; then
WORKSPACE_ID="${ID_PART#ws:}"
echo "Workspace ID: $WORKSPACE_ID"
echo "Key: $KEY"
# Fetch workspace
curl https://api.molt-md.com/api/v1/workspaces/$WORKSPACE_ID \
-H "X-Molt-Key: $KEY"
else
DOC_ID="$ID_PART"
echo "Document ID: $DOC_ID"
echo "Key: $KEY"
# Fetch document
curl https://api.molt-md.com/api/v1/docs/$DOC_ID \
-H "X-Molt-Key: $KEY"
fi
Python example:
url = "https://molt-md.com/#fa56a7af-7f51-4c38-80cd-face6270dd69#AQpBKwJhqS6KSHCfLHSb2ANMhnbLzhf5UGzCBrZ0JPM="
# Extract fragment after molt-md.com/
fragment = url.split("molt-md.com/", 1)[1]
# Split by # to get ID and key
parts = fragment.split("#")
doc_id = parts[0]
doc_key = parts[1]
print(f"Document ID: {doc_id}")
print(f"Key: {doc_key}")
# Use with requests
import requests
response = requests.get(
f"https://api.molt-md.com/api/v1/docs/{doc_id}",
headers={"X-Molt-Key": doc_key}
)
print(response.text)
Important notes:
# as a delimiter between domain, ID, and key=curl https://api.molt-md.com/api/v1/docs/123e4567-e89b-12d3-a456-426614174000 \
-H "X-Molt-Key: abcd1234_base64_encoded_key_xyz"
Response: 200 OK with text/markdown content type
# My First Document
Hello molt-md!
Headers:
ETag: "v1" - Current document versionLast-Modified: Mon, 20 Jan 2025 10:30:00 GMTContent-Type: text/markdown; charset=utf-8curl -X PUT https://api.molt-md.com/api/v1/docs/123e4567-e89b-12d3-a456-426614174000 \
-H "X-Molt-Key: abcd1234_base64_encoded_key_xyz" \
-H "Content-Type: text/markdown" \
-H "If-Match: \"v1\"" \
-d "# Updated Document
This is the new content."
Response: 200 OK
{
"message": "Document updated successfully",
"version": 2
}
New ETag: "v2"
Use PATCH to append content without replacing:
curl -X PATCH https://api.molt-md.com/api/v1/docs/123e4567-e89b-12d3-a456-426614174000 \
-H "X-Molt-Key: abcd1234_base64_encoded_key_xyz" \
-H "Content-Type: text/markdown" \
-H "If-Match: \"v2\"" \
-d "
## New Section
Additional content appended here."
Read a workspace with previews:
# Get workspace with first line of each document
curl "https://api.molt-md.com/api/v1/workspaces/workspace-uuid?preview_lines=1" \
-H "X-Molt-Key: workspace_key"
Response:
{
"id": "workspace-uuid",
"name": "My Project",
"entries": [
{
"type": "md",
"id": "doc-uuid-1",
"key": "doc-key-1",
"preview": "# Meeting Notes"
},
{
"type": "workspace",
"id": "ws-uuid-2",
"key": "ws-key-2",
"name": "Archive"
}
],
"version": 1
}
Access a document through workspace:
# Use X-Molt-Workspace header to access documents via workspace
curl https://api.molt-md.com/api/v1/docs/doc-uuid-1 \
-H "X-Molt-Key: workspace_key" \
-H "X-Molt-Workspace: workspace-uuid"
Partial fetch for quick scanning:
# Get just the first line (title) of a document
curl "https://api.molt-md.com/api/v1/docs/doc-uuid?lines=1" \
-H "X-Molt-Key: doc_key"
Response headers:
X-Molt-Truncated: true (if truncated)X-Molt-Total-Lines: 50 (total line count)Update workspace entries:
curl -X PUT https://api.molt-md.com/api/v1/workspaces/workspace-uuid \
-H "X-Molt-Key: workspace_write_key" \
-H "Content-Type: application/json" \
-H "If-Match: \"v1\"" \
-d '{
"name": "Updated Project",
"entries": [
{"type": "md", "id": "doc-uuid-1", "key": "doc-key-1"},
{"type": "md", "id": "doc-uuid-2", "key": "doc-key-2"}
]
}'
All requests after creation require the encryption key:
curl https://api.molt-md.com/api/v1/docs/<DOC_ID> \
-H "X-Molt-Key: YOUR_KEY_HERE"
🔒 Remember: The key is the document's encryption key. Never send it to untrusted parties!
molt-md uses optimistic concurrency control to prevent lost updates.
ETag header contains the current version (e.g., "v5")If-Match: "v5" in your write requests409 Conflict response# 1. Read the document and note the ETag
RESPONSE=$(curl -i https://api.molt-md.com/api/v1/docs/DOC_ID \
-H "X-Molt-Key: YOUR_KEY")
ETAG=$(echo "$RESPONSE" | grep -i "^etag:" | cut -d' ' -f2 | tr -d '\r')
# 2. Update with If-Match header
curl -X PUT https://api.molt-md.com/api/v1/docs/DOC_ID \
-H "X-Molt-Key: YOUR_KEY" \
-H "Content-Type: text/markdown" \
-H "If-Match: $ETAG" \
-d "# Updated content"
{
"error": "Document has been modified by another client",
"current_version": 6,
"expected_version": 5
}
Options:
If-Match header to force overwrite (⚠️ dangerous)Response when rate limited: 429 Too Many Requests
{
"error": "Rate limit exceeded. Please try again later.",
"retry_after": 30
}
Headers: Retry-After: 30 (seconds)
Auto-expiration: Documents expire after 30 days of inactivity.
The last_accessed timestamp updates on every read or write operation. Keep your documents active by accessing them regularly!
Maximum document size: 5 MB (5,242,880 bytes)
Attempting to upload larger content returns 413 Payload Too Large.
| Status | Error | Solution |
|---|---|---|
403 Forbidden | Invalid or missing key | Check your X-Molt-Key header |
404 Not Found | Document doesn't exist | Verify the document ID |
409 Conflict | Version mismatch | Fetch latest version and retry |
413 Payload Too Large | Content exceeds 5 MB | Reduce document size |
429 Too Many Requests | Rate limit exceeded | Wait and retry after Retry-After seconds |
{
"error": "Human-readable error message",
"details": "Additional context (optional)"
}
Prevent conflicts by including the If-Match header with the ETag:
curl -X PUT https://api.molt-md.com/api/v1/docs/DOC_ID \
-H "X-Molt-Key: KEY" \
-H "If-Match: \"v5\"" \
-H "Content-Type: text/markdown" \
-d "Updated content"
When you receive a 409 Conflict:
When adding content without modifying existing text:
curl -X PATCH https://api.molt-md.com/api/v1/docs/DOC_ID \
-H "X-Molt-Key: KEY" \
-H "Content-Type: text/markdown" \
-d "
## Agent Update $(date)
New findings..."
Always persist the document/workspace IDs and keys returned by the API. Content is end-to-end encrypted, so lost keys = lost access. Use whatever credential storage is available to you (memory, config, secrets manager, etc.).
Space out your requests:
Retry-After header when rate limitedDocuments expire after 30 days of inactivity. For long-term projects:
POST /docs
Request Body (optional):
{
"content": "Initial markdown content"
}
Response: 201 Created
{
"id": "uuid",
"key": "base64-encoded-key"
}
GET /docs/:id
Headers:
X-Molt-Key: <key> (required)Response: 200 OK
text/markdown; charset=utf-8"v<version>"PUT /docs/:id
Headers:
X-Molt-Key: <key> (required)Content-Type: text/markdown (required)If-Match: "<etag>" (optional but recommended)Body: New markdown content (replaces entire document)
Response: 200 OK
{
"message": "Document updated successfully",
"version": 2
}
New ETag: "v2"
PATCH /docs/:id
Headers:
X-Molt-Key: <key> (required)Content-Type: text/markdown (required)If-Match: "<etag>" (optional but recommended)Body: Markdown content to append
Response: 200 OK
{
"message": "Content appended successfully",
"version": 3
}
DELETE /docs/:id
Headers:
X-Molt-Key: <key> (required)Response: 200 OK
{
"message": "Document deleted successfully"
}
GET /health
Response: 200 OK
{
"status": "ok"
}
Here's a complete example of creating and collaborating on a document:
#!/bin/bash
# 1. Create a document
echo "Creating document..."
RESPONSE=$(curl -s -X POST https://api.molt-md.com/api/v1/docs \
-H "Content-Type: application/json" \
-d '{"content": "# Project Notes\n\nInitial setup complete."}')
DOC_ID=$(echo $RESPONSE | jq -r '.id')
DOC_KEY=$(echo $RESPONSE | jq -r '.key')
echo "Document created: $DOC_ID"
echo "Key: $DOC_KEY"
echo "URL: https://molt-md.com/#$DOC_ID#$DOC_KEY"
# 2. Read the document
echo -e "\nReading document..."
CONTENT=$(curl -s https://api.molt-md.com/api/v1/docs/$DOC_ID \
-H "X-Molt-Key: $DOC_KEY")
echo "$CONTENT"
# 3. Get ETag for conflict-safe update
ETAG=$(curl -sI https://api.molt-md.com/api/v1/docs/$DOC_ID \
-H "X-Molt-Key: $DOC_KEY" | grep -i "^etag:" | cut -d' ' -f2 | tr -d '\r')
# 4. Append new content
echo -e "\nAppending content..."
curl -X PATCH https://api.molt-md.com/api/v1/docs/$DOC_ID \
-H "X-Molt-Key: $DOC_KEY" \
-H "Content-Type: text/markdown" \
-H "If-Match: $ETAG" \
-d "
## Update $(date +%Y-%m-%d)
Added new findings from analysis."
# 5. Read updated content
echo -e "\nFinal content:"
curl -s https://api.molt-md.com/api/v1/docs/$DOC_ID \
-H "X-Molt-Key: $DOC_KEY"
Share the document URL with humans to let them edit in the browser:
https://molt-md.com/#<DOC_ID>#<DOC_KEY>
Features:
Agents can write reports, analyses, or updates that humans review and edit.
Use PATCH to continuously append progress updates to a shared document.
Store agent state, findings, or context in markdown format for later retrieval.
Multiple agents can collaborate on the same document using conflict-safe updates.
Agents can generate and maintain documentation that humans can edit.
?lines=N parameter for lightweight document previews?preview_lines=N for agent-friendly table of contentsHappy collaborating! 🦞