The upload response now includes an embedMarkdown field with the correct Outline attachment syntax ([name size](/api/attachments.redirect?id=...)) so callers can insert it directly into documents for native card rendering. IMPLEMENTATION.md updated with storage backend details, auth header, and embedding format documentation.
11 KiB
Outline MCP Implementation Guide
This document provides implementation details and comprehensive API reference for AI agents using the Outline MCP server.
Architecture
The server follows the Hybrid MCP Light pattern:
- 4 specific tools for common read operations
- 1 API passthrough for full coverage
- Embedded API reference resource
Tools Overview
search_documents
Full-text search across all documents.
Params: query (required), collection_id, limit (default 25), include_archived
Returns: Search results with document titles, IDs, and context snippets
get_document
Retrieve a document by ID.
Params: document_id (required), share_id
Returns: Document metadata and full Markdown content
list_collections
List all collections in the workspace.
Params: limit (default 25), offset
Returns: Collection names, IDs, permissions, and metadata
list_collection_documents
List documents within a specific collection.
Params: collection_id (required), limit, offset
Returns: Document tree structure for the collection
outline_api_call
Raw API passthrough for any Outline endpoint.
Params: method (required), params (JSON string)
Returns: Raw API response as JSON string
Outline API Reference
Outline uses an RPC-style API where all requests are POST to /api/. All responses have format: {"ok": true/false, "data": ...}
Authentication
All requests require Bearer token: Authorization: Bearer Get your token from Outline Settings > API Tokens.
Pagination
Most list endpoints accept: limit (default 25, max 100), offset (default 0) Response includes: pagination.nextPath if more results exist.
Documents
documents.list
List documents. Params: collectionId?, userId?, parentDocumentId?, sort?, direction?, limit?, offset?
documents.info
Get document by ID. Params: id (required), shareId?
documents.search
Full-text search. Params: query (required), collectionId?, userId?, dateFilter?, includeArchived?, includeDrafts?, limit?, offset?
documents.create
Create document. Params: title (required), collectionId (required), text?, parentDocumentId?, templateId?, template?, publish?
documents.update
Update document. Params: id (required), title?, text?, append?, publish?, done?
documents.delete
Delete document. Params: id (required), permanent?
documents.move
Move document. Params: id (required), collectionId?, parentDocumentId?
documents.archive
Archive document. Params: id (required)
documents.unarchive
Restore archived document. Params: id (required)
documents.restore
Restore deleted document. Params: id (required), revisionId?
documents.export
Export document. Params: id (required) Returns Markdown content.
documents.import
Import document. Multipart form: file, collectionId, parentDocumentId?, template?, publish?
documents.star
Star a document. Params: id (required)
documents.unstar
Remove star. Params: id (required)
documents.templatize
Convert to template. Params: id (required)
documents.unpublish
Unpublish document. Params: id (required)
Collections
collections.list
List all collections. Params: limit?, offset?
collections.info
Get collection details. Params: id (required)
collections.documents
Get document structure for collection. Params: id (required), limit?, offset?
collections.create
Create collection. Params: name (required), description?, color?, permission?, sharing?
collections.update
Update collection. Params: id (required), name?, description?, color?, permission?, sharing?
collections.delete
Delete collection. Params: id (required)
collections.add_user
Add user to collection. Params: id (required), userId (required), permission?
collections.remove_user
Remove user from collection. Params: id (required), userId (required)
collections.memberships
List collection members. Params: id (required), query?, permission?, limit?, offset?
collections.add_group
Add group to collection. Params: id (required), groupId (required), permission?
collections.remove_group
Remove group. Params: id (required), groupId (required)
collections.group_memberships
List group memberships. Params: id (required), query?, permission?, limit?, offset?
collections.export
Export entire collection. Params: id (required), format?
collections.export_all
Export all collections. Params: format?
Users
users.list
List workspace users. Params: query?, filter?, sort?, direction?, limit?, offset? Filter options: all, active, invited, suspended, admins
users.info
Get user by ID. Params: id (required)
users.invite
Invite users. Params: invites (array of {email, name, role})
users.update
Update user. Params: id (required), name?, avatarUrl?
users.delete
Delete user. Params: id (required)
users.suspend
Suspend user. Params: id (required)
users.activate
Activate suspended user. Params: id (required)
users.promote
Promote to admin. Params: id (required)
users.demote
Remove admin. Params: id (required)
Groups
groups.list
List groups. Params: query?, sort?, direction?, limit?, offset?
groups.info
Get group. Params: id (required)
groups.create
Create group. Params: name (required)
groups.update
Update group. Params: id (required), name (required)
groups.delete
Delete group. Params: id (required)
groups.memberships
List group members. Params: id (required), query?, limit?, offset?
groups.add_user
Add user to group. Params: id (required), userId (required)
groups.remove_user
Remove user from group. Params: id (required), userId (required)
Comments
comments.list
List comments on document. Params: documentId (required), limit?, offset?
comments.create
Create comment. Params: documentId (required), data (required - ProseMirror JSON)
comments.update
Update comment. Params: id (required), data (required)
comments.delete
Delete comment. Params: id (required)
Revisions
revisions.list
List document revisions. Params: documentId (required), limit?, offset?
revisions.info
Get revision. Params: id (required)
Shares
shares.list
List document shares. Params: documentId?, sort?, direction?, limit?, offset?
shares.info
Get share by ID or documentId. Params: id?, documentId?
shares.create
Create share link. Params: documentId (required), published?, urlId?, includeChildDocuments?
shares.update
Update share. Params: id (required), published?, urlId?, includeChildDocuments?
shares.revoke
Revoke share. Params: id (required)
Stars
stars.list
List starred documents. Params: limit?, offset?
stars.create
Star an item. Params: documentId?, collectionId?
stars.delete
Remove star. Params: id (required)
Events
events.list
List audit events. Params: name?, actorId?, documentId?, collectionId?, auditLog?, sort?, direction?, limit?, offset?
File Operations
fileOperations.list
List file operations. Params: type?, limit?, offset?
fileOperations.info
Get file operation status. Params: id (required)
fileOperations.redirect
Get download URL. Params: id (required)
fileOperations.delete
Delete file operation. Params: id (required)
Attachments
attachments.create
Create attachment upload URL. Params: name (required), documentId (required), size (required), contentType (required)
attachments.delete
Delete attachment. Params: id (required)
attachments.redirect
Get attachment URL. Params: id (required)
Custom HTTP Gateway Upload
Instead of manually calling attachments.create and executing the subsequent storage upload, you can use the MCP server's integrated HTTP upload proxy.
This endpoint receives binary content over HTTP, registers the attachment with Outline, and uploads it to the configured storage backend (S3 or local file storage).
- Endpoint:
POST /upload - Query Parameters:
documentId(required): The UUID of the destination Outline document.name(required): The filename of the attachment (e.g.,image.png,document.pdf).
- Headers:
Authorization(required):Bearer <OUTLINE_API_TOKEN>Content-Length(required): The exact size of the file in bytes.Content-Type(optional): The MIME type of the file (e.g.,application/pdf,image/png). If omitted, it will be auto-detected by filename extension.
- Request Body: The raw file binary content.
- Storage backends: Auto-detected from the Outline API response.
- S3: PUT to pre-signed URL.
- Local file storage: Multipart POST to
/api/files.createwith form fields.
- Response:
{ "ok": true, "data": { "id": "attachment-uuid", "name": "filename.ext", "size": 12345, "contentType": "mime/type", "url": "/api/attachments.redirect?id=attachment-uuid", "embedMarkdown": "[filename.ext 12345](/api/attachments.redirect?id=attachment-uuid)" } }
Embedding Attachments in Documents
Outline uses a special markdown syntax to render attachment cards (with file icon, name, and download size). The format is:
[filename.ext filesize](/api/attachments.redirect?id=attachment-uuid)
Where:
filename.extis the attachment filenamefilesizeis the file size in bytes (space-separated, not a label)- The URL is the relative
/api/attachments.redirect?id=...path
The embedMarkdown field in the upload response provides this string ready to insert into a document body via documents.update.
Example: Upload a file and embed it in a document:
1. POST /upload?documentId=doc-uuid&name=report.pdf → get embedMarkdown
2. outline_api_call("documents.update", {"id": "doc-uuid", "text": "...\n\n" + embedMarkdown, "append": true})
Important: Do NOT use absolute URLs (e.g., https://docs.example.com/api/attachments.redirect?id=...) — Outline will not render the attachment card for absolute URLs. Always use the relative path.
Auth
auth.info
Get current user and team info. No params.
auth.config
Get auth configuration. No params.
Views
views.list
List document views. Params: documentId (required), limit?, offset?
views.create
Record a view. Params: documentId (required)
Common Response Patterns
Success
{"ok": true, "data": {...}, "pagination": {"nextPath": "...", "limit": 25, "offset": 0}}
Error
{"ok": false, "error": "message", "status": 401}
Rate Limiting
HTTP 429 with Retry-After header
Usage Examples
Create a document
method: "documents.create"
params: {"title": "My Document", "collectionId": "collection-uuid", "text": "# Hello\n\nDocument content here.", "publish": true}
Update document content
method: "documents.update"
params: {"id": "document-uuid", "text": "# Updated Content\n\nNew content here."}
Delete a document
method: "documents.delete"
params: {"id": "document-uuid"}
Invite a user
method: "users.invite"
params: {"invites": [{"email": "user@example.com", "name": "User Name", "role": "member"}]}
Create a collection
method: "collections.create"
params: {"name": "Engineering", "description": "Engineering documentation", "permission": "read_write"}