Skip to main content

CLI for syncing Outline documents into a local cache and managing them through the raw API.

Project description

outline-edit

outline-edit is a Python command-line tool for working with an Outline knowledge base through the raw Outline API while keeping a local markdown cache on disk.

It is designed for agent and automation workflows that need cheaper repeated reads than full remote document fetches, plus predictable local diff, push, and lifecycle operations.

Why Not Just Use MCP?

Outline ships an MCP server, and MCP is usually the right choice for one-off interactive queries. But the MCP surface has structural inefficiencies that compound in agent and automation workflows:

Operation What MCP does Cost
List 50 recent docs Returns full ProseMirror JSON body for every doc ~1 MB of tokens
Read one document Searches by title, returns full content of all matches N x full doc bodies
Fix a typo Fetch full doc, generate full replacement, send full doc, re-fetch to verify 4 x full doc body
Browse a collection Returns full content of every doc in the collection Entire collection
Check what changed this week Fetch all docs just to read timestamps All content for metadata

Root causes (verified against Outline v1.6.1):

  • No metadata-only mode. list_documents always includes full document bodies. There is no way to request titles or timestamps without content.
  • No partial content. You cannot request a section or a summary — it is always the full document.
  • No diff or patch on update. update_document requires sending the entire body as a replacement. The only alternatives are append and prepend.
  • No revision history. The MCP does not expose revisions.* endpoints. You cannot retrieve past versions or compare revisions.
  • No event or audit log. The MCP does not expose events.list. You cannot ask "what changed this week" without fetching every document.
  • No reliable document read by ID. MCP resource URIs are registered but return authorization errors in practice.

outline-edit sidesteps these costs by maintaining a local markdown cache:

With outline-edit:
  Read a doc      →  local file read           (~0 API tokens)
  Edit a doc      →  local file edit           (~0 API tokens)
  Push edits      →  one API call              (1x full doc)
  Pull fresh copy →  one API call, cached      (1x full doc)

With MCP:
  Read a doc      →  search by title           (Nx full docs in results)
  Edit a doc      →  generate full replacement (1x full doc in context)
  Push edits      →  send full doc             (1x full doc)
  Verify the push →  search by title again     (Nx full docs)

Additional capabilities that MCP does not provide at all:

  • Revision history and revision-to-revision diff via the raw API
  • Activity and audit log queries
  • Document archive, restore, and delete operations
  • Optimistic-locking push that refuses to overwrite newer remote edits

Use MCP when you want direct tool-mediated interaction with a live Outline workspace. Use outline-edit when you want a reproducible local cache, a cheap read path for repeated workflows, or access to revision and audit capabilities.

Features

  • Local markdown cache with index metadata
  • Pull by collection, query, document ID, or full crawl
  • Local status, list, read, search, and diff
  • Remote create, push, publish, archive, restore, and delete
  • Revision history, activity log, and revision-to-revision diff
  • Starter config generation with init
  • Bundled agent skill definition via outline-edit skill
  • No third-party runtime dependencies

Requirements

  • Python 3.10+
  • An Outline instance with API access enabled
  • An API token with the scopes needed for your workflow

Installation

Install from PyPI:

pip install outline-edit

Install as a global tool with uv:

uv tool install outline-edit

Install as a global tool with pipx:

pipx install outline-edit

Run without installing:

uvx outline-edit --help

Install from a local checkout while developing:

uv tool install -e .

Configuration

You can configure the CLI with flags, environment variables, or an env file in the XDG config location.

Generate a starter config file:

outline-edit init

Generate and fill the required values interactively:

outline-edit init --interactive

Default config file:

~/.config/outline-edit/config.env

If XDG_CONFIG_HOME is set, the CLI uses:

$XDG_CONFIG_HOME/outline-edit/config.env

Example config file:

OUTLINE_CLI_BASE_URL=https://your-outline.example.com
OUTLINE_CLI_API_KEY=...

Optional settings:

OUTLINE_CLI_CACHE_DIR=/path/to/custom/cache
OUTLINE_CLI_TIMEOUT=30

Quick Start

Generate config and validate auth:

outline-edit init --interactive
outline-edit auth

Pull one collection into the local cache:

outline-edit pull --collection Engineering

Inspect the local cache:

outline-edit status
outline-edit list --collection Engineering
outline-edit read "Weekly Notes"
outline-edit search incident

Edit locally and push changes back:

outline-edit diff "Weekly Notes"
outline-edit push "Weekly Notes"

Create and publish documents:

outline-edit create --collection Engineering --title "CLI Test" --text "draft body"
outline-edit publish "CLI Test"

Manage lifecycle and history:

outline-edit archive "CLI Test"
outline-edit restore "CLI Test"
outline-edit delete "CLI Test"
outline-edit history "Architecture Notes" --limit 10
outline-edit revdiff "Architecture Notes" previous latest
outline-edit log "Architecture Notes" --limit 20

Agent Integration

outline-edit ships a built-in skill definition that any AI agent can retrieve at runtime:

outline-edit skill

This prints a structured markdown document describing all commands, recommended workflows, rules, and common patterns. Agents that can run shell commands can use this to learn how to operate the tool without external documentation.

The skill file is also available in the repository at integrations/skills/outline-edit/SKILL.md.

Notes

  • The env file defaults to ~/.config/outline-edit/config.env, or $XDG_CONFIG_HOME/outline-edit/config.env when XDG_CONFIG_HOME is set.
  • outline-edit init writes a commented starter config to that path and refuses to overwrite an existing file unless --force is passed.
  • The cache defaults to ~/.local/state/outline-edit/cache/<host>/, or $XDG_STATE_HOME/outline-edit/cache/<host>/ when XDG_STATE_HOME is set.
  • The default cache path is scoped by Outline host so different instances do not share one index by accident.
  • XDG path resolution is implemented directly with the Python standard library; platformdirs is intentionally not used so the runtime dependency set stays at zero.
  • push uses optimistic locking against the last content-synced revision and refuses to overwrite newer remote edits.
  • delete --permanent depends on the caller having the necessary Outline permission.
  • revdiff works against remote revisions and does not depend on the local cached file.

Gotchas

  • Optimistic locking, not merging. push checks the remote revision against your last pull. If someone else edited the document remotely, push refuses the update. You must re-pull (which overwrites your local copy) or resolve the conflict manually. There is no three-way merge.
  • diff is local-only. diff compares your cached file against the snapshot saved at last pull. It does not contact the remote server. Use revdiff to compare remote revisions against each other.
  • Search is substring-only. Local search does case-insensitive substring matching on titles, paths, and file content. There is no regex, fuzzy, or ranked full-text search.
  • pull --all fetches everything. On a large Outline workspace this can be slow and write a lot of files. Prefer pull --collection or pull --query to scope the sync.
  • delete --permanent is irreversible. The document is removed server-side and cannot be restored. This also requires the appropriate Outline permission on the server.
  • No automatic staleness detection. The cache does not refresh on its own. Run pull explicitly to update. status --stale shows documents where the remote revision is ahead of the cached content revision, but only based on metadata from the last pull.
  • Single-writer cache. The local cache is not designed for concurrent writes from multiple processes to the same cache directory.

Current Limits

Not currently exposed by outline-edit

  • Collection create/update/delete operations
  • Comments
  • Document move and duplicate operations
  • Attachment or file upload workflows
  • Recently viewed documents or per-document viewer reporting

Some of these exist in the Outline API but outline-edit does not wrap them yet.

Not a first-class primitive in the current workflow

  • Section-level patch or merge operations
  • Conflict-aware three-way merges
  • A structured query layer beyond local substring search plus event/revision inspection

The write path is document-oriented: local edit, diff, then push.

Development

Basic smoke checks from a checkout:

python3 -m py_compile src/outline_edit/*.py
PYTHONPATH=src python3 -m outline_edit --help

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

outline_edit-0.1.0.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

outline_edit-0.1.0-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

Details for the file outline_edit-0.1.0.tar.gz.

File metadata

  • Download URL: outline_edit-0.1.0.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for outline_edit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 716a402291004139936e1afa901ac0d6f066cf5166fdcb82624a4879523db623
MD5 08d5c8ec0e17e07a65d875b689513adc
BLAKE2b-256 2dcfe9da22e9c61a545d491db3dbee44cc7fa6af6b134b932d164a9468a6af00

See more details on using hashes here.

File details

Details for the file outline_edit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: outline_edit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for outline_edit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c346ec1ced3dd92fa92f9aae265d7515584eda688dca0ba7034025cbfb40ca50
MD5 9a26656041e5fda5b974f111d97d87ec
BLAKE2b-256 a1e6e8ebe1db2daef7b951efcfb3afb26c9fdf4d3c2171ba526c4513831c2bfb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page