Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
query_tasksA

Query tasks in an OmniPlan document with optional filters.

Args: keyword: Filter by title or note containing this text (case-insensitive). task_type: One of: task, group, milestone, hammock. completed: True = completed only, False = incomplete only, None = all. due_before: ISO date string (e.g. 2025-12-31). Tasks ending before this date. due_after: ISO date string (e.g. 2025-01-01). Tasks ending after this date. limit: Maximum number of tasks to return. Returns all tasks if omitted. detail: 'summary' (default) returns core fields only; 'full' returns all fields.

get_taskA

Get full details of a single task by its unique ID.

Args: task_id: The uniqueID of the task.

create_taskA

Create a new task in an OmniPlan document.

Args: title: Task title. parent_id: uniqueID of the parent task. If omitted, adds to root. task_type: One of: task, group, milestone, hammock. Defaults to task. note: Optional task description. manual_start_date: ISO date string for manual start. manual_end_date: ISO date string for manual end. effort_seconds: Total effort in person-seconds (e.g. 14400 for 4h). min_effort_seconds: Three-point estimation minimum (person-seconds). expected_effort_seconds: Three-point estimation expected value. max_effort_seconds: Three-point estimation maximum.

create_tasksA

Create multiple tasks in a single JXA call.

Performance: each evaluateJavascript round-trip is ~1-3s of osascript startup. Building 50 tasks via 50 calls to create_task is ~50-150s. This tool does the whole batch in one round-trip.

Args: tasks: list of task specs. Each spec is a dict with the same fields create_task accepts: title (required), parent_id, task_type, note, manual_start_date, manual_end_date, effort_seconds, min_effort_seconds, expected_effort_seconds, max_effort_seconds. Plus one extra: parent_index — int, optional. References another task in the same batch by zero-based position. Must be less than the task's own index. At most one of parent_id and parent_index may be set; if neither is set, the task is added under the document root.

Returns: JSON array of created-task shapes — same fields as create_task returns, in the order the inputs were given.

Raises ValueError on invalid parent_index references or unknown parent_id, before any task is created.

update_taskA

Update an existing task. Only provided fields are changed.

Args: task_id: The uniqueID of the task. title: New title. note: New note text. completed: True to mark complete, False to mark incomplete. manual_start_date: ISO date string, or empty string to clear. manual_end_date: ISO date string, or empty string to clear. effort_seconds: Total effort in person-seconds. Pass 0 to set to zero; None (omit) to leave unchanged. min_effort_seconds: Three-point estimation minimum (person-seconds). expected_effort_seconds: Three-point estimation expected value. max_effort_seconds: Three-point estimation maximum. start_no_earlier_than: ISO date string, or empty string to clear. Maps to task.startNoEarlierThanDate. start_no_later_than: ISO date string, or empty string to clear. Maps to task.startNoLaterThanDate. end_no_earlier_than: ISO date string, or empty string to clear. Maps to task.endNoEarlierThanDate. end_no_later_than: ISO date string, or empty string to clear. Maps to task.endNoLaterThanDate.

find_taskA

Look up tasks by title, returning lightweight identifiers.

Removes the "list everything → grep → use ID" pattern when an agent knows the title but not the uniqueID.

Args: name: Title to match. Case-insensitive substring match by default. exact: When True, only return tasks whose title equals name exactly (case-sensitive). When False, returns every descendant whose title contains name (case-insensitive).

Returns: JSON array of {"id", "title", "outline_id"}. Empty array if nothing matches. Order matches outline traversal (depth-first, children in document order).

move_taskA

Reparent a task without changing its uniqueID.

Wraps the omniJS task.move(newParent, index) method introduced in OmniPlan 4.10.3 (build v232.5.9, 2026-05-06). Both omniJS args are required at the API level; this tool fills in index with newParent.subtasks.length (append at end) when the caller omits it.

Because uniqueID is preserved across the move, dependencies and resource assignments that reference the moved task stay intact — no clone-and-rebuild required.

Args: task_id: uniqueID of the task to move. new_parent_id: uniqueID of the destination parent. If omitted, the task is moved to the document root. index: 0-based position in new_parent.subtasks after the move. If omitted, the task is appended at the end.

Returns: JSON {moved: true, id, new_parent_id, index} where id is the unchanged uniqueID, new_parent_id is the resolved parent's uniqueID (root's -1 if moved to root), and index is the final position used.

delete_taskC

Delete a task by its unique ID.

Args: task_id: The uniqueID of the task to delete.

list_documentsA

List all currently open OmniPlan documents. Note: task tools now always operate on the current front document.

save_documentA

Save the front OmniPlan document to disk.

OmniPlan does NOT autosave the front document on idle — verified empirically against OmniPlan 4.10.2 by editing a task via MCP and polling document.modified over a 10-second window: the flag stayed true throughout. Explicit save is therefore the only way to persist changes to disk between explicit File > Save commands in the UI (or quit-time prompts).

Returns: JSON {"saved": true, "name": "<doc>", "modified_after": false} on success. The modified_after field reads back the document's dirty flag after the save call to confirm the save took effect.

get_project_infoA

Return project-level info for the front document.

Returns: JSON {name, path, start_date, end_date, scenarios}. path comes from the JXA SDEF surface (omniJS doesn't expose it). start_date and end_date are the actual scenario's computed bounds (ISO YYYY-MM-DD). scenarios is ["Actual", ...proj.baselineNames] — the active scenario followed by every baseline scenario name defined on the project. The order matches OmniPlan's own baseline list; "Actual" is the conventional name for the active scenario (proj.actual).

omniJS surface gaps surfaced during implementation (probed 2026-05-01 against OmniPlan 4.10.2):

  • proj.startDate is undefined; date lives on actual.startDate.

  • actual.currency accepts a write inline but does NOT persist across JXA calls (same trap as constraint dates) — omitted from the response shape rather than returning a stale value.

update_projectA

Update project-level fields on the front document.

Args: start_date: ISO date for the project's actual start. Maps to document.project.actual.startDate. Verified persistent across JXA calls. Empty string is rejected — clearing the project start date isn't supported.

Returns: Post-write get_project_info shape.

Note: currency and working_hours are NOT supported by this tool. omniJS accepts the writes but they don't persist across calls (probed live 2026-05-01); shipping them would be a footgun. The fields would need a parallel SDEF AppleScript bridge.

add_dependencyA

Add a dependency from predecessor to successor.

Args: predecessor_id: uniqueID of the prerequisite task. successor_id: uniqueID of the dependent task. kind: One of "FS" (finish-to-start, default), "SS", "FF", "SF". lead_time_seconds: Lead time before the successor can start, in work-seconds. Defaults to 0. Negative values are not supported here; if you need lag in the other direction, model it as a different dependency kind.

Returns: JSON {predecessor_id, successor_id, kind, lead_time_seconds}. lead_time_seconds is read back via dep.leadTimeDuration.workSeconds after the write — a true round-trip, not an echo. When no Duration is set on the dependency (e.g. lead_time_seconds=0), the field is reported as 0 rather than null.

remove_dependencyA

Remove the dependency between two tasks.

Args: predecessor_id: uniqueID of the prerequisite task. successor_id: uniqueID of the dependent task.

Returns: JSON {"removed": true} if a matching dependency was found and removed, {"removed": false} if no such dependency existed.

list_dependenciesA

List dependencies in the document.

Args: task_id: Optional uniqueID. If provided, only dependencies where the task is the predecessor or successor are returned. If omitted, every dependency in the document is returned.

Returns: JSON array of {"predecessor_id", "successor_id", "kind", "lead_time_seconds"}. lead_time_seconds is read from dep.leadTimeDuration.workSeconds; it is null only when no lead-time Duration is set on the dependency.

list_resourcesA

List all resources in the document.

Returns: JSON array of {id, name, type, email, cost_per_use}. Walks the rootResource tree depth-first; group resources are flattened out (their leaf members appear individually).

create_resourceA

Create a new resource at the document's resource root.

Args: name: Resource name. type: One of "staff" (default), "equipment", "material", "group". email: Optional email address (relevant mainly for staff). cost_per_use: Optional cost in the document's currency. Stored as a Decimal — writes go through Decimal.fromString(...) so float inputs round-trip without Number precision issues.

Returns: JSON {id, name, type, email, cost_per_use} for the new resource.

move_resourceA

Reparent a resource without changing its uniqueID.

Wraps the omniJS resource.move(newParent, index) method introduced in OmniPlan 4.10.3 (build v232.5.9, 2026-05-06). Both omniJS args are required at the API level; this tool fills in index with newParent.members.length (append at end) when omitted.

Because uniqueID is preserved across the move, assignments that reference the moved resource stay intact — no clone-and-rebuild.

Args: resource_id: uniqueID of the resource to move. new_parent_id: uniqueID of the destination group resource. If omitted, the resource is moved under the document's rootResource. index: 0-based position in new_parent.members. If omitted, appended at the end.

Returns: JSON {moved: true, id, new_parent_id, index} where id is the unchanged uniqueID and new_parent_id is the resolved parent's uniqueID.

delete_resourceA

Delete a resource by uniqueID.

Args: resource_id: uniqueID of the resource to delete.

Returns: JSON {deleted: bool, id, name}. deleted is true when a matching resource was found and removed, false if not found. Removing a resource that is currently assigned to tasks succeeds — OmniPlan strips the assignments.

assign_resourceA

Assign a resource to a task.

Args: task_id: uniqueID of the task. resource_id: uniqueID of the resource. units: Optional fractional allocation (1.0 = 100% of a staff resource's working hours). Maps to the documented assignment.unitsAssigned accessor (Number, read/write). Round-trips cleanly across JXA call boundaries.

Returns: JSON {task_id, resource_id, units}. units is read back from assignment.unitsAssigned after the write — a true round-trip. When units is omitted on input, the returned value reflects whatever default OmniPlan applied (typically 1.0).

list_assignmentsA

List the resource assignments on a task.

Args: task_id: uniqueID of the task.

Returns: JSON array of {resource_id, resource_name, units_assigned} for each assignment on the task. Empty array if the task has no assignments. Reads assignment.unitsAssigned directly per the documented Assignment class.

unassign_resourceA

Remove a resource assignment from a task.

Args: task_id: uniqueID of the task. resource_id: uniqueID of the resource.

Returns: JSON {removed: bool}. True when a matching assignment was found and removed, false otherwise.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/johntrandall/omniplan-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server