New modules (11): - teams.ts (5 tools): Team/workspace management - integrations.ts (6 tools): External integrations (Slack, embeds) - notifications.ts (4 tools): User notification management - subscriptions.ts (4 tools): Document subscription management - templates.ts (5 tools): Document template management - imports-tools.ts (4 tools): Import job management - emojis.ts (3 tools): Custom emoji management - user-permissions.ts (3 tools): Permission management - bulk-operations.ts (6 tools): Batch operations - advanced-search.ts (6 tools): Faceted search, recent, orphaned, duplicates - analytics.ts (6 tools): Usage statistics and insights Updated: - src/index.ts: Import and register all new tools - src/tools/index.ts: Export all new modules - CHANGELOG.md: Version 1.2.0 entry - CLAUDE.md: Updated tool count to 160 - CONTINUE.md: Updated state documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
984 lines
29 KiB
Markdown
984 lines
29 KiB
Markdown
# MCP Outline - Especificação Completa
|
|
|
|
**Versão:** 1.0.0
|
|
**Data:** 2026-01-31
|
|
**Autor:** Descomplicar®
|
|
|
|
---
|
|
|
|
## 1. Visão Geral
|
|
|
|
### Objectivo
|
|
|
|
MCP para acesso directo à base de dados PostgreSQL do Outline, seguindo os padrões estabelecidos pelo `mcp-desk-crm-sql-v3`.
|
|
|
|
### Arquitectura
|
|
|
|
```
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ Claude Code │────▶│ MCP Outline │────▶│ PostgreSQL │
|
|
│ (Cliente) │◀────│ (Servidor) │◀────│ (Outline DB) │
|
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
│ │
|
|
│ MCP Protocol │ SQL Directo
|
|
│ (stdio/SSE) │ (pg client)
|
|
```
|
|
|
|
### Decisões Técnicas
|
|
|
|
| Aspecto | Decisão | Razão |
|
|
|---------|---------|-------|
|
|
| **Acesso** | SQL Directo (não API) | Performance, controlo total |
|
|
| **BD** | PostgreSQL 15 | Compatível com Outline |
|
|
| **Transporte** | stdio (dev), SSE (prod) | Padrão MCP |
|
|
| **Linguagem** | TypeScript | Type safety, padrão Desk |
|
|
|
|
---
|
|
|
|
## 2. Ambiente de Desenvolvimento
|
|
|
|
### Configuração Local
|
|
|
|
```bash
|
|
# Base de dados
|
|
Host: localhost
|
|
Port: 5432
|
|
User: outline
|
|
Password: outline_dev_2026
|
|
Database: outline
|
|
|
|
# Connection string
|
|
postgres://outline:outline_dev_2026@localhost:5432/outline
|
|
```
|
|
|
|
### Estrutura do Projecto
|
|
|
|
```
|
|
~/mcp-servers/mcp-outline/
|
|
├── package.json
|
|
├── tsconfig.json
|
|
├── .env
|
|
├── .env.example
|
|
├── CHANGELOG.md
|
|
├── README.md
|
|
├── SPEC-MCP-OUTLINE.md ← Este ficheiro
|
|
├── src/
|
|
│ ├── index.ts ← Entry point MCP
|
|
│ ├── pg-client.ts ← Cliente PostgreSQL
|
|
│ ├── config/
|
|
│ │ └── database.ts ← Configuração BD
|
|
│ ├── types/
|
|
│ │ ├── index.ts
|
|
│ │ ├── tools.ts ← Tipos base das tools
|
|
│ │ └── db.ts ← Tipos das tabelas
|
|
│ ├── tools/
|
|
│ │ ├── index.ts ← Exporta todas as tools
|
|
│ │ ├── documents.ts
|
|
│ │ ├── collections.ts
|
|
│ │ ├── users.ts
|
|
│ │ ├── groups.ts
|
|
│ │ ├── comments.ts
|
|
│ │ ├── attachments.ts
|
|
│ │ ├── shares.ts
|
|
│ │ ├── revisions.ts
|
|
│ │ └── events.ts
|
|
│ └── utils/
|
|
│ ├── logger.ts
|
|
│ └── security.ts
|
|
├── dist/ ← Build output
|
|
└── tests/
|
|
└── tools/
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Dependências
|
|
|
|
### package.json
|
|
|
|
```json
|
|
{
|
|
"name": "mcp-outline",
|
|
"version": "1.0.0",
|
|
"type": "module",
|
|
"main": "dist/index.js",
|
|
"scripts": {
|
|
"build": "tsc",
|
|
"start": "node dist/index.js",
|
|
"dev": "tsx watch src/index.ts",
|
|
"test": "vitest"
|
|
},
|
|
"dependencies": {
|
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
"pg": "^8.11.0",
|
|
"dotenv": "^16.0.0"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^20.0.0",
|
|
"@types/pg": "^8.10.0",
|
|
"typescript": "^5.0.0",
|
|
"tsx": "^4.0.0",
|
|
"vitest": "^1.0.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### tsconfig.json
|
|
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"target": "ES2022",
|
|
"module": "NodeNext",
|
|
"moduleResolution": "NodeNext",
|
|
"outDir": "./dist",
|
|
"rootDir": "./src",
|
|
"strict": true,
|
|
"esModuleInterop": true,
|
|
"skipLibCheck": true,
|
|
"declaration": true
|
|
},
|
|
"include": ["src/**/*"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Tipos Base (Padrão Desk)
|
|
|
|
### src/types/tools.ts
|
|
|
|
```typescript
|
|
import { Pool } from 'pg';
|
|
|
|
export interface ToolResponse {
|
|
content: Array<{
|
|
type: 'text';
|
|
text: string;
|
|
}>;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface BaseTool<TArgs = Record<string, unknown>> {
|
|
name: string;
|
|
description: string;
|
|
inputSchema: {
|
|
type: string;
|
|
properties: Record<string, unknown>;
|
|
required?: string[];
|
|
};
|
|
handler: (args: TArgs, pgClient: Pool) => Promise<ToolResponse>;
|
|
}
|
|
|
|
// Argumentos comuns
|
|
export interface PaginationArgs {
|
|
limit?: number;
|
|
offset?: number;
|
|
}
|
|
|
|
export interface DateRangeArgs {
|
|
dateFrom?: string;
|
|
dateTo?: string;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. API Outline → Tools MCP
|
|
|
|
### 5.1 Documents (17 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `documents.list` | `list_documents` | SELECT | P1 |
|
|
| `documents.info` | `get_document` | SELECT | P1 |
|
|
| `documents.create` | `create_document` | INSERT | P1 |
|
|
| `documents.update` | `update_document` | UPDATE | P1 |
|
|
| `documents.delete` | `delete_document` | UPDATE (soft) | P1 |
|
|
| `documents.search` | `search_documents` | SELECT FTS | P1 |
|
|
| `documents.drafts` | `list_drafts` | SELECT | P2 |
|
|
| `documents.viewed` | `list_viewed_documents` | SELECT | P2 |
|
|
| `documents.archive` | `archive_document` | UPDATE | P2 |
|
|
| `documents.restore` | `restore_document` | UPDATE | P2 |
|
|
| `documents.move` | `move_document` | UPDATE | P2 |
|
|
| `documents.unpublish` | `unpublish_document` | UPDATE | P3 |
|
|
| `documents.templatize` | `templatize_document` | INSERT | P3 |
|
|
| `documents.export` | `export_document` | SELECT | P2 |
|
|
| `documents.import` | `import_document` | INSERT | P3 |
|
|
| `documents.users` | `list_document_users` | SELECT | P2 |
|
|
| `documents.memberships` | `list_document_memberships` | SELECT | P3 |
|
|
|
|
#### Exemplo: list_documents
|
|
|
|
```typescript
|
|
export const listDocuments: BaseTool = {
|
|
name: 'list_documents',
|
|
description: 'Lista documentos com filtros. Suporta paginação e ordenação.',
|
|
inputSchema: {
|
|
type: 'object',
|
|
properties: {
|
|
collection_id: {
|
|
type: 'string',
|
|
description: 'UUID da collection para filtrar'
|
|
},
|
|
user_id: {
|
|
type: 'string',
|
|
description: 'UUID do autor para filtrar'
|
|
},
|
|
template: {
|
|
type: 'boolean',
|
|
description: 'Filtrar apenas templates'
|
|
},
|
|
published: {
|
|
type: 'boolean',
|
|
description: 'Filtrar apenas publicados (default: true)'
|
|
},
|
|
limit: {
|
|
type: 'number',
|
|
description: 'Máximo de resultados (default: 25, max: 100)'
|
|
},
|
|
offset: {
|
|
type: 'number',
|
|
description: 'Offset para paginação'
|
|
},
|
|
sort: {
|
|
type: 'string',
|
|
enum: ['updatedAt', 'createdAt', 'title', 'index'],
|
|
description: 'Campo para ordenação'
|
|
},
|
|
direction: {
|
|
type: 'string',
|
|
enum: ['ASC', 'DESC'],
|
|
description: 'Direcção da ordenação'
|
|
}
|
|
}
|
|
},
|
|
handler: async (args, pgClient) => {
|
|
const limit = Math.min(args.limit || 25, 100);
|
|
const offset = args.offset || 0;
|
|
const sort = args.sort || 'updatedAt';
|
|
const direction = args.direction || 'DESC';
|
|
|
|
let sql = `
|
|
SELECT
|
|
d.id,
|
|
d.title,
|
|
d.text,
|
|
d."collectionId",
|
|
d."parentDocumentId",
|
|
d."createdById",
|
|
d."publishedAt",
|
|
d."updatedAt",
|
|
d."archivedAt",
|
|
d.template,
|
|
c.name as collection_name,
|
|
u.name as author_name
|
|
FROM documents d
|
|
LEFT JOIN collections c ON d."collectionId" = c.id
|
|
LEFT JOIN users u ON d."createdById" = u.id
|
|
WHERE d."deletedAt" IS NULL
|
|
`;
|
|
|
|
const params: any[] = [];
|
|
let paramIndex = 1;
|
|
|
|
if (args.collection_id) {
|
|
sql += ` AND d."collectionId" = $${paramIndex++}`;
|
|
params.push(args.collection_id);
|
|
}
|
|
|
|
if (args.user_id) {
|
|
sql += ` AND d."createdById" = $${paramIndex++}`;
|
|
params.push(args.user_id);
|
|
}
|
|
|
|
if (args.template !== undefined) {
|
|
sql += ` AND d.template = $${paramIndex++}`;
|
|
params.push(args.template);
|
|
}
|
|
|
|
if (args.published !== false) {
|
|
sql += ` AND d."publishedAt" IS NOT NULL`;
|
|
}
|
|
|
|
sql += ` ORDER BY d."${sort}" ${direction}`;
|
|
sql += ` LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
params.push(limit, offset);
|
|
|
|
const result = await pgClient.query(sql, params);
|
|
|
|
return {
|
|
content: [{
|
|
type: 'text',
|
|
text: JSON.stringify({
|
|
documents: result.rows,
|
|
pagination: { limit, offset, count: result.rows.length }
|
|
}, null, 2)
|
|
}]
|
|
};
|
|
}
|
|
};
|
|
```
|
|
|
|
### 5.2 Collections (13 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `collections.list` | `list_collections` | SELECT | P1 |
|
|
| `collections.info` | `get_collection` | SELECT | P1 |
|
|
| `collections.create` | `create_collection` | INSERT | P1 |
|
|
| `collections.update` | `update_collection` | UPDATE | P1 |
|
|
| `collections.delete` | `delete_collection` | UPDATE (soft) | P2 |
|
|
| `collections.documents` | `list_collection_documents` | SELECT | P1 |
|
|
| `collections.add_user` | `add_user_to_collection` | INSERT | P2 |
|
|
| `collections.remove_user` | `remove_user_from_collection` | DELETE | P2 |
|
|
| `collections.memberships` | `list_collection_memberships` | SELECT | P2 |
|
|
| `collections.add_group` | `add_group_to_collection` | INSERT | P3 |
|
|
| `collections.remove_group` | `remove_group_from_collection` | DELETE | P3 |
|
|
| `collections.group_memberships` | `list_collection_group_memberships` | SELECT | P3 |
|
|
| `collections.export` | `export_collection` | SELECT | P3 |
|
|
|
|
### 5.3 Users (7 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `users.list` | `list_users` | SELECT | P1 |
|
|
| `users.info` | `get_user` | SELECT | P1 |
|
|
| `users.create` | `create_user` | INSERT | P2 |
|
|
| `users.update` | `update_user` | UPDATE | P2 |
|
|
| `users.delete` | `delete_user` | UPDATE (soft) | P3 |
|
|
| `users.suspend` | `suspend_user` | UPDATE | P2 |
|
|
| `users.activate` | `activate_user` | UPDATE | P2 |
|
|
|
|
### 5.4 Groups (7 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `groups.list` | `list_groups` | SELECT | P1 |
|
|
| `groups.info` | `get_group` | SELECT | P1 |
|
|
| `groups.create` | `create_group` | INSERT | P2 |
|
|
| `groups.update` | `update_group` | UPDATE | P2 |
|
|
| `groups.delete` | `delete_group` | DELETE | P3 |
|
|
| `groups.memberships` | `list_group_members` | SELECT | P2 |
|
|
| `groups.add_user` | `add_user_to_group` | INSERT | P2 |
|
|
|
|
### 5.5 Comments (5 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `comments.list` | `list_comments` | SELECT | P1 |
|
|
| `comments.info` | `get_comment` | SELECT | P2 |
|
|
| `comments.create` | `create_comment` | INSERT | P1 |
|
|
| `comments.update` | `update_comment` | UPDATE | P2 |
|
|
| `comments.delete` | `delete_comment` | DELETE | P2 |
|
|
|
|
### 5.6 Shares (4 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `shares.info` | `get_share` | SELECT | P2 |
|
|
| `shares.create` | `create_share` | INSERT | P2 |
|
|
| `shares.update` | `update_share` | UPDATE | P3 |
|
|
| `shares.delete` | `delete_share` | DELETE | P2 |
|
|
|
|
### 5.7 Revisions (2 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `revisions.list` | `list_revisions` | SELECT | P2 |
|
|
| `revisions.info` | `get_revision` | SELECT | P2 |
|
|
|
|
### 5.8 Events (1 tool)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `events.list` | `list_events` | SELECT | P2 |
|
|
|
|
### 5.9 Attachments (3 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `attachments.create` | `create_attachment` | INSERT | P3 |
|
|
| `attachments.redirect` | `get_attachment_url` | SELECT | P3 |
|
|
| `attachments.delete` | `delete_attachment` | DELETE | P3 |
|
|
|
|
### 5.10 Auth (2 tools)
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `auth.info` | `get_auth_info` | SELECT | P3 |
|
|
| `auth.config` | `get_auth_config` | SELECT | P3 |
|
|
|
|
### 5.11 Stars (3 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `stars.list` | `list_stars` | SELECT | P2 |
|
|
| `stars.create` | `star_document` | INSERT | P2 |
|
|
| `stars.delete` | `unstar_document` | DELETE | P2 |
|
|
|
|
### 5.12 Pins (3 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `pins.list` | `list_pins` | SELECT | P2 |
|
|
| `pins.create` | `pin_document` | INSERT | P2 |
|
|
| `pins.delete` | `unpin_document` | DELETE | P2 |
|
|
|
|
### 5.13 Views (2 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `views.list` | `list_document_views` | SELECT | P2 |
|
|
| `views.create` | `register_view` | INSERT | P3 |
|
|
|
|
### 5.14 Reactions (3 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `reactions.list` | `list_reactions` | SELECT | P3 |
|
|
| `reactions.create` | `add_reaction` | INSERT | P3 |
|
|
| `reactions.delete` | `remove_reaction` | DELETE | P3 |
|
|
|
|
### 5.15 API Keys (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `apiKeys.list` | `list_api_keys` | SELECT | P2 |
|
|
| `apiKeys.create` | `create_api_key` | INSERT | P2 |
|
|
| `apiKeys.delete` | `delete_api_key` | DELETE | P2 |
|
|
| `apiKeys.info` | `get_api_key` | SELECT | P3 |
|
|
|
|
### 5.16 Webhooks (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `webhooks.list` | `list_webhooks` | SELECT | P3 |
|
|
| `webhooks.create` | `create_webhook` | INSERT | P3 |
|
|
| `webhooks.update` | `update_webhook` | UPDATE | P3 |
|
|
| `webhooks.delete` | `delete_webhook` | DELETE | P3 |
|
|
|
|
### 5.17 Backlinks (1 tool) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `backlinks.list` | `list_backlinks` | SELECT | P2 |
|
|
|
|
### 5.18 Search Queries (2 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `searchQueries.list` | `list_search_queries` | SELECT | P3 |
|
|
| `searchQueries.popular` | `get_popular_searches` | SELECT | P3 |
|
|
|
|
### 5.19 Teams (5 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `teams.info` | `get_team` | SELECT | P1 |
|
|
| `teams.update` | `update_team` | UPDATE | P2 |
|
|
| `teams.stats` | `get_team_stats` | SELECT | P2 |
|
|
| `teams.domains` | `list_team_domains` | SELECT | P2 |
|
|
| `teams.settings` | `update_team_settings` | UPDATE | P2 |
|
|
|
|
### 5.20 Integrations (6 tools) - CRÍTICO para embeds
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `integrations.list` | `list_integrations` | SELECT | P1 |
|
|
| `integrations.info` | `get_integration` | SELECT | P1 |
|
|
| `integrations.create` | `create_integration` | INSERT | P1 |
|
|
| `integrations.update` | `update_integration` | UPDATE | P2 |
|
|
| `integrations.delete` | `delete_integration` | DELETE | P2 |
|
|
| `integrations.sync` | `sync_integration` | UPDATE | P2 |
|
|
|
|
### 5.21 Notifications (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `notifications.list` | `list_notifications` | SELECT | P1 |
|
|
| `notifications.read` | `mark_notification_read` | UPDATE | P2 |
|
|
| `notifications.readAll` | `mark_all_notifications_read` | UPDATE | P2 |
|
|
| `notifications.settings` | `get_notification_settings` | SELECT | P2 |
|
|
|
|
### 5.22 Subscriptions (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `subscriptions.list` | `list_subscriptions` | SELECT | P1 |
|
|
| `subscriptions.create` | `subscribe_to_document` | INSERT | P2 |
|
|
| `subscriptions.delete` | `unsubscribe_from_document` | DELETE | P2 |
|
|
| `subscriptions.settings` | `get_subscription_settings` | SELECT | P2 |
|
|
|
|
### 5.23 Imports (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `imports.list` | `list_imports` | SELECT | P2 |
|
|
| `imports.status` | `get_import_status` | SELECT | P2 |
|
|
| `imports.create` | `create_import` | INSERT | P2 |
|
|
| `imports.cancel` | `cancel_import` | UPDATE | P2 |
|
|
|
|
### 5.24 Emojis (3 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `emojis.list` | `list_emojis` | SELECT | P2 |
|
|
| `emojis.create` | `create_emoji` | INSERT | P3 |
|
|
| `emojis.delete` | `delete_emoji` | DELETE | P3 |
|
|
|
|
### 5.25 User Permissions (3 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `userPermissions.list` | `list_user_permissions` | SELECT | P2 |
|
|
| `userPermissions.grant` | `grant_permission` | INSERT | P2 |
|
|
| `userPermissions.revoke` | `revoke_permission` | DELETE | P2 |
|
|
|
|
### 5.26 Bulk Operations (6 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `bulk.moveDocuments` | `bulk_move_documents` | UPDATE | P2 |
|
|
| `bulk.archiveDocuments` | `bulk_archive_documents` | UPDATE | P2 |
|
|
| `bulk.deleteDocuments` | `bulk_delete_documents` | DELETE | P2 |
|
|
| `bulk.updateDocuments` | `bulk_update_documents` | UPDATE | P2 |
|
|
| `documents.duplicate` | `duplicate_document` | INSERT | P2 |
|
|
| `collections.merge` | `merge_collections` | UPDATE | P2 |
|
|
|
|
### 5.27 Export/Import Avançado (4 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `export.collectionMarkdown` | `export_collection_to_markdown` | SELECT | P2 |
|
|
| `export.documentTree` | `export_document_tree` | SELECT | P2 |
|
|
| `import.markdownFolder` | `import_markdown_folder` | INSERT | P2 |
|
|
| `import.fromUrl` | `import_from_url` | INSERT | P3 |
|
|
|
|
### 5.28 Advanced Search (6 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `search.byDateRange` | `search_by_date_range` | SELECT | P2 |
|
|
| `search.byAuthor` | `search_by_author` | SELECT | P2 |
|
|
| `search.inCollection` | `search_in_collection` | SELECT | P2 |
|
|
| `search.orphanDocuments` | `find_orphan_documents` | SELECT | P2 |
|
|
| `search.emptyCollections` | `find_empty_collections` | SELECT | P2 |
|
|
| `search.brokenLinks` | `find_broken_links` | SELECT | P2 |
|
|
|
|
### 5.29 Analytics (6 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `analytics.workspace` | `get_workspace_stats` | SELECT | P2 |
|
|
| `analytics.userActivity` | `get_user_activity` | SELECT | P2 |
|
|
| `analytics.collection` | `get_collection_stats` | SELECT | P2 |
|
|
| `analytics.mostViewed` | `get_most_viewed_documents` | SELECT | P2 |
|
|
| `analytics.mostEdited` | `get_most_edited_documents` | SELECT | P2 |
|
|
| `analytics.stale` | `get_stale_documents` | SELECT | P2 |
|
|
|
|
### 5.30 External Sync (5 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `sync.deskProject` | `create_desk_project_doc` | INSERT | P3 |
|
|
| `sync.deskTask` | `link_desk_task` | INSERT | P3 |
|
|
| `embeds.create` | `create_embed` | INSERT | P2 |
|
|
| `embeds.update` | `update_embed` | UPDATE | P2 |
|
|
| `embeds.list` | `list_document_embeds` | SELECT | P2 |
|
|
|
|
### 5.31 Templates (5 tools) - NOVO
|
|
|
|
| API Endpoint | Tool MCP | Operação | Prioridade |
|
|
|--------------|----------|----------|------------|
|
|
| `templates.list` | `list_templates` | SELECT | P1 |
|
|
| `templates.info` | `get_template` | SELECT | P1 |
|
|
| `templates.create` | `create_from_template` | INSERT | P1 |
|
|
| `templates.convert` | `convert_to_template` | UPDATE | P2 |
|
|
| `templates.unconvert` | `convert_from_template` | UPDATE | P2 |
|
|
|
|
---
|
|
|
|
## 6. Resumo de Tools
|
|
|
|
### Por Prioridade
|
|
|
|
| Prioridade | Quantidade | Descrição |
|
|
|------------|------------|-----------|
|
|
| P1 | 32 | Core: CRUD, search, templates, integrations, notifications |
|
|
| P2 | 85 | Secundárias: bulk ops, analytics, search avançado, embeds |
|
|
| P3 | 27 | Avançadas: OAuth, sync externo, import URL |
|
|
| **Total** | **144** | |
|
|
|
|
### Por Módulo
|
|
|
|
| Módulo | Tools | Estado |
|
|
|--------|-------|--------|
|
|
| Documents | 17 | ✅ Implementado |
|
|
| Collections | 13 | ✅ Implementado |
|
|
| Users | 7 | ✅ Implementado |
|
|
| Groups | 7 | ✅ Implementado |
|
|
| Comments | 5 | ✅ Implementado |
|
|
| Shares | 4 | ✅ Implementado |
|
|
| Revisions | 2 | ✅ Implementado |
|
|
| Events | 1 | ✅ Implementado |
|
|
| Attachments | 3 | ✅ Implementado |
|
|
| Auth | 2 | ✅ Implementado |
|
|
| OAuth | 8 | ✅ Implementado |
|
|
| File Operations | 4 | ✅ Implementado |
|
|
| Stars | 3 | A implementar |
|
|
| Pins | 3 | A implementar |
|
|
| Views | 2 | A implementar |
|
|
| Reactions | 3 | A implementar |
|
|
| API Keys | 4 | A implementar |
|
|
| Webhooks | 4 | A implementar |
|
|
| Backlinks | 1 | A implementar |
|
|
| Search Queries | 2 | A implementar |
|
|
| Teams | 5 | A implementar |
|
|
| Integrations | 6 | A implementar (CRÍTICO) |
|
|
| Notifications | 4 | A implementar |
|
|
| Subscriptions | 4 | A implementar |
|
|
| Imports | 4 | A implementar |
|
|
| Emojis | 3 | A implementar |
|
|
| User Permissions | 3 | A implementar |
|
|
| Bulk Operations | 6 | A implementar |
|
|
| Export/Import | 4 | A implementar |
|
|
| Advanced Search | 6 | A implementar |
|
|
| Analytics | 6 | A implementar |
|
|
| External Sync | 5 | A implementar |
|
|
| Templates | 5 | A implementar |
|
|
|
|
---
|
|
|
|
## 7. Schema PostgreSQL (Outline)
|
|
|
|
### Tabelas Reais (41 tabelas - verificado 2026-01-31)
|
|
|
|
```sql
|
|
-- Core Content
|
|
documents -- Documentos e drafts
|
|
collections -- Organizações de documentos
|
|
revisions -- Histórico de versões
|
|
comments -- Comentários em documentos
|
|
attachments -- Ficheiros anexados
|
|
backlinks -- Links entre documentos
|
|
|
|
-- Users & Auth
|
|
users -- Utilizadores
|
|
teams -- Workspaces
|
|
groups -- Grupos de utilizadores
|
|
group_users -- Membros de grupos
|
|
user_permissions -- Permissões de utilizadores
|
|
user_authentications -- Autenticações de utilizadores
|
|
user_passkeys -- Passkeys WebAuthn
|
|
authentications -- Sessões de autenticação
|
|
authentication_providers -- Providers OAuth
|
|
oauth_authentications -- Tokens OAuth
|
|
oauth_authorization_codes -- Códigos OAuth
|
|
oauth_clients -- Clientes OAuth registados
|
|
apiKeys -- API tokens
|
|
|
|
-- Permissions
|
|
collection_users -- Permissões collection-user
|
|
collection_groups -- Permissões collection-group
|
|
group_permissions -- Permissões de grupos
|
|
|
|
-- Sharing & Social
|
|
shares -- Links públicos
|
|
stars -- Favoritos
|
|
pins -- Documentos fixados
|
|
views -- Visualizações de documentos
|
|
reactions -- Reacções (emojis em docs)
|
|
emojis -- Emojis customizados
|
|
relationships -- Relações entre entidades
|
|
|
|
-- Notifications & Events
|
|
events -- Audit log
|
|
notifications -- Alertas
|
|
subscriptions -- Subscrições de notificações
|
|
|
|
-- Import/Export
|
|
imports -- Imports em curso
|
|
import_tasks -- Tarefas de import
|
|
file_operations -- Operações de ficheiros
|
|
|
|
-- Integrations
|
|
integrations -- Integrações externas
|
|
webhook_subscriptions -- Webhooks registados
|
|
webhook_deliveries -- Entregas de webhooks
|
|
|
|
-- System
|
|
SequelizeMeta -- Migrações Sequelize
|
|
team_domains -- Domínios por team
|
|
search_queries -- Histórico de pesquisas
|
|
```
|
|
|
|
### Relações Chave
|
|
|
|
```
|
|
teams (1) ─────────< (N) users
|
|
teams (1) ─────────< (N) collections
|
|
teams (1) ─────────< (N) groups
|
|
teams (1) ─────────< (N) team_domains
|
|
teams (1) ─────────< (N) integrations
|
|
|
|
collections (1) ────< (N) documents
|
|
collections (1) ────< (N) collection_users
|
|
collections (1) ────< (N) collection_groups
|
|
|
|
documents (1) ──────< (N) comments
|
|
documents (1) ──────< (N) revisions
|
|
documents (1) ──────< (N) shares
|
|
documents (1) ──────< (N) attachments
|
|
documents (1) ──────< (N) views
|
|
documents (1) ──────< (N) stars
|
|
documents (1) ──────< (N) pins
|
|
documents (1) ──────< (N) reactions
|
|
documents (1) ──────< (N) backlinks
|
|
|
|
users (1) ──────────< (N) documents (createdById)
|
|
users (1) ──────────< (N) apiKeys
|
|
users (1) ──────────< (N) user_authentications
|
|
users (1) ──────────< (N) notifications
|
|
users (1) ──────────< (N) subscriptions
|
|
users (N) ─────────<>───── (N) groups (via group_users)
|
|
|
|
groups (N) ────────<>───── (N) collections (via collection_groups)
|
|
|
|
integrations (1) ───< (N) webhook_subscriptions
|
|
webhook_subscriptions (1) < (N) webhook_deliveries
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Implementação
|
|
|
|
### Fase 1: Setup (MVP)
|
|
|
|
```bash
|
|
# 1. Criar estrutura
|
|
mkdir -p ~/mcp-servers/mcp-outline/{src/{tools,types,config,utils},tests}
|
|
cd ~/mcp-servers/mcp-outline
|
|
|
|
# 2. Inicializar
|
|
npm init -y
|
|
npm install @modelcontextprotocol/sdk pg dotenv
|
|
npm install -D typescript @types/node @types/pg tsx vitest
|
|
|
|
# 3. Configurar
|
|
cp .env.example .env
|
|
# Editar .env com credenciais
|
|
|
|
# 4. Build
|
|
npm run build
|
|
|
|
# 5. Testar
|
|
npm run dev
|
|
```
|
|
|
|
### Fase 2: Core Tools (P1)
|
|
|
|
Implementar por ordem:
|
|
1. `list_documents`, `get_document`, `search_documents`
|
|
2. `list_collections`, `get_collection`
|
|
3. `list_users`, `get_user`
|
|
4. `create_document`, `update_document`
|
|
5. `create_collection`, `update_collection`
|
|
|
|
### Fase 3: Secondary Tools (P2)
|
|
|
|
1. Comments (CRUD)
|
|
2. Memberships
|
|
3. Revisions
|
|
4. Shares
|
|
5. Events
|
|
|
|
### Fase 4: Advanced Tools (P3)
|
|
|
|
1. Templates
|
|
2. Attachments
|
|
3. OAuth
|
|
4. Import/Export
|
|
|
|
---
|
|
|
|
## 9. Configuração Claude Code
|
|
|
|
### ~/.claude.json
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"outline": {
|
|
"command": "node",
|
|
"args": ["/home/ealmeida/mcp-servers/mcp-outline/dist/index.js"],
|
|
"env": {
|
|
"DATABASE_URL": "postgres://outline:outline_dev_2026@localhost:5432/outline"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Testes
|
|
|
|
### Estrutura
|
|
|
|
```
|
|
tests/
|
|
├── setup.ts # Configuração vitest
|
|
├── tools/
|
|
│ ├── documents.test.ts
|
|
│ ├── collections.test.ts
|
|
│ └── users.test.ts
|
|
└── integration/
|
|
└── full-flow.test.ts
|
|
```
|
|
|
|
### Exemplo Test
|
|
|
|
```typescript
|
|
import { describe, it, expect, beforeAll } from 'vitest';
|
|
import { Pool } from 'pg';
|
|
import { listDocuments } from '../src/tools/documents';
|
|
|
|
describe('Documents Tools', () => {
|
|
let pool: Pool;
|
|
|
|
beforeAll(() => {
|
|
pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL
|
|
});
|
|
});
|
|
|
|
it('list_documents returns array', async () => {
|
|
const result = await listDocuments.handler({}, pool);
|
|
const data = JSON.parse(result.content[0].text);
|
|
|
|
expect(Array.isArray(data.documents)).toBe(true);
|
|
expect(data.pagination).toBeDefined();
|
|
});
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Padrões de Código (do Desk)
|
|
|
|
### Response Format
|
|
|
|
```typescript
|
|
// SEMPRE retornar neste formato
|
|
return {
|
|
content: [{
|
|
type: 'text',
|
|
text: JSON.stringify(data, null, 2)
|
|
}]
|
|
};
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
```typescript
|
|
try {
|
|
const result = await pgClient.query(sql, params);
|
|
return {
|
|
content: [{
|
|
type: 'text',
|
|
text: JSON.stringify({ success: true, data: result.rows }, null, 2)
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
content: [{
|
|
type: 'text',
|
|
text: JSON.stringify({
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
}, null, 2)
|
|
}]
|
|
};
|
|
}
|
|
```
|
|
|
|
### Naming Conventions
|
|
|
|
| Tipo | Padrão | Exemplo |
|
|
|------|--------|---------|
|
|
| Tool name | snake_case | `list_documents` |
|
|
| Function | camelCase | `listDocuments` |
|
|
| Type | PascalCase | `DocumentRow` |
|
|
| File | kebab-case | `documents.ts` |
|
|
|
|
---
|
|
|
|
## 12. Checklist de Implementação
|
|
|
|
### Setup
|
|
- [ ] Estrutura de pastas criada
|
|
- [ ] package.json configurado
|
|
- [ ] tsconfig.json configurado
|
|
- [ ] .env configurado
|
|
- [ ] pg-client.ts implementado
|
|
|
|
### Tools P1
|
|
- [ ] list_documents
|
|
- [ ] get_document
|
|
- [ ] create_document
|
|
- [ ] update_document
|
|
- [ ] delete_document
|
|
- [ ] search_documents
|
|
- [ ] list_collections
|
|
- [ ] get_collection
|
|
- [ ] create_collection
|
|
- [ ] update_collection
|
|
- [ ] list_collection_documents
|
|
- [ ] list_users
|
|
- [ ] get_user
|
|
- [ ] list_groups
|
|
- [ ] get_group
|
|
- [ ] list_comments
|
|
- [ ] create_comment
|
|
- [ ] list_group_members
|
|
|
|
### Tools P2 (novas)
|
|
- [ ] list_stars
|
|
- [ ] star_document
|
|
- [ ] unstar_document
|
|
- [ ] list_pins
|
|
- [ ] pin_document
|
|
- [ ] unpin_document
|
|
- [ ] list_document_views
|
|
- [ ] list_backlinks
|
|
- [ ] list_api_keys
|
|
- [ ] create_api_key
|
|
- [ ] delete_api_key
|
|
|
|
### Integração
|
|
- [ ] Build sem erros
|
|
- [ ] Configurado em ~/.claude.json
|
|
- [ ] Tools visíveis no Claude Code
|
|
- [ ] Testes P1 passam
|
|
|
|
### Documentação
|
|
- [ ] README.md
|
|
- [ ] CHANGELOG.md
|
|
- [ ] Obsidian docs actualizados
|
|
|
|
---
|
|
|
|
## 13. Referências
|
|
|
|
- [Outline API Docs](https://www.getoutline.com/developers)
|
|
- [MCP SDK](https://modelcontextprotocol.io/)
|
|
- [mcp-desk-crm-sql-v3](~/mcp-servers/mcp-desk-crm-sql-v3/)
|
|
- [PostgreSQL pg docs](https://node-postgres.com/)
|
|
|
|
---
|
|
|
|
*Documento gerado: 2026-01-31*
|
|
*Autor: Descomplicar®*
|