Files
outline-mcp-custom/IMPLEMENTATION.md
T
b3nw 176e1f1040
Build and Push Outline MCP Docker Image / build (push) Successful in 7s
feat: Add embedMarkdown to upload response and document attachment format
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.
2026-05-25 02:52:49 +00:00

442 lines
11 KiB
Markdown

# 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/<method>.
All responses have format: {"ok": true/false, "data": ...}
### Authentication
All requests require Bearer token: Authorization: Bearer <token>
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.create` with form fields.
- **Response**:
```json
{
"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.ext` is the attachment filename
- `filesize` is 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
```json
{"ok": true, "data": {...}, "pagination": {"nextPath": "...", "limit": 25, "offset": 0}}
```
### Error
```json
{"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"}
```