Skip to main content
Glama
README.md
# @fswap/mcp-outline

An [MCP](https://modelcontextprotocol.io) server for [Outline](https://www.getoutline.com) that lets Claude Desktop, Claude Code, Cursor and other MCP clients search, read, create and update your wiki.

Runs locally over stdio. No install step — clients launch it with `npx`.

## Quick start

1. Create an API token in Outline under **Settings → API**.
2. Run the interactive setup once:

   ```bash
   npx -y @fswap/mcp-outline@latest setup
   ```

   It asks for your Outline URL and token, verifies them against `auth.info`, and stores them in your OS config directory (mode `0600`).

3. Add the server to your client. Every value asked in `setup` can be skipped with Enter; anything you skip goes into the `env` block shown below instead. `setup --print` shows these snippets again at any time.

   **Claude Desktop** (`claude_desktop_config.json`) and **Cursor** (`~/.cursor/mcp.json` or `<project>/.cursor/mcp.json`):

   ```json
   {
     "mcpServers": {
       "outline": {
         "command": "npx",
         "args": ["-y", "@fswap/mcp-outline@latest"]
       }
     }
   }
   ```

   **Codex** (`~/.codex/config.toml`):

   ```toml
   [mcp_servers.outline]
   command = "npx"
   args = ["-y", "@fswap/mcp-outline@latest"]
   ```

   **Claude Code**:

   ```bash
   claude mcp add outline -- npx -y @fswap/mcp-outline@latest
   ```

### Without `setup` (environment variables)

Environment variables take precedence over the config file, so you can skip `setup` entirely (or skip individual values in it and set them here):

```json
{
  "mcpServers": {
    "outline": {
      "command": "npx",
      "args": ["-y", "@fswap/mcp-outline@latest"],
      "env": {
        "OUTLINE_URL": "https://app.getoutline.com",
        "OUTLINE_API_TOKEN": "ol_api_..."
      }
    }
  }
}
```

Codex equivalent:

```toml
[mcp_servers.outline]
command = "npx"
args = ["-y", "@fswap/mcp-outline@latest"]
[mcp_servers.outline.env]
OUTLINE_URL = "https://app.getoutline.com"
OUTLINE_API_TOKEN = "ol_api_..."
```

| Variable | Purpose |
|---|---|
| `OUTLINE_URL` | Outline base URL (cloud or self-hosted) |
| `OUTLINE_API_TOKEN` | API token |
| `OUTLINE_ALLOW_DELETE` | `true` to expose `delete_document` |
| `OUTLINE_DEFAULT_COLLECTION` | Optional default collection name |

## Tools

| Tool | Outline endpoint | Notes |
|---|---|---|
| `list_collections` | `collections.list` | id, name, description, url |
| `get_collection` | `collections.info` | includes document tree |
| `search_documents` | `documents.search` | query, optional `collectionId`; returns snippets, not bodies |
| `get_document` | `documents.info` | full markdown body; accepts id or URL slug |
| `list_documents` | `documents.list` | filter by `collectionId` / `parentDocumentId` |
| `create_document` | `documents.create` | title, markdown, collection, optional parent; published by default |
| `update_document` | `documents.update` | title/text; `append=true` appends instead of replacing |
| `move_document` | `documents.move` | change collection and/or parent |
| `archive_document` | `documents.archive` | reversible |
| `delete_document` | `documents.delete` | only when delete is allowed (setup answer or `OUTLINE_ALLOW_DELETE=true`) |

API errors are returned to the model as `isError` results rather than crashing the server.

## Development

TypeScript source in `src/`, bundled to `dist/` with [tsdown](https://tsdown.dev). Only `dist/` is published.

```bash
npm install
npm run build        # tsdown → dist/index.js
npm run lint         # eslint (typescript-eslint)
npm run typecheck    # tsc --noEmit
npm test             # builds, then spawns the server and checks the tool list
npm run check        # all of the above (also runs on prepublishOnly)
OUTLINE_URL=... OUTLINE_API_TOKEN=... npm run inspect   # MCP Inspector UI against dist/
```

Never write to stdout from server code — it is the protocol channel. Use `console.error`.

## Reset

```bash
npx -y @fswap/mcp-outline@latest setup --reset
```

## License

MIT

TDQS

A4/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clearly distinct action-resource pairing: list/search/get/list-collections for reads, create/update/move/archive for writes. The only mild overlap is list_documents vs search_documents, but descriptions make the boundary explicit (metadata listing vs full-text search with snippets) and search_documents points to get_document for bodies.

Naming Consistency5/5

All nine tools follow a strict snake_case verb_noun pattern (list_collections, get_collection, list_documents, create_document, update_document, move_document, archive_document, search_documents, get_document) with no exceptions or mixed conventions.

Tool Count5/5

Nine tools is well-scoped for an Outline document service, covering both the collection and document resources without redundancy. Every tool earns its place, none feels like filler.

Completeness4/5

The document lifecycle is largely covered (list, search, get, create, update, move, archive), plus collection reads. However, there is no collection creation/update and no explicit unarchive/restore or hard delete, leaving minor gaps agents must work around; archive is documented as reversible but no restore tool is exposed.

Maintenance

ActivityMaintained
ResponsivenessNo issues