Skip to main content

emperor_vikunja/
lib.rs

1//! MCP server for [Vikunja](https://vikunja.io), built on
2//! [emperor-mcp](https://github.com/yarenty/emperor-mcp).
3//!
4//! Six tools over a thin REST client: `list_tasks`, `get_task` and `list_projects` always,
5//! `create_task`, `update_task` and `comment` only when writing is switched on
6//! ([`VikunjaServer::writable`]; the server is read-only by default). The token is forwarded
7//! per request over HTTP or read from `VIKUNJA_TOKEN` in stdio mode, and never stored.
8//!
9//! - [`client`]: the Vikunja REST client (only the endpoints the tools use)
10//! - [`server`]: the rmcp `#[tool_router]` server
11//! - [`text`]: Markdown to HTML (in) and HTML to text (out)
12//! - [`dates`]: date arguments and Vikunja's zero time
13//! - [`doctor`]: the `doctor` subcommand
14
15#![warn(missing_docs)]
16
17pub mod client;
18pub mod dates;
19pub mod doctor;
20pub mod server;
21pub mod text;
22
23pub use client::{Token, Upstreams, Vikunja};
24pub use server::VikunjaServer;
25
26/// Log to stderr with an `RUST_LOG` filter (default `info`, rmcp at `warn`). Stderr keeps
27/// stdout clean for the stdio protocol stream (Emperor Profile E9).
28pub fn init_tracing() {
29    use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
30    let _ = tracing_subscriber::registry()
31        .with(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info,rmcp=warn".into()))
32        .with(fmt::layer().with_writer(std::io::stderr))
33        .try_init();
34}