Adds a command-line client in cli/ as its own Cargo workspace, depending on the outline library via a path dependency. Covers exactly the requested scope: login (stores the API key in the system keyring via the Secret Service D-Bus protocol, verified against auth.info() before storing), search (full-text), and get (fetch a document, render its markdown to a self-contained HTML page, open it in the default browser). Verified end-to-end against a real Outline instance and the local gnome-keyring: login stores and search/get retrieve the token purely from the keyring and saved config, with no environment variables set.
outline
An async Rust client library for the Outline knowledge base API.
This crate is the foundation for building Outline clients (CLI, GUI, ...) on top of a shared, well-tested API layer. It only talks to the API — no CLI or GUI code lives here.
Quickstart
use outline::Client;
# async fn run() -> outline::Result<()> {
let client = Client::new("ol_api_...")?;
let me = client.auth().info().await?;
println!("Signed in as {} ({})", me.user.name, me.team.name);
let mut documents = client.documents().list().collection_id("col_123").paginate();
while let Some(page) = documents.next_page().await? {
for document in page.items {
println!("{}", document.title);
}
}
# Ok(())
# }
For a self-hosted instance or an OAuth access token, use [Client::builder]:
use std::time::Duration;
use outline::Client;
# fn run() -> outline::Result<()> {
let client = Client::builder()
.base_url("https://wiki.example.com")
.access_token("...")
.timeout(Duration::from_secs(10))
.build()?;
# let _ = client;
# Ok(())
# }
Design notes
The Outline API is RPC-style: every endpoint is POST /api/<resource>.<action>
with a JSON body and a {ok, data, pagination, policies} envelope. This crate
mirrors that with a single internal request primitive; resources are exposed
as scoped accessors (client.documents(), client.collections(), ...).
Because the API is unversioned and self-hosted instances vary in age, models are deliberately forward-compatible: unknown fields are ignored and unknown string-enum values are preserved rather than causing deserialization to fail.
Status
This crate currently covers a first vertical slice of the API — auth,
documents, collections, users — chosen to validate the request/response
patterns (single object, paginated list, tree, create/update, delete, search)
used across the rest of the API. Broader endpoint coverage, automatic retry
on rate limiting, and streaming exports are planned but not yet implemented.
License
MIT OR Apache-2.0