Model Context Protocol server for the Deferno task manager backend.
Project description
Deferno MCP Server
An MCP server that exposes the Deferno task-manager backend to AI agents.
MCP is the open standard used by Claude Desktop / Claude Code, Cursor, Windsurf, Zed, VS Code Copilot agents, Continue, OpenAI Agents, and others, so this server works with any of them — you configure it once in your client and every tool and resource below becomes available.
What the agent can do
Tools (function calls)
| Tool | Purpose |
|---|---|
start_auth |
Begin browser-based login (returns a URL + session ID) |
complete_auth |
Exchange the browser code for a saved token |
logout |
Invalidate session and remove saved credentials |
whoami |
Return the currently authenticated user |
list_tasks |
List every task owned by the authenticated user |
get_task |
Fetch a single task by UUID |
create_task |
Create a new task (optionally nested under a parent) |
update_task |
Patch any mutable field (title, description, status, mood…) |
set_task_status |
Convenience wrapper for open/in-progress/done/… |
split_task |
Decompose a task into two child tasks |
fold_task |
Insert a next-step task into the sibling chain |
merge_task |
Roll a parent's active children back into the parent |
get_daily_tasks |
Today's prioritized tasks with urgency reasons |
get_mood_history |
Mood log for finished tasks |
Resources (readable by MCP clients that index resources)
| URI | Content |
|---|---|
defernowork://tasks |
All tasks for the current user |
defernowork://tasks/today |
Today's prioritized tasks |
defernowork://tasks/mood-history |
Mood log for finished tasks |
defernowork://task/{task_id} |
A single task by UUID |
Install
The easiest way is uvx — it runs the package
in an isolated environment without a manual install step:
uvx deferno-mcp
Or install permanently:
pip install deferno-mcp
# or with uv:
uv pip install deferno-mcp
Authenticate
Run the one-time auth command:
defernowork-mcp auth --base-url https://deferno.work
This opens a browser-based login flow:
- A URL is printed — open it in your browser
- Sign in (or approve if already signed in)
- A short code is shown — paste it back into the terminal
Your token is saved to ~/.config/defernowork/credentials.json and
loaded automatically on future runs. No env vars needed.
Alternatively, set DEFERNO_TOKEN as an environment variable to skip the
interactive flow (useful for CI or containers).
Authentication flow
The auth flow works the same whether triggered from the CLI
(defernowork-mcp auth) or from within an agent (the start_auth /
complete_auth MCP tools). Three backend endpoints coordinate the
handshake:
MCP / CLI Backend Browser
| | |
|-- POST /auth/cli/init -->| |
|<-- {session_id, url} ----| |
| | |
| (user opens url) | |
| |<--- GET /cli-auth?s=...---|
| | |
| | (user logs in if needed)|
| | |
| |<- POST /auth/cli/approve -|
| | {session_id} |
| |-- {code} ---------------->|
| | (browser shows code) |
| | |
| (user pastes code) | |
| | |
|-- POST /auth/cli/verify->| |
| {session_id, code} | |
|<-- {token, user} --------| |
| | |
| (token saved to disk) | |
Backend endpoints
| Endpoint | Auth | Request | Response |
|---|---|---|---|
POST /auth/cli/init |
none | {} |
{session_id: string, auth_url: string} |
POST /auth/cli/approve |
Bearer | {session_id: string} |
{code: string} |
POST /auth/cli/verify |
none | {session_id: string, code: string} |
{token: string, user: {id, username, …}} |
cli/init creates a pending CLI session in Redis with a short TTL
(~10 minutes) and returns a URL the user should open in their browser.
cli/approve is called by the frontend after the user is logged in.
It creates a new backend session for the CLI (including the cached
DEK so encrypted task data remains accessible), generates a short
one-time code, and stores both in the CLI session record. The browser
session and CLI session are independent — logging out of one does not
affect the other.
cli/verify is called by the MCP server / CLI. It looks up the
CLI session, verifies the code, returns the session token and user info,
and deletes the CLI session record from Redis.
Token resolution order
When the MCP server needs a token it checks, in order:
- Per-request
Authorization: Bearerheader (HTTP transport only) DEFERNO_TOKENenvironment variable- Saved credentials at
~/.config/defernowork/credentials.json
Agent-driven flow
When an agent (Claude Code, Cursor, etc.) calls any tool and gets a 401, the server instructions tell it to:
- Call
start_auth— returns{auth_url, session_id} - Show the URL to the user and ask them to sign in
- Ask the user to paste the code shown in their browser
- Call
complete_auth(session_id, code)— saves credentials to disk
All subsequent tool calls work automatically, including across restarts.
Where to implement
Backend (Deferno/backend/src/main.rs + repository.rs):
- Payload/response structs alongside the existing auth types
cli_init,cli_approve,cli_verifyhandler functionscli/initandcli/verifyas public routes;cli/approvebehindrequire_auth- CLI session CRUD in the repository layer (Redis key
cli_session:{id}, TTL 10 min)
Frontend (Deferno/webui/):
- New page
src/pages/CliAuth.tsxat route/cli-auth?session=<id> - If not logged in: redirect to login, then back to
/cli-auth - If logged in: show "Approve this CLI login?" button
- On approve: call
POST /auth/cli/approve, display the code
Configure
Environment variables:
| Variable | Default | Purpose |
|---|---|---|
DEFERNO_BASE_URL |
http://127.0.0.1:3000 |
URL of the Deferno backend HTTP API |
DEFERNO_TOKEN |
(unset) | Pre-existing bearer token; skips browser login |
DEFERNO_LOG_LEVEL |
WARNING |
Python logging level |
Client configuration snippets
Claude Desktop / Claude Code
Add to your MCP client settings (claude_desktop_config.json on
Claude Desktop, or Claude Code's mcpServers config):
{
"mcpServers": {
"deferno": {
"command": "uvx",
"args": ["deferno-mcp"],
"env": {
"DEFERNO_BASE_URL": "https://deferno.work"
}
}
}
}
The agent will walk you through browser-based auth on first use.
If you prefer to skip the interactive flow, add "DEFERNO_TOKEN": "...".
Cursor / Windsurf / Zed
Same shape — these clients all consume the MCP stdio transport. Point
them at the deferno-mcp command and set DEFERNO_BASE_URL.
VS Code Copilot agent mode
In .vscode/mcp.json:
{
"servers": {
"deferno": {
"command": "deferno-mcp",
"env": { "DEFERNO_BASE_URL": "https://deferno.work" }
}
}
}
Running the backend
The server talks to the Rust backend over HTTP. Start it first:
cd backend
cargo run
It listens on :3000 and connects to Redis via REDIS_URL
(default redis://127.0.0.1:6379/).
Development
Syntax / import sanity check:
python -c "from defernowork_mcp.server import create_server; create_server()"
The server implementation is a single module (src/defernowork_mcp/server.py)
plus a thin async HTTP client (src/defernowork_mcp/client.py) and
credential storage (src/defernowork_mcp/credentials.py). Adding a new
tool is a matter of wrapping a new client method in an @mcp.tool().
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file defernowork_mcp-0.1.13.tar.gz.
File metadata
- Download URL: defernowork_mcp-0.1.13.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8604e0e411ec4963b1cddde2e020ff440525fe2ef4d9e62e1ecc21c6314aab47
|
|
| MD5 |
afa905b8934e22d4109e613df8c5a4d0
|
|
| BLAKE2b-256 |
25bf8d057308bf97fc4bfb6f6b96074497317e65b8287d0902effcba5f1e9f85
|
Provenance
The following attestation bundles were made for defernowork_mcp-0.1.13.tar.gz:
Publisher:
release.yml on Kyle-Falconer/defernowork-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
defernowork_mcp-0.1.13.tar.gz -
Subject digest:
8604e0e411ec4963b1cddde2e020ff440525fe2ef4d9e62e1ecc21c6314aab47 - Sigstore transparency entry: 1287858107
- Sigstore integration time:
-
Permalink:
Kyle-Falconer/defernowork-mcp@0e1264b7063e88b843cf4e426917595d9a2bc332 -
Branch / Tag:
refs/tags/v0.1.13 - Owner: https://github.com/Kyle-Falconer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0e1264b7063e88b843cf4e426917595d9a2bc332 -
Trigger Event:
push
-
Statement type:
File details
Details for the file defernowork_mcp-0.1.13-py3-none-any.whl.
File metadata
- Download URL: defernowork_mcp-0.1.13-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be9058680a748367528bb5aba5b664b9531efc3107bb3ce7d3b2ea670dcaa46e
|
|
| MD5 |
6f020c3ad354410a721066852a3919a9
|
|
| BLAKE2b-256 |
d1386785359bd794438e48d23b79f9705252fd567909ceec23fed02a9aa5704a
|
Provenance
The following attestation bundles were made for defernowork_mcp-0.1.13-py3-none-any.whl:
Publisher:
release.yml on Kyle-Falconer/defernowork-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
defernowork_mcp-0.1.13-py3-none-any.whl -
Subject digest:
be9058680a748367528bb5aba5b664b9531efc3107bb3ce7d3b2ea670dcaa46e - Sigstore transparency entry: 1287858180
- Sigstore integration time:
-
Permalink:
Kyle-Falconer/defernowork-mcp@0e1264b7063e88b843cf4e426917595d9a2bc332 -
Branch / Tag:
refs/tags/v0.1.13 - Owner: https://github.com/Kyle-Falconer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0e1264b7063e88b843cf4e426917595d9a2bc332 -
Trigger Event:
push
-
Statement type: