Skip to main content
Glama

MCP Outline Server

by Vortiago
CLAUDE.md5.35 kB
# MCP Outline Server Guide This guide helps you implement and modify the MCP Outline server effectively. ## Purpose This MCP server bridges AI assistants with Outline's document management platform: - REST API integration for Outline services - Tools for documents, collections, and comments - API key authentication - Docker and local development support ## Architecture ### Tool Categories - **Search**: Find documents, collections, hierarchies - **Reading**: Read content, export markdown - **Content**: Create, update, comment - **Organization**: Move documents between collections - **Lifecycle**: Archive, delete, restore operations - **Collaboration**: Comments, backlinks - **Collections**: Create, update, delete, export - **AI**: Natural language queries ## Core Concepts ### Outline Objects - **Documents**: Markdown content with title and metadata - **Collections**: Grouping with name, description, color - **Comments**: Threaded discussions with replies - **Hierarchy**: Parent-child document relationships - **Lifecycle**: Draft → Published → Archived → Deleted ### API Client `OutlineClient` in `utils/outline_client.py` handles REST API interactions: **Operations**: - Documents: get, search, create, update, move, archive, delete, restore - Collections: list, create, update, delete, export - Comments: create, list, get - AI: answer questions **Configuration**: - `OUTLINE_API_KEY` (required) - `OUTLINE_API_URL` (optional, defaults to https://app.getoutline.com/api) - Authentication via Bearer token **Error Handling**: - Raises `OutlineError` for API failures - Tools catch exceptions and return error strings **Rate Limiting**: - Tracks `RateLimit-Remaining` and `RateLimit-Reset` headers, waits proactively when exhausted - Automatic retry on HTTP 429 with exponential backoff (1s, 2s, 4s) - Respects `Retry-After` header - Enabled by default, no configuration required ## Implementation Patterns ### Module Structure Feature modules follow this pattern: ```python # 1. Imports (standard lib → third-party → local) import os from typing import Any, Optional from mcp_outline.utils.outline_client import OutlineClient # 2. Helper formatters (private functions) def _format_search_results(data: dict) -> str: """Format API response for user display.""" # Clean, readable output formatting pass # 3. Tool registration function def register_tools(mcp): """Register all tools in this module.""" @mcp.tool() async def search_documents( query: str, collection_id: Optional[str] = None ) -> str: """ Search for documents by keywords. Args: query: Search keywords collection_id: Optional collection filter Returns: Formatted search results """ try: client = OutlineClient() result = client.search_documents(query, collection_id) return _format_search_results(result) except Exception as e: return f"Error: {str(e)}" ``` ### Adding New Tools **Client Method** (if new endpoint needed): ```python def new_operation(self, param: str) -> dict: """Docstring describing operation.""" url = f"{self.base_url}/endpoint" response = requests.post(url, headers=self.headers, json={"param": param}) if response.status_code != 200: raise OutlineError(f"Error: {response.status_code}", response) return response.json().get("data", {}) ``` **Tool Function**: ```python @mcp.tool() async def new_tool_name(param: str) -> str: """Clear description.""" try: client = OutlineClient() result = client.new_operation(param) return _format_result(result) except Exception as e: return f"Error: {str(e)}" ``` **Testing**: Mock OutlineClient, test success and error cases ## Technical Requirements ### Code Style - PEP 8 conventions - Type hints for all functions - Max line length: 79 characters (ruff enforced) - Google-style docstrings - Import order: stdlib → third-party → local - Single responsibility per function ### Error Handling ```python # In OutlineClient methods if response.status_code != 200: raise OutlineError( f"Operation failed: {response.status_code}", response ) # In tool functions try: client = OutlineClient() result = client.operation() return format_result(result) except OutlineError as e: return f"Outline API error: {str(e)}" except Exception as e: return f"Error: {str(e)}" ``` ### Testing Mock `OutlineClient` in tests: ```python with patch('module.OutlineClient') as mock_client: mock_client.return_value.method.return_value = {"data": "value"} # Test tool behavior ``` ### Configuration `.env` file: ```bash OUTLINE_API_KEY=<your_key> # Required OUTLINE_API_URL=<custom_url> # Optional ``` ### Critical Requirements - No stdout/stderr logging (MCP uses stdio) - Tools return strings, not dicts - Use `async def` for tool functions - Catch exceptions, return error strings - Follow KISS principle ## Common Patterns **Pagination**: Use `offset` and `limit` parameters for large result sets **Tree Formatting**: Recursive formatting with indentation for hierarchies **Document ID Resolution**: `get_document_id_from_title` for user-friendly lookups

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vortiago/mcp-outline'

If you have feedback or need assistance with the MCP directory API, please join our Discord server