Skip to main content
Glama
norman2112

Planview Portfolios Actions MCP Server

by norman2112

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
USE_OAUTHNoSet to 'true' to use OAuth authenticationtrue
PLANVIEW_API_URLYesBase URL including /polaris path (lowercase). Example: https://your-instance.pvcloud.com/polaris
PLANVIEW_CLIENT_IDYesOAuth Client ID
PLANVIEW_TENANT_IDYesOrganization Tenant ID
PLANVIEW_CLIENT_SECRETYesOAuth Client Secret

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
oauth_pingA

[LOCAL — auth health check for this server's connection.]

Call secured ping to verify credentials.

get_project_attributesA

[LOCAL — raw attribute list. For natural-language attribute search, use Beta MCP's searchAttributes instead.]

List available project attributes.

get_work_attributesA

[LOCAL — raw work attribute list. For natural-language attribute search, use Beta MCP's searchAttributes(entity='work').]

Get available work attributes.

get_projectA

[LOCAL — single project read by ID. For listing/searching projects across a portfolio, use Beta MCP's listProjectsByPortfolioId or searchProjectByName instead.]

Get a single project by id.

create_projectA

[LOCAL — write operation. Beta MCP is read-only and cannot create projects.]

Create a new project.

Creates a project using the Planview Portfolios API. The payload should match the CreateProjectDtoPublic schema from the Swagger documentation.

Projects MUST have defined start and finish dates. If dates are not provided, default dates will be set: start date = today, finish date = 6 months from today.

Args: data: Project creation payload. Minimum required fields: - description: Project name/description (required) - parent: Object with structureCode (required) Optional fields: - scheduleStart: Start date (ISO 8601 format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS) - scheduleFinish: Finish date (ISO 8601 format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS) If not provided, defaults to today and 6 months from today respectively. attributes: Optional list of attributes to return in response create_default_tasks: If True, automatically creates 5 default sample tasks (Project Setup, Requirements Gathering, Design, Development, Testing)

Returns: Created project data from API response. The response may include warnings (e.g., "InvalidStructureCode", "InvalidDefaultValues") which are non-fatal. Projects are created successfully even with these warnings - they indicate configuration issues but don't prevent project creation.

Example: { "description": "Jon's MCP Project", "parent": {"structureCode": "14170"} }

With explicit dates:
{
    "description": "My Project",
    "parent": {"structureCode": "14170"},
    "scheduleStart": "2024-01-01",
    "scheduleFinish": "2024-06-30"
}

Notes: - See your instance's Swagger docs at {PLANVIEW_API_URL}/swagger/index.html for full schema details and additional optional fields like shortName, attributes, etc. - Warnings are non-fatal: Warnings like "InvalidStructureCode" or "InvalidDefaultValues" indicate Planview configuration issues (e.g., default region code not configured) but don't prevent successful project creation. Check response for warning details.

Note: On create, you MUST provide 'description' (project name) and 'parent' (structureCode of parent work item). Optional: scheduleStart, scheduleFinish (default to today and +6 months). For available writable fields, call list_field_reference() to browse by category: core_identity, dates, progress, status_assessments, investment_scoring, strategic_classification, wsjf_safe, risk, business_case_text, lifecycle_roles, financial_metrics, agileplace_integration, swot

update_projectA

[LOCAL — write operation. Beta MCP is read-only and cannot update projects.]

Update an existing project (partial payload).

Send only the fields you want to change. Field IDs are case-sensitive. Planview business rules may override some values (e.g., dates get calendar-aligned).

IMPORTANT CONSTRAINTS:

  • Duration is calculated from start/finish — don't send it directly

  • Lifecycle-controlled Work Status cannot be overridden via API

  • StructureCode fields: send {"structureCode": "CODE"} or {"structureCode": "CODE", "description": "LABEL"}

  • Fields marked PPL-only only work at Primary Planning Level (projects), not sub-tasks

For available writable fields, call list_field_reference() to browse by category: core_identity, dates, progress, status_assessments, investment_scoring, strategic_classification, wsjf_safe, risk, business_case_text, lifecycle_roles, financial_metrics, agileplace_integration, swot

delete_projectA

[LOCAL — write operation. Beta MCP is read-only and cannot delete projects. WARNING: destructive operation, deletes project and all child data.]

Delete a project by ID.

Deletes a project from Planview Portfolios using the REST API. WARNING: This is destructive and will delete the project and all its child tasks, financial plans, and other associated data.

Args: project_id: The structureCode/ID of the project to delete.

Returns: Dict with deletion status.

Raises: PlanviewNotFoundError: If the project doesn't exist. PlanviewAuthError: If authentication fails. PlanviewError: For other errors.

list_field_referenceA

[LOCAL — field discovery for write operations. For read-side attribute discovery, use Beta MCP's searchAttributes instead.]

List available writable project fields organized by category.

Use this tool to discover which field IDs to pass to update_project or create_project.

Args: category: Optional category filter. If not provided, returns all categories. Valid categories: core_identity, dates, progress, status_assessments, investment_scoring, strategic_classification, wsjf_safe, risk, business_case_text, lifecycle_roles, financial_metrics, agileplace_integration, swot

get_project_wbsA

[LOCAL — nested WBS tree with schedule data. For a flat hierarchy view, Beta MCP's getWorkHierarchy is an alternative.]

Get a project's WBS as a nested, lean tree.

Calls list_work with project.Id .eq {project_id} and rebuilds the parent/child structure into a sorted tree.

Node shape (lean): structureCode, description, depth, place, isMilestone, hasChildren, scheduleStart, scheduleFinish, status, constraintDate, constraintType, and children.

list_workA

[LOCAL — query work items with filter (e.g., project.Id .eq X). Limited filtering support. For portfolio-scoped project lists, use Beta MCP's listProjectsByPortfolioId instead.]

List work items using a filter string (e.g., project.Id .eq 1906).

If fields is provided, the response is trimmed per work item to reduce payload size.

update_workA

[LOCAL — write operation. Beta MCP is read-only and cannot update work items.]

Update an existing work item (partial payload).

Useful for updating phase/task fields like ExecType (execution type) on work items via PATCH /public-api/v1/work/{id}.

Note: Some instances reject PATCH on /work/{id} with HTTP 405. In that case, this tool returns a clear limitation message.

get_workB

[LOCAL — read any single work hierarchy node by ID (including portfolio-level nodes). For listing projects within a portfolio, use Beta MCP's listProjectsByPortfolioId.]

Get a single work item by id.

create_taskA

[LOCAL — write operation via SOAP. Beta MCP cannot create tasks.]

Create a new task using SOAP TaskService.

Creates a task (planning entity below PPL) in Planview Portfolios using the SOAP API.

Args: task_data: Task data dictionary with TaskDto2 fields. Required fields: - Description: Task description (required) - FatherKey: Parent work entity key URI (required) Optional fields: - Key: External key URI (recommended to prevent duplicates) - ScheduleStartDate: Schedule start date (ISO 8601) - ScheduleFinishDate: Schedule finish date (ISO 8601) - Duration: Duration in minutes - CalendarKey: Calendar key URI - EnterProgress: Enable manual progress entry (bool) - IsMilestone: Is this a milestone (bool) - IsTicketable: Can create tickets (bool) - IsDeliverable: Is deliverable (bool) - PercentComplete: Percent complete (0-100) - WorkId: Work ID string - WorkStatusKey: Work status key URI - LifecycleAdminUserKey: Lifecycle admin user key URI - Notes: Task notes - Place: Task place/order options: Optional WorkOptionsDto dictionary: - CopyMissingValuesFromPlanview: Copy missing values from existing record (bool) - RollupActuals: Roll up actuals to parent (bool) - ClearStagingTableAfterRun: Clear staging table after run (bool, default: True)

Returns: Dict with: - success: True if operation succeeded - data: Task DTO (may have null fields - this is normal SOAP API behavior) - warnings: List of non-fatal warnings

Note: The SOAP API may return null for many fields (e.g., ScheduleStartDate, Duration)
even though the task was created successfully with those values. This is expected behavior.
Use read_task() to verify the task was created with the correct data.

Raises: PlanviewValidationError: If task data is invalid PlanviewAuthError: If authentication fails PlanviewError: For other errors

Examples: Minimal (required fields only): {"Description": "My Task", "FatherKey": "key://2/$Plan/12345"}

With external key (recommended to prevent duplicates):
    {
        "Description": "My Task",
        "FatherKey": "key://2/$Plan/12345",
        "Key": "ekey://2/namespace/task-1"
    }

With schedule dates:
    {
        "Description": "My Task",
        "FatherKey": "key://2/$Plan/12345",
        "ScheduleStartDate": "2024-01-01T08:00:00",
        "ScheduleFinishDate": "2024-01-15T17:00:00"
    }

Notes: - Field names must use PascalCase (e.g., FatherKey, not father_key) - Date format: ISO 8601 (YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD) - Fields are automatically sorted alphabetically (Planview requirement) - None values are automatically filtered - Use external key (ekey://) to prevent duplicate creation

Known SOAP API Behaviors: - Response fields may be null: The SOAP API doesn't always populate all fields in the response DTO, even though the task was created successfully with those values. This is normal. The task IS created correctly in Planview - use read_task() to verify. - Warnings are non-fatal: Warnings indicate configuration issues but don't prevent creation. Check the warnings array in the response for details.

batch_create_tasksA

[LOCAL — bulk write operation via SOAP. Beta MCP cannot create tasks.]

Batch create multiple tasks in a single SOAP call.

Much faster than calling create_task() multiple times. Creates all tasks in a single SOAP request, significantly reducing latency for bulk creation.

Args: tasks: List of task creation dictionaries. Each dict must contain: - Description: Task description (required) - FatherKey: Parent work entity key URI (required) Optional fields: Key, ScheduleStartDate, ScheduleFinishDate, Duration, etc. (same as create_task) options: Optional WorkOptionsDto dictionary (applies to all tasks)

Returns: Dict with per-task results (SOAP may partially succeed): - success: True only if all tasks succeeded - created: List of per-task entries in the same order as tasks: - description: task description (if available) - key: created task key (for succeeded tasks) or null (for failed tasks) - status: "success" | "failed" - error: present only for failed tasks - summary: {total, succeeded, failed} - warnings: optional list of warning messages

Raises: PlanviewValidationError: If task data is invalid PlanviewAuthError: If authentication fails PlanviewError: For other errors

Example: tasks = [ { "Description": "Task 1", "FatherKey": "key://2/$Plan/12345", "ScheduleStartDate": "2024-01-01T08:00:00", "ScheduleFinishDate": "2024-01-15T17:00:00" }, { "Description": "Task 2", "FatherKey": "key://2/$Plan/12345", "ScheduleStartDate": "2024-01-16T08:00:00", "ScheduleFinishDate": "2024-01-30T17:00:00" } ] result = await batch_create_tasks(tasks)

Notes: - All tasks are created in a single SOAP call, making this much faster than individual create_task() calls - If some tasks fail, this tool still returns the successful ones so callers can avoid retrying the already-created tasks (which would create duplicates) - Response fields may be null - this is normal SOAP API behavior - Use read_task() to verify individual tasks if needed - Recommended to use external Key (ekey://) to prevent duplicates

batch_delete_tasksA

[LOCAL — bulk write operation via SOAP. Beta MCP cannot delete tasks.]

Delete multiple tasks in bulk using the SOAP TaskService.

Planview SOAP operations are not guaranteed atomic. This tool therefore returns per-key success/failure information so callers can safely retry only the failed keys (without re-deleting ones that already succeeded).

read_taskA

[LOCAL — SOAP task read by key. For reading tasks with custom attributes by project or task ID, Beta MCP's getTasksByProjectIds or getTasksByTaskIds may be richer.]

Read a task by key using SOAP TaskService.

Reads a task from Planview Portfolios using the SOAP API.

Args: task_key: Task key URI in key://, search://, or ekey:// format

Returns: Dict with task data (full TaskDto2)

Raises: PlanviewValidationError: If task_key is invalid PlanviewNotFoundError: If task is not found PlanviewAuthError: If authentication fails PlanviewError: For other errors

Example: task_key: "key://2/$Plan/12345" or: "ekey://2/namespace/task-1" or: "search://2/$Plan?description=Task Name"

delete_taskA

[LOCAL — write operation via SOAP. Beta MCP cannot delete tasks.]

Delete a task using SOAP TaskService.

Deletes a task from Planview Portfolios using the SOAP API. Note: Deleting a task will also delete all its child tasks.

Args: task_key: Task key URI in key://, search://, or ekey:// format

Returns: Dict with deletion status

Raises: PlanviewValidationError: If task_key is invalid PlanviewNotFoundError: If task is not found PlanviewAuthError: If authentication fails PlanviewError: For other errors

discover_financial_plan_infoA

[LOCAL — financial plan discovery with smart fallback. No Beta MCP equivalent exists.]

Discover financial plan information with smart fallback.

Attempts to read the financial plan for the target project. If that fails (e.g., project is too new), falls back to reading a reference project's financial plan to discover available accounts and periods.

Optimized to check config data first (instant), and skip slow target reads for new projects when skip_target_read=True. Use include_entries=False (default for this tool) to avoid large EntryDto arrays and reduce payload size.

Args: entity_key: Target project entity key (e.g., "key://2/$Plan/17291") version_key: Financial plan version key (default: "key://14/1" for Actual/Forecast) reference_entity_key: Optional reference project entity key for fallback. Defaults to None - if not provided and target read fails, returns config data. skip_target_read: If True, skip reading target project's plan (much faster for new projects). Defaults to False for backward compatibility. include_entries: If False, strip EntryDto arrays from each line (default False for smaller response). summary: If True, return only account_keys and period_keys (minimal response). fields: If set, return only these top-level data fields.

Returns: Dict with financial plan data including accounts and periods, or None if unavailable. May return config-based data structure for fast path.

Example: # Fast path for new projects - skip target read, use config or reference plan_info = await discover_financial_plan_info( entity_key="key://2/$Plan/17291", reference_entity_key="key://2/$Plan/3818", skip_target_read=True # Skip slow read for new project )

# Standard path - try target first, then reference
plan_info = await discover_financial_plan_info(
    entity_key="key://2/$Plan/17291",
    reference_entity_key="key://2/$Plan/3818"
)

if plan_info:
    # Extract accounts and periods
    lines = plan_info.get("data", {}).get("Lines", {}).get("FinancialPlanLineDto", [])
load_financial_plan_from_referenceA

[LOCAL — copy financial plan from reference project. No Beta MCP equivalent exists.]

Load a financial plan onto a project by copying the account structure and values from a reference project. Defaults to dry-run mode (confirm=False) which shows a preview without writing anything. Set confirm=True to execute.

This is a heavy operation — always preview first unless you're sure.

read_financial_planA

[LOCAL — SOAP financial plan read. No Beta MCP equivalent exists for financial plans.]

Read a financial plan for a project using SOAP FinancialPlanService.

This tool reads the financial plan structure including all account lines, entries, and periods. Use this to discover available accounts before adding new lines with upsert_financial_plan.

Args: entity_key: Project entity key (e.g., "key://2/$Plan/17288") version_key: Financial plan version key (e.g., "key://14/1" for Actual/Forecast) include_entries: If True, include EntryDto arrays for each line. Defaults to False. summary: If True, return only account_keys and period_keys (minimal response). fields: If set, return only these top-level data fields (e.g. ["EntityKey", "VersionKey", "Lines"]).

Returns: Dict with financial plan data including: - EntityKey: Project entity key - VersionKey: Version key - Lines: Array of FinancialPlanLineDto objects with account details (unless summary=True) - ModelDescription: Financial model name - VersionDescription: Version name

Raises: PlanviewValidationError: If entity_key or version_key is invalid PlanviewNotFoundError: If financial plan is not found PlanviewAuthError: If authentication fails PlanviewError: For other errors

Example: # Read financial plan for project 17288, Actual/Forecast version result = await read_financial_plan( entity_key="key://2/$Plan/17288", version_key="key://14/1" )

# Extract available accounts
lines = result.get("data", {}).get("Lines", {}).get("FinancialPlanLineDto", [])
accounts = {}
for line in lines:
    account_key = line.get("AccountKey")
    if account_key:
        accounts[account_key] = {
            "description": line.get("AccountDescription"),
            "parent": line.get("AccountParentDescription"),
            "unit": line.get("Unit"),
        }
upsert_financial_planA

[LOCAL — SOAP financial plan write. No Beta MCP equivalent exists.]

Upsert (create or update) a financial plan using SOAP FinancialPlanService.

Creates or updates a financial plan in Planview Portfolios using the SOAP API. This is a single-line update tool optimized for simple use cases.

Args: plan_data: Financial plan data dictionary. Required fields: - Key: Financial plan key URI (e.g., "ekey://12/MyPlan") OR - EntityKey: Entity key URI (e.g., "key://2/$Plan/17286") AND - VersionKey: Version key URI (e.g., "key://14/57") - Lines: List of FinancialPlanLineDto dictionaries Each FinancialPlanLineDto requires: - AccountKey: Account key URI (e.g., "key://2/$Account/13607") - Unit: Unit type ("Currency", "Units", "Unit Cost", "Unit Price", "FTE", "Hours") - Entries: List of EntryDto dictionaries - CurrencyKey: Currency key URI (defaults to "key://1/USD" if not provided) - Attributes: Optional list of LineAttributeDto dictionaries Each EntryDto requires: - PeriodKey: Period key URI (e.g., "key://16/197") - Value: Numeric value

Returns: Dict with: - success: True if operation succeeded - data: Financial plan DTO (may have empty Lines array - this is normal SOAP API behavior) - warnings: List of non-fatal warnings (e.g., "InvalidStructureCode", "InvalidDefaultValues")

Note: The SOAP API may return empty Lines array in the response even though data was persisted.
This is expected behavior - use read_financial_plan() to verify the data was saved.

Raises: PlanviewValidationError: If plan data is invalid PlanviewAuthError: If authentication fails PlanviewError: For other errors

Examples: Minimal (single line, single period): { "EntityKey": "key://2/$Plan/17286", "VersionKey": "key://14/57", "Lines": [{ "AccountKey": "key://2/$Account/13607", "Unit": "Currency", "CurrencyKey": "key://1/USD", "Entries": [{ "PeriodKey": "key://16/197", "Value": 10000 }] }] }

Using existing plan Key:
    {
        "Key": "ekey://12/MyPlan",
        "Lines": [{
            "AccountKey": "key://2/$Account/13607",
            "Unit": "Currency",
            "Entries": [{
                "PeriodKey": "key://16/197",
                "Value": 10000
            }]
        }]
    }

Notes: - Field names must use PascalCase (e.g., AccountKey, not account_key) - Only changed or added lines must be sent - AccountKey and PeriodKey must match Planview configuration - Unit types: "Currency", "Units", "Unit Cost", "Unit Price", "FTE", "Hours" - For new projects, the financial plan may not exist yet - upsert will create it

Common Errors and Solutions: - "No editable lines were provided": The account/period keys don't match the model. Solution: Use discover_financial_plan_info() or read_financial_plan() to find valid keys. - "Account not found in model": The specified account doesn't exist for this version. Solution: Use discover_financial_plan_info() with a reference project to discover valid accounts. - "Unable to find the requested Financial Plan": Plan doesn't exist (common for new projects). Solution: Use upsert_financial_plan() directly - it creates the plan if needed.

Known SOAP API Behaviors: - Response may show empty Lines array: The SOAP API doesn't always echo back the full payload. This is normal - the data IS persisted. Use read_financial_plan() to verify. - Warnings are non-fatal: Warnings like "InvalidStructureCode" or "InvalidDefaultValues" indicate configuration issues but don't prevent successful creation. Check the warnings array in the response for details.

list_objectivesA

[LOCAL — OKR objectives list. No Beta MCP equivalent exists for OKRs.]

List all objectives from the OKRs API.

Args: ids: Optional comma-separated list of objective IDs to filter by limit: Number of results to return (default: 10, max: 500) offset: Offset for pagination (default: 0)

Returns: Dict with objectives list and total_records count

Example: { "fetch_objectives": { "total_records": 1100, "objectives": [...] } }

get_key_results_for_objectiveA

[LOCAL — OKR key results for a single objective. No Beta MCP equivalent exists.]

Get all key results for a specific objective.

Args: objective_id: The ID of the objective

Returns: Dict with key_results array

Example: { "key_results": [ { "id": 28304, "name": "Increase NPS Score", "objective_id": 17841, ... } ] }

list_all_objectives_with_key_resultsA

[LOCAL — OKR objectives with key results. No Beta MCP equivalent exists.]

List all objectives with their key results.

This is a convenience function that fetches all objectives and optionally includes their key results in the response.

Args: limit: Maximum number of objectives per page (default: 500, max: 500) include_key_results: If True, fetch key results for each objective (default: True)

Returns: Dict with objectives and their key results: { "total_records": 1100, "objectives": [ { "id": 17841, "name": "Increase customer satisfaction", "key_results": [...], # Only if include_key_results=True ... } ] }

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/norman2112/portfoliosMCP'

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