Skip to main content

pymnifocus

A Python toolkit for OmniFocus on macOS: an MCP server for AI assistant integration (Cursor, Claude, Gemini) and a standalone CLI query tool.

Inspired by themotionmachine/OmniFocus-MCP, rebuilt in Python with security hardening, a CLI, and PyPI packaging.

Prerequisites

  • macOS with OmniFocus installed and running
  • Python 3.10+
  • uv (recommended) or pip

Installation

# From PyPI
pip install pymnifocus

# Or with uv
uv pip install pymnifocus

# For development
git clone https://github.com/vdanen/pymnifocus.git
cd pymnifocus
uv sync

CLI Query Tool

Query OmniFocus directly from your terminal with pymnifocus-query:

# Shorthand flags
pymnifocus-query --overdue
pymnifocus-query --flagged --sort dueDate
pymnifocus-query --inbox
pymnifocus-query --due-within 7 --limit 10
pymnifocus-query --project "Weekly Review"
pymnifocus-query --tag work --tag urgent
pymnifocus-query --available --summary
pymnifocus-query --today

# JSON input (same format as MCP query_omnifocus tool)
pymnifocus-query '{"entity": "tasks", "filters": {"status": ["Overdue", "DueSoon"]}, "sortBy": "dueDate"}'

# Pipe from stdin
echo '{"entity": "projects", "filters": {"status": ["Active"]}}' | pymnifocus-query

# Other tools
pymnifocus-query --tags
pymnifocus-query --perspectives
pymnifocus-query --dump

# Raw JSON output (for scripting)
pymnifocus-query --overdue --json

Run pymnifocus-query --help for full usage.

MCP Server

The MCP server enables AI assistants to interact with OmniFocus through natural language.

Running the Server

# Stdio transport (default, for Cursor/Claude/Gemini)
pymnifocus-server

# Streamable HTTP transport (for web clients or container access)
pymnifocus-server --transport streamable-http
pymnifocus-server --transport streamable-http --port 9000

# Or via module
python -m pymnifocus

Run pymnifocus-server --help for all options.

Cursor Integration

Edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "omnifocus": {
      "command": "pymnifocus-server"
    }
  }
}

Or if using uv from a local clone:

{
  "mcpServers": {
    "omnifocus": {
      "command": "uv",
      "args": [
        "run",
        "--project",
        "/path/to/pymnifocus",
        "python",
        "-m",
        "pymnifocus.server"
      ]
    }
  }
}

Restart Cursor or reload MCP servers (Cmd+Shift+P -> "MCP: Restart Servers").

Claude Code Integration

Same as above, just edit ~/.claude.json.

Claude Desktop Integration

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "omnifocus": {
      "command": "pymnifocus-server"
    }
  }
}

Restart Claude Desktop.

Google AI Studio / Gemini

For MCP-compatible Gemini clients, the server uses stdio transport by default:

  • Command: pymnifocus-server

For Streamable HTTP (web-based clients):

pymnifocus-server --transport streamable-http

Then connect to http://localhost:8000/mcp.

Container Access

Since OmniFocus is a macOS application, the MCP server must run on the macOS host. Containers can reach it over HTTP using host.docker.internal.

1. Start the server on the host:

pymnifocus-server --transport streamable-http

This binds to 127.0.0.1:8000 by default. OmniFocus must be running.

2. Configure the MCP client inside the container:

{
  "mcpServers": {
    "omnifocus": {
      "url": "http://host.docker.internal:8000/mcp"
    }
  }
}

3. Sample Containerfile:

FROM python:3.13-slim

RUN pip install --no-cache-dir mcp-client-cli

# Configure MCP to reach the host's pymnifocus server
RUN mkdir -p /root/.config
COPY <<'EOF' /root/.config/mcp.json
{
  "mcpServers": {
    "omnifocus": {
      "url": "http://host.docker.internal:8000/mcp"
    }
  }
}
EOF

CMD ["bash"]

Build and run (Docker or Podman):

docker build -t my-mcp-app .
docker run --rm -it my-mcp-app

Note: host.docker.internal resolves to the host machine on Docker Desktop for Mac and Podman Machine. On Linux with native Docker, add --add-host=host.docker.internal:host-gateway to the docker run command.

Available MCP Tools

Tool Description
query_omnifocus Query tasks, projects, or folders with filters
dump_database Get full OmniFocus database state
add_omnifocus_task Add a new task
add_project Add a new project
remove_item Remove a task or project
edit_item Edit a task or project
batch_add_items Add multiple items at once (max 100)
batch_remove_items Remove multiple items at once (max 100)
list_perspectives List available perspectives
get_perspective_view Get items from a perspective
list_tags List all tags with hierarchy

MCP Resources

URI Description
omnifocus://inbox Current inbox items
omnifocus://today Today's agenda (due, planned, overdue)
omnifocus://flagged All flagged items
omnifocus://stats Database statistics
omnifocus://project/{name} Tasks in a project
omnifocus://perspective/{name} Items in a perspective

Example Prompts

  • "Show me all flagged tasks due this week"
  • "Add a task 'Review quarterly report' to my Work project, due Friday"
  • "What's in my inbox?"
  • "List all my projects"
  • "Create a project called 'Website Redesign' with 3 tasks"

How It Works

The server communicates with OmniFocus using:

  • OmniJS scripts executed via JXA (osascript -l JavaScript) for queries, dumps, perspectives, and tags
  • AppleScript for add/edit/remove operations

OmniFocus must be running for either the MCP server or the CLI tool to function.

Security

  • All user input is validated and escaped before embedding in generated scripts
  • Entity names, sort fields, and field names are whitelisted
  • Numeric parameters are validated as integers
  • AppleScript strings are sanitized against injection (quotes, backslashes, newlines)
  • Script paths are constrained to prevent directory traversal
  • Batch operations are capped at 100 items
  • Query results are capped at 5000 items
  • Stdio transport: all communication is local (no network traffic)
  • HTTP transport: binds to localhost by default; use --host to override

License

MIT

Credits

Inspired by themotionmachine/OmniFocus-MCP. OmniJS scripts are adapted from that project.

Metadata

Release files for pymnifocus 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymnifocus 0.1.2
File Size Uploaded
pymnifocus-0.1.2.tar.gz 92.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pymnifocus 0.1.2
File Interpreter ABI Platform
pymnifocus-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 128.7 kB

Release files / pymnifocus-0.1.2.tar.gz

Download URL pymnifocus-0.1.2.tar.gz
Size 92.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2d85f7f6d8a8564abcd966100085ebba7dce31eadd5b652a90e10b8b9ab88d6d
BLAKE2b-256 checksum
How to use checksums
c9746db3ab7e6f01a7357f700e1975852c02a3271caab50940942cd87443d539
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 18, 2026.

Transparency log

Release files / pymnifocus-0.1.2-py3-none-any.whl

Download URL pymnifocus-0.1.2-py3-none-any.whl
Size 36.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b503b7a5664cde3b04486007765b9e9b6dc072824a3064a6dbb0d2fb6a04dc62
BLAKE2b-256 checksum
How to use checksums
4613e203f4c8ac499664d294eb53a17f2f7e39dbead292c701a9030223b1c2a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page