Skip to main content
Glama
README.md
# 🎯 OmniFocus Operator

**The last OmniFocus MCP Server you'll ever need.**

![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue?logo=python&logoColor=white)
[![PyPI](https://img.shields.io/pypi/v/omnifocus-operator?logo=pypi&logoColor=white&color=blue)](https://pypi.org/project/omnifocus-operator/)
![Tests 2561](https://img.shields.io/badge/tests-2561-brightgreen)
![Coverage 97%](https://img.shields.io/badge/coverage-97%25-brightgreen)
![macOS only](https://img.shields.io/badge/platform-macOS-lightgrey?logo=apple)

Production-grade MCP server exposing OmniFocus as structured task infrastructure for AI agents. Agent-first design, SQLite-cached performance, 2,561 tests.

### [**β†’ See the full landing page**](https://hellothisisflo.github.io/omnifocus-operator) β€” features, architecture, benchmarks, and comparison

---

## πŸš€ Quick Start

**Prerequisites:** macOS, OmniFocus 4, Python 3.12+

> πŸͺ„ **Not sure where this config goes?** The [setup wizard](https://hellothisisflo.github.io/omnifocus-operator) on the landing page walks you through it step-by-step β€” including auto-merging with your existing config.

### For Claude Desktop

Paste this into `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "omnifocus-operator": {
      "command": "uvx",
      "args": ["omnifocus-operator"]
    }
  }
}
```

`uvx` downloads, isolates, and runs the server automatically. No install step.

> **First run:** OmniFocus shows a one-time permission dialog. Tick the box, click **Run Script**. You won't see it again.

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="docs/images/first-run-dark.png">
  <img src="docs/images/first-run-light.png" alt="OmniFocus first-run permission dialog showing OmniFocus Operator's welcome banner with two steps: tick the 'Automatically run' checkbox, then click Run Script" width="600">
</picture>

### For Claude Code, OpenCode, Cursor…

Ask your agent β€” copy this prompt:

> Add this MCP server to my client config. Just edit the config file β€” don't install anything, don't run any scripts.
>
> ```json
> "omnifocus-operator": {
>   "command": "uvx",
>   "args": ["omnifocus-operator"]
> }
> ```

> ⚠️ This doesn't work with Claude Desktop β€” Desktop has no config-editing tools. Use the manual paste above.

<details>
<summary><strong>Development install (contributors)</strong></summary>

```bash
git clone https://github.com/HelloThisIsFlo/omnifocus-operator.git
cd omnifocus-operator
uv sync
```

See [CONTRIBUTING.md](https://github.com/HelloThisIsFlo/omnifocus-operator/blob/main/CONTRIBUTING.md) for dev workflow details.

</details>

---

## ✨ Features

- ⚑ **46ms reads** β€” SQLite caching gives 30–60x faster reads than bridge-only servers
- πŸ› οΈ **11 MCP tools** β€” lookups, filtered lists, task creation & editing
- πŸ€– **Agent-first design** β€” warnings that teach, errors that educate, guidance in every response
- πŸ§ͺ **2,561 tests, 97% coverage** β€” strict mypy, no corners cut
- πŸ›‘οΈ **Graceful degradation** β€” server stays alive no matter what, always recoverable
- πŸ”„ **Automatic fallback** β€” SQLite β†’ OmniJS bridge when needed

See the [full documentation](https://hellothisisflo.github.io/omnifocus-operator) for architecture details, examples, and deep dives.

---

## πŸ› οΈ Available Tools

### Lookups

| Tool | Description |
|------|-------------|
| `get_all` | Full OmniFocus database as structured data (last-resort debugging) |
| `get_task` | Single task by ID β€” urgency, availability, dates, tags, parent, project |
| `get_project` | Single project by ID β€” status, review interval, next task |
| `get_tag` | Single tag by ID β€” availability, parent hierarchy |

### List & Filter

| Tool | Description |
|------|-------------|
| `list_tasks` | Filter by date, availability, flags, tags, project, parent subtree, search β€” with pagination, field selection, and presence-flag derivation |
| `list_projects` | Filter by status, folder, review schedule, flags |
| `list_tags` | List tags with parent hierarchy |
| `list_folders` | List folders with parent hierarchy |
| `list_perspectives` | List custom perspectives |

### Write

| Tool | Description |
|------|-------------|
| `add_tasks` | Create tasks with full field control β€” parent, tags, dates, flags, notes, repetition rules, parallel/sequential, completes-with-children |
| `edit_tasks` | Patch semantics β€” update fields, move tasks, complete/drop, manage tags, repetition rules, and hierarchy properties |

All read tools are idempotent. Write tools reference projects and tags by name or ID.

---

## πŸ” Tool Examples

**Filter tasks** (`list_tasks`):

```json
{
  "query": {
    "flagged": true,
    "due": "soon",
    "availability": "remaining",
    "include": ["notes"],
    "limit": 10
  }
}
```

**Create a task** (`add_tasks`):

```json
{
  "items": [{
    "name": "Review Q3 roadmap",
    "parent": "Work Projects",
    "tags": ["Planning"],
    "dueDate": "2026-03-15T17:00:00",
    "flagged": true,
    "estimatedMinutes": 30,
    "note": "Focus on v1.3-v1.5 milestones"
  }]
}
```

**Edit with patch semantics** (`edit_tasks`):

```json
{
  "items": [{
    "id": "oRx3bL_UYq7",
    "dueDate": null,
    "actions": {
      "tags": {"add": ["Urgent"]},
      "move": {"ending": "Work Projects"}
    }
  }]
}
```

**Patch semantics cheat sheet:**

| Input | Meaning |
|-------|---------|
| Field omitted | No change |
| Field set to `null` | Clear the value |
| Field set to a value | Update |

---

## πŸ—ΊοΈ Roadmap

| Version | Focus |
|---------|-------|
| **v1.0** | Foundation β€” read tools, three-layer arch, test suite βœ… |
| **v1.1** | Performance β€” SQLite caching, 30–60x speedup βœ… |
| **v1.2** | Writes & Lookups β€” add/edit tasks, get-by-ID βœ… |
| **v1.2.1** | Architectural Cleanup β€” contracts, service refactor, golden master tests βœ… |
| **v1.2.2** | FastMCP v3 Migration βœ… |
| **v1.2.3** | Repetition Rule Write Support βœ… |
| **v1.3** | Read Tools β€” SQL filtering, list/count, 5 new tools βœ… |
| **v1.3.1** | First-Class References β€” name resolution, `$inbox`, rich refs βœ… |
| **v1.3.2** | Date Filtering β€” 7 dimensions, shortcuts, calendar math βœ… |
| **v1.3.3** | Task Ordering β€” dotted notation, outline order βœ… |
| **v1.4** | Response Shaping & Batch Processing βœ… |
| **v1.4.1** | Task Properties & Subtree β€” presence flags, auto-complete, parallel/sequential, parent filter βœ… |
| **v1.4.2** | UNTIL Format Hotfix β€” parser accepts RFC 5545 DATE form; builder aligns with OmniFocus UI βœ… |
| **v1.4.3** | First-Run UX β€” welcome banners in `bridge.js` that frame OmniFocus's permission dialog with two-click instructions; startup log line βœ… |
| **v1.4.4** | Batch Limit Increase β€” `add_tasks` / `edit_tasks` accept up to 150 items per call βœ… |
| **v1.5** | Project Writes β€” add/edit projects, review marking |
| **v1.6** | UI & Perspectives β€” perspective switching, deep links |
| **v1.7** | Smart Perspective Content β€” perspective-aware response shapes |
| **v1.8** | Production Hardening β€” retry, crash recovery, serial execution |

---

## πŸ”— Links

- πŸ“– [Full Documentation](https://hellothisisflo.github.io/omnifocus-operator) β€” features, architecture, examples
- πŸ“¦ [PyPI](https://pypi.org/project/omnifocus-operator/) β€” package page
- πŸ› [Issues](https://github.com/HelloThisIsFlo/omnifocus-operator/issues)
- πŸ’¬ [Discussions](https://github.com/HelloThisIsFlo/omnifocus-operator/discussions)

---

## πŸ“„ License

Proprietary β€” all rights reserved. Free to use, not to redistribute. License under review.

## 🀝 Contributing

See [CONTRIBUTING.md](https://github.com/HelloThisIsFlo/omnifocus-operator/blob/main/CONTRIBUTING.md) for guidelines. In short: fork, branch, test, PR.