Files
mcp-outline-postgresql/SPEC-MCP-OUTLINE.md
Emanuel Almeida b05b54033f feat: Initial release MCP Outline PostgreSQL v1.0.0
86 tools across 12 modules for direct PostgreSQL access to Outline Wiki:
- Documents (19), Collections (14), Users (9), Groups (8)
- Comments (6), Shares (5), Revisions (3), Events (3)
- Attachments (5), File Operations (4), OAuth (8), Auth (2)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:25:09 +00:00

23 KiB

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

# 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

{
  "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

{
  "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

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

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
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

6. Resumo de Tools

Por Prioridade

Prioridade Quantidade Descrição
P1 18 Core: CRUD documentos, collections, users, search
P2 37 Secundárias: memberships, comments, shares, stars, pins, views, apiKeys
P3 28 Avançadas: templates, OAuth, attachments, reactions, webhooks
Total 83

Por Módulo

Módulo Tools Estado
Documents 17 A implementar
Collections 13 A implementar
Users 7 A implementar
Groups 7 A implementar
Comments 5 A implementar
Shares 4 A implementar
Revisions 2 A implementar
Events 1 A implementar
Attachments 3 A implementar
Auth 2 A implementar
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

7. Schema PostgreSQL (Outline)

Tabelas Reais (41 tabelas - verificado 2026-01-31)

-- 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)

# 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

{
  "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

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

// SEMPRE retornar neste formato
return {
  content: [{
    type: 'text',
    text: JSON.stringify(data, null, 2)
  }]
};

Error Handling

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


Documento gerado: 2026-01-31 Autor: Descomplicar®