git clone https://github.com/openclaw/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/atomtanstudio/craft-do" ~/.claude/skills/openclaw-skills-craft-do && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/atomtanstudio/craft-do" ~/.openclaw/skills/openclaw-skills-craft-do && rm -rf "$T"
skills/atomtanstudio/craft-do/SKILL.mdCraft.do Integration Skill
Complete REST API integration for Craft.do - the beautiful note-taking and document app.
Overview
This skill provides full programmatic access to Craft.do for:
- Task automation: Create, update, manage tasks across inbox/daily notes/logbook
- Document workflows: Programmatically create, read, organize documents
- Folder management: Build nested folder hierarchies via API
- Obsidian migration: One-time full vault migration with content preservation
- Content manipulation: Add/edit markdown content via blocks API
Craft.do features:
- Native markdown support
- Task management (inbox, daily notes, logbook)
- Collections (database tables)
- Hierarchical folders and documents
- Full REST API access
Setup
- Get your API key from Craft.do settings
- Store credentials securely:
export CRAFT_API_KEY="pdk_xxx" export CRAFT_ENDPOINT="https://connect.craft.do/links/YOUR_LINK/api/v1"
API Capabilities
✅ What Works
List Folders
curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/folders"
Returns all locations: unsorted, daily_notes, trash, templates, and custom folders.
List Documents
curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/documents?folderId=FOLDER_ID"
Create Folder (with optional parent for nesting)
# Root-level folder curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "folders": [{ "name": "Projects" }] }' \ "$CRAFT_ENDPOINT/folders" # Nested folder (requires parent folder ID) curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "folders": [{ "name": "Q1 2024", "parentFolderId": "PARENT_FOLDER_ID" }] }' \ "$CRAFT_ENDPOINT/folders"
Create Document
curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "documents": [{ "title": "Document Title" }], "destination": { "folderId": "FOLDER_ID" } }' \ "$CRAFT_ENDPOINT/documents"
Note: Documents are created without content initially. Use the
/blocks endpoint to add content.
Add Content to Document
curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "blocks": [{ "type": "text", "markdown": "# Document content\n\nFull markdown support!" }], "position": { "pageId": "DOCUMENT_ID", "position": "end" } }' \ "$CRAFT_ENDPOINT/blocks"
Read Document Content
curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/blocks?id=DOCUMENT_ID"
Returns full markdown content with all blocks.
Create Task
curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tasks": [{ "markdown": "Task description", "location": {"type": "inbox"}, "status": "active" }] }' \ "$CRAFT_ENDPOINT/tasks"
Update Task (Mark Complete)
curl -X PUT \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tasksToUpdate": [{ "id": "TASK_ID", "markdown": "- [x] Completed task" }] }' \ "$CRAFT_ENDPOINT/tasks"
List Tasks
# Active tasks curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=active" # All completed (logbook) curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=logbook" # Upcoming curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=upcoming" # Inbox only curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=inbox"
Move Documents
curl -X PUT \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "documentIds": ["DOC_ID"], "destination": {"location": "unsorted"} }' \ "$CRAFT_ENDPOINT/documents/move"
Note: Can only move to
unsorted, templates, or custom folder IDs. Cannot move directly to trash.
❌ Limitations
- No Collections API - Collections (databases) not accessible via API
- No task deletion - Can only create/update tasks, not delete
- No document deletion - Cannot delete documents directly (only move)
- No search endpoint - Search requires specific query format (needs more testing)
- Limited filtering - Collections filtering/grouping only in UI, not via API
Common Use Cases
Sync Tasks from External System
# Create task in Craft from Mission Control TASK_TITLE="Deploy new feature" curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"tasks\": [{ \"markdown\": \"$TASK_TITLE\", \"location\": {\"type\": \"inbox\"}, \"status\": \"active\" }] }" \ "$CRAFT_ENDPOINT/tasks"
Create Daily Note
TODAY=$(date +%Y-%m-%d) curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"documents\": [{ \"title\": \"Daily Note - $TODAY\", \"content\": [{\"textContent\": \"# $TODAY\\n\\n## Tasks\\n\\n## Notes\\n\"}], \"location\": \"daily_notes\" }] }" \ "$CRAFT_ENDPOINT/documents"
Archive Completed Work
# Get all completed tasks curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=logbook" | jq '.items[] | {id, markdown, completedAt}'
Integration Patterns
Mission Control → Craft Sync
Problem: Mission Control has automation but ugly UI. Craft has beautiful UI but no automation.
Solution: Use Mission Control as the source of truth, sync completed work to Craft for viewing.
#!/bin/bash # sync-to-craft.sh - Sync completed tasks to Craft # Read completed tasks from Mission Control COMPLETED_TASKS=$(cat mission-control/tasks.json | jq -r '.[] | select(.status=="done") | .title') # Push each to Craft echo "$COMPLETED_TASKS" | while read -r task; do curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"tasks\": [{ \"markdown\": \"- [x] $task\", \"location\": {\"type\": \"inbox\"} }] }" \ "$CRAFT_ENDPOINT/tasks" done
Markdown Support
Craft fully supports markdown:
- Headers:
,# H1
, etc.## H2 - Lists:
,- item1. item - Tasks:
,- [ ] todo- [x] done - Links:
[text](url) - Code:
or`inline````block``` - Emphasis:
,*italic***bold**
All content is stored and returned as markdown, making it perfect for programmatic manipulation.
Best Practices
- Store API key securely - Never commit to code
- Test in unsorted folder first - Easy to find/clean up
- Use markdown format - Native to both systems
- One-way sync only - Craft → read-only, Mission Control → write
- Batch operations - API supports arrays for efficiency
- Handle errors gracefully - API returns detailed validation errors
Error Handling
Common errors:
- Check required fields (markdown, location)VALIDATION_ERROR
- Invalid/expired API key403
- Document/task ID not found404
Example validation error:
{ "error": "Validation failed", "code": "VALIDATION_ERROR", "details": [{ "path": ["tasks", 0, "markdown"], "message": "Invalid input: expected string" }] }
Future Possibilities
When Craft adds to their API:
- Collections CRUD via API
- Task deletion
- Document deletion
- Advanced search
- Webhooks for real-time sync
- Batch operations for large datasets
Resources
- Craft API Docs (get your personal API endpoint from Craft settings)
- Craft Blog - Collections
- Craft YouTube
Testing Checklist
- List folders
- List documents
- Create document
- Add content to document (via /blocks endpoint)
- Read document content
- Create task
- Update task (mark complete)
- List tasks (all scopes)
- Move documents between locations
- Full Obsidian → Craft migration with content
- Search (needs format refinement)
- Collections - NOT accessible via API
- Delete tasks - NOT supported
- Delete documents - NOT supported (only move)
Example: Complete Workflow
# 1. Create a project folder PROJECT_ID=$(curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Q1 2024 Projects"}' \ "$CRAFT_ENDPOINT/folders" | jq -r '.id') # 2. Create a project document DOC_ID=$(curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"documents\": [{ \"title\": \"Project Alpha\", \"content\": [{\"textContent\": \"## Overview\\n\\nProject details here.\"}], \"location\": \"$PROJECT_ID\" }] }" \ "$CRAFT_ENDPOINT/documents" | jq -r '.items[0].id') # 3. Create tasks for the project curl -X POST \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tasks": [ {"markdown": "Design wireframes", "location": {"type": "inbox"}}, {"markdown": "Build prototype", "location": {"type": "inbox"}}, {"markdown": "User testing", "location": {"type": "inbox"}} ] }' \ "$CRAFT_ENDPOINT/tasks" # 4. Mark first task complete TASK_ID=$(curl -H "Authorization: Bearer $CRAFT_API_KEY" \ "$CRAFT_ENDPOINT/tasks?scope=active" | jq -r '.items[0].id') curl -X PUT \ -H "Authorization: Bearer $CRAFT_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"tasksToUpdate\": [{ \"id\": \"$TASK_ID\", \"markdown\": \"- [x] Design wireframes\" }] }" \ "$CRAFT_ENDPOINT/tasks"
Status: Tested and working (2026-01-31) Tested with: Craft API v1 Author: Eliza