{"id":49315505,"url":"https://github.com/perforce/p4plan-mcp","last_synced_at":"2026-04-26T15:01:44.711Z","repository":{"id":350226340,"uuid":"1193857547","full_name":"perforce/p4plan-mcp","owner":"perforce","description":"[Community Supported] Perforce P4 Plan MCP is a Model Context Protocol (MCP) that integrates with the P4 Plan real-time planner.","archived":false,"fork":false,"pushed_at":"2026-04-16T12:02:24.000Z","size":148,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-16T13:29:08.412Z","etag":null,"topics":["hansoft","mcp","mcp-server","p4plan","p4plan-mcp","perforce"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/perforce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-27T16:48:13.000Z","updated_at":"2026-04-16T12:00:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/perforce/p4plan-mcp","commit_stats":null,"previous_names":["perforce/p4plan-mcp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/perforce/p4plan-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perforce%2Fp4plan-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perforce%2Fp4plan-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perforce%2Fp4plan-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perforce%2Fp4plan-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perforce","download_url":"https://codeload.github.com/perforce/p4plan-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perforce%2Fp4plan-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32301330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T09:34:17.070Z","status":"ssl_error","status_checked_at":"2026-04-26T09:34:00.993Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hansoft","mcp","mcp-server","p4plan","p4plan-mcp","perforce"],"created_at":"2026-04-26T15:01:44.444Z","updated_at":"2026-04-26T15:01:44.697Z","avatar_url":"https://github.com/perforce.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1\u003eP4 Plan MCP Server\u003c/h1\u003e\n\n![Support](https://img.shields.io/badge/Support-Community-yellow.svg)\n![License](https://img.shields.io/badge/License-MIT-blue.svg)\n\n\u003cp\u003e\n  \u003cstrong\u003eMCP (Model Context Protocol) server for P4 Plan, enabling AI assistants like Claude and VS Code Copilot to interact with P4 Plan project management data.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cnav aria-label=\"Quick navigation\"\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"#architecture\"\u003eArchitecture\u003c/a\u003e ·\n    \u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e ·\n    \u003ca href=\"#quick-start-npx\"\u003eQuick Start\u003c/a\u003e ·\n    \u003ca href=\"#installation\"\u003eInstall\u003c/a\u003e ·\n    \u003ca href=\"#client-configuration\"\u003eClient Configurations\u003c/a\u003e ·\n    \u003ca href=\"#available-tools-28-total\"\u003eTools\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"#skills--resources\"\u003eSkills\u003c/a\u003e ·\n    \u003ca href=\"#logging\"\u003eLogging\u003c/a\u003e ·\n    \u003ca href=\"#troubleshooting\"\u003eTroubleshoot\u003c/a\u003e ·\n    \u003ca href=\"#development\"\u003eDevelopment\u003c/a\u003e ·\n    \u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/nav\u003e\n\u003c/div\u003e\n\n## Architecture\n\nThis service acts as a **stateless** protocol adapter between MCP clients (AI assistants) and the P4 Plan GraphQL API, using **stdio transport** (stdin/stdout).\n\n```\n┌─────────────────┐     stdio (stdin/stdout)    ┌─────────────────┐     GraphQL      ┌─────────────────┐\n│   AI Client     │  ────────────────────────▶  │  P4 Plan MCP    │  ──────────────▶ │ P4 Plan GraphQL │\n│(Claude, Copilot)│   Spawns as child process   │    Server       │    Port 4000     │      API        │\n│                 │   P4PLAN_API_AUTH_TOKEN     │   (stateless)   │  Bearer token    │                 │\n└─────────────────┘          env var            └─────────────────┘  forwarded       └─────────────────┘\n```\n\nThe client spawns the MCP server as a child process. Authentication is provided via the `P4PLAN_API_AUTH_TOKEN` environment variable, which the server validates at startup and forwards to the GraphQL API on every tool call.\n\n## Prerequisites\n\n| Requirement             | Version                  | Notes                                                                                  |\n|-------------------------|--------------------------|----------------------------------------------------------------------------------------|\n| **Node.js**             | \\\u003e= 20 (24+ recommended) | The server targets ES2023. Check with `node -v`.                                       |\n| **npm**                 | \\\u003e= 9                    | Comes with Node.js. Check with `npm -v`.                                               |\n| **P4 Plan API**         | \\\u003e= 2026.1.002           | Required for all tool operations. Earlier versions are not supported.                  |\n\n\u003e **Tip:** Use [nvm](https://github.com/nvm-sh/nvm) to manage Node.js versions, or skip the Node.js requirement entirely by using [Docker](#docker).\n\n## Quick Start (npx)\n\nThe fastest way to get started — **no installation required**. Just configure your MCP client to use `npx`:\n\n```bash\nnpx -y @perforce/p4plan-mcp\n```\n\n`npx` automatically downloads and runs the latest version of the server. Your MCP client (VS Code, Claude Desktop, etc.) handles this for you — just add the config below and start chatting.\n\n**VS Code** — add to `.vscode/mcp.json`:\n\n```json\n{\n    \"servers\": {\n        \"p4-plan\": {\n            \"type\": \"stdio\",\n            \"command\": \"npx\",\n            \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n            \"env\": {\n                \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n                \"P4PLAN_API_URL\": \"http://localhost:4000\"\n            }\n        }\n    }\n}\n```\n\n**Claude Desktop** — add to your config:\n\n```json\n{\n  \"mcpServers\": {\n    \"p4-plan\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n      \"env\": {\n        \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n        \"P4PLAN_API_URL\": \"http://localhost:4000\"\n      }\n    }\n  }\n}\n```\n\n\u003e **Note:** The `-y` flag auto-confirms the npm install prompt so the server starts without user interaction.\n\nSee [Client Configuration](#client-configuration) for more options including Docker, secure token prompts, and local builds.\n\n## Installation\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eBuild from source\u003c/b\u003e\u003c/summary\u003e\n\nFor development or when you want to run from a local clone:\n\n```bash\nnpm ci\nnpm run build\n\n# For using npx locally\nnpm link\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eRun from Docker\u003c/b\u003e\u003c/summary\u003e\n\nRun the MCP server via Docker instead of installing Node.js locally. The MCP client (VS Code, Claude Desktop) spawns the container as a child process — same as `npx`, just using `docker` as the command.\n\n**Build the image:**\n\n```bash\ndocker build -t p4-plan-mcp .\n```\n\n**VS Code** (`.vscode/mcp.json`):\n\n```json\n{\n    \"servers\": {\n        \"p4-plan\": {\n            \"type\": \"stdio\",\n            \"command\": \"docker\",\n            \"args\": [\n                \"run\", \"-i\", \"--rm\",\n                \"-e\", \"P4PLAN_API_AUTH_TOKEN=YOUR_JWT_TOKEN\",\n                \"-e\", \"P4PLAN_API_URL=http://host.docker.internal:4000\",\n                \"p4-plan-mcp\"\n            ]\n        }\n    }\n}\n```\n\n**Claude Desktop:**\n\n```json\n{\n  \"mcpServers\": {\n    \"p4-plan\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\",\n        \"-e\", \"P4PLAN_API_AUTH_TOKEN=YOUR_JWT_TOKEN\",\n        \"-e\", \"P4PLAN_API_URL=http://host.docker.internal:4000\",\n        \"p4-plan-mcp\"\n      ]\n    }\n  }\n}\n```\n\n\u003e **Note:** Use `host.docker.internal` (macOS/Windows) or `172.17.0.1` (Linux) to reach the P4 Plan GraphQL API running on the host machine.\n\n\u003c/details\u003e\n\n## Configuration\n\nCopy the example config and configure:\n\n```bash\ncp config-example.env .env\n```\n\nEdit `.env` with your settings:\n\n```dotenv\n# JWT token for authenticating with P4 Plan GraphQL API\nP4PLAN_API_AUTH_TOKEN=your-jwt-token\n\n# P4 Plan GraphQL API URL\nP4PLAN_API_URL=http://localhost:4000\n\n# Logging level\nLOG_LEVEL=debug\n\n# Search results limit (default: 400)\n# SEARCH_LIMIT=400\n\n# Allow self-signed TLS certificates (for HTTPS APIs with untrusted certs)\n# P4PLAN_ALLOW_SELF_SIGNED_CERTS=true\n```\n\n\nThe server communicates via stdin/stdout. It is not meant to be run interactively — MCP clients (VS Code, Claude Desktop) spawn it as a child process automatically.\n\n## Authentication\n\nThe MCP server requires a JWT token provided via the `P4PLAN_API_AUTH_TOKEN` environment variable. The token is validated at startup and forwarded to the P4 Plan GraphQL API on every tool call. No sessions or state are maintained.\n\n### Obtaining a JWT Token\n\nGet a JWT token from the P4 Plan GraphQL API using `curl`. You can authenticate with either your **password** or a **Personal Access Token (PAT)**:\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eUsing your password\u003c/b\u003e\u003c/summary\u003e\n\n```bash\ncurl -s -X POST http://localhost:4000/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation Login($loginUserInput: LoginUserInput!) { login(loginUserInput: $loginUserInput) { access_token } }\",\n    \"variables\": { \"loginUserInput\": { \"username\": \"YOUR_USERNAME\", \"password\": \"YOUR_PASSWORD\" } }\n  }'\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eUsing a Personal Access Token (recommended)\u003c/b\u003e\u003c/summary\u003e\n\nA PAT can be used in place of your password in the same login mutation. This avoids exposing your actual password:\n\n```bash\ncurl -s -X POST http://localhost:4000/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation Login($loginUserInput: LoginUserInput!) { login(loginUserInput: $loginUserInput) { access_token } }\",\n    \"variables\": { \"loginUserInput\": { \"username\": \"YOUR_USERNAME\", \"password\": \"YOUR_PERSONAL_ACCESS_TOKEN\" } }\n  }'\n```\n\n\u003c/details\u003e\n\nBoth methods return the same response:\n\n```json\n{\n  \"data\": {\n    \"login\": {\n      \"access_token\": \"eyJhbGciOiJIUzI1NiIs...\"\n    }\n  }\n}\n```\n\nCopy the `access_token` value and use it in your MCP client configuration.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eGetting a Personal Access Token\u003c/b\u003e\u003c/summary\u003e\n\n1. Log in to P4 Plan\n2. Go to **User Settings** → **Personal Access Tokens**\n3. Click **Generate New Token**\n4. Set an appropriate expiration date\n5. Copy the token — use it in the login mutation above to obtain a JWT\n\n\u003c/details\u003e\n\n\u003e **Note:** JWT tokens expire. When your token expires, the server will fail to start with an authentication error. Generate a new JWT using the same `curl` command above.\n\n## Available Tools (28 total)\n\n### Projects\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003elist_projects\u003c/code\u003e\u003c/strong\u003e - List all active projects the user is a member of\u003c/summary\u003e\n\n- **Use cases**: Discover project IDs needed by other tools\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_project\u003c/code\u003e\u003c/strong\u003e - Get project configuration including archivedStatus, backlog ID, and QA ID\u003c/summary\u003e\n\n- **Parameters**: `projectId`\n- **Use cases**: Retrieve section IDs (backlog, QA, planning) for other tools\n\n\u003c/details\u003e\n\n### Tasks\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_my_tasks\u003c/code\u003e\u003c/strong\u003e - Get tasks assigned to current user (todoList)\u003c/summary\u003e\n\n- **Parameters**: `showCompleted`, `showOnlyNextFourWeeks`, `showHidden`, `showPipelineTasksThatCannotStart`\n- **Use cases**: View personal work queue across all projects\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_tasks\u003c/code\u003e\u003c/strong\u003e - Get detailed information for one or more items by ID (max 20)\u003c/summary\u003e\n\n- **Parameters**: `taskIds` (array of strings, max 20)\n- **Use cases**: Full item details, link inspection, batch retrieval of multiple items\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003esearch_tasks\u003c/code\u003e\u003c/strong\u003e - Search for items in a project section using P4 Plan Find queries\u003c/summary\u003e\n\n- **Parameters**: `findQuery`, `projectId`\n- Uses P4 Plan Find query syntax for all searches. Call `read_skill` with `skillName=\"search-queries\"` first to get exact column names, operators, and value formats. For simple name search use `Itemname:Text(\"text\")`. Supports filtering by status, assignee, severity, item type, dates, boolean conditions, and combinations with AND/OR/NOT.\n- Each project has three sections (Backlog, QA, Planning) with different IDs.\n- **Use cases**: Item discovery, filtering, reporting\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003ecreate_item\u003c/code\u003e\u003c/strong\u003e - Create any item type\u003c/summary\u003e\n\n- **Types**: `backlog_task`, `bug`, `scheduled_task`, `sprint`, `release`, `sprint_task`\n- **Parameters**: `type`, `name`, `projectId`, `parentItemId`, `previousItemId`, and type-specific fields\n- **Use cases**: Task creation, sprint creation, bug filing\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eupdate_item\u003c/code\u003e\u003c/strong\u003e - Update any item (auto-detects type)\u003c/summary\u003e\n\n- **Types**: BacklogTask, Bug, ScheduledTask, Sprint, Release\n- **Parameters**: `itemId`, plus any updatable fields (name, status, assignedTo, points, etc.)\n- **Use cases**: Status updates, assignments, estimation, sprint configuration\n\n\u003c/details\u003e\n\n### Sprint \u0026 Release Management\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003ecommit_to_sprint\u003c/code\u003e\u003c/strong\u003e - Commit a backlog task or bug to a sprint\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `sprintId`\n- **Use cases**: Sprint planning, backlog commitment\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003euncommit_from_sprint\u003c/code\u003e\u003c/strong\u003e - Remove a task from a sprint (return to backlog)\u003c/summary\u003e\n\n- **Parameters**: `taskId`\n- **Use cases**: Sprint scope adjustment\n\n\u003c/details\u003e\n\n### Custom Fields \u0026 Workflows\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_custom_columns\u003c/code\u003e\u003c/strong\u003e - Get custom column definitions available in a project\u003c/summary\u003e\n\n- **Parameters**: `projectId`\n- **Use cases**: Discover custom fields before reading/writing values\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_custom_fields\u003c/code\u003e\u003c/strong\u003e - Get custom field values set on a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `onlySet`\n- **Use cases**: Read project-specific metadata\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eset_custom_field\u003c/code\u003e\u003c/strong\u003e - Set a custom field value on a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `columnId`, `value`\n- **Use cases**: Update project-specific metadata\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_workflows\u003c/code\u003e\u003c/strong\u003e - Get workflow definitions and status IDs for a project\u003c/summary\u003e\n\n- **Parameters**: `projectId`\n- **Use cases**: Discover workflow statuses for status transitions\n\n\u003c/details\u003e\n\n### Task Actions\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003ecomplete_task\u003c/code\u003e\u003c/strong\u003e - Mark a task as completed\u003c/summary\u003e\n\n- **Parameters**: `taskId`\n- **Use cases**: Quick status update convenience method\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003estart_task\u003c/code\u003e\u003c/strong\u003e - Mark a task as in progress\u003c/summary\u003e\n\n- **Parameters**: `taskId`\n- **Use cases**: Quick status update convenience method\n\n\u003c/details\u003e\n\n### Comments \u0026 Attachments\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_comments\u003c/code\u003e\u003c/strong\u003e - Get all comments on a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`\n- **Use cases**: Read discussion history\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003epost_comment\u003c/code\u003e\u003c/strong\u003e - Post a new comment on a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `text`\n- **Use cases**: Add discussion, acceptance criteria, notes\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eupdate_comment\u003c/code\u003e\u003c/strong\u003e - Edit an existing comment\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `commentId`, `text`\n- **Use cases**: Correct or update existing comments\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003edelete_comment\u003c/code\u003e\u003c/strong\u003e - Delete a comment from a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `commentId`\n- **Use cases**: Remove outdated or incorrect comments\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_attachments\u003c/code\u003e\u003c/strong\u003e - Get all attachments on a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`\n- **Use cases**: List attached files, discover paths for download\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003edownload_attachment\u003c/code\u003e\u003c/strong\u003e - Download and return attachment file content\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `path`\n- Text files returned inline, images as base64\n- **Use cases**: Read attached documents, view screenshots\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003edelete_attachment\u003c/code\u003e\u003c/strong\u003e - Delete an attachment from a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `path`\n- **Use cases**: Remove outdated attachments\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eset_cover_image\u003c/code\u003e\u003c/strong\u003e - Set or unset the cover image for a task\u003c/summary\u003e\n\n- **Parameters**: `taskId`, `imagePath`\n- **Use cases**: Set visual identity for cards/items\n\n\u003c/details\u003e\n\n### Links\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003elink_items\u003c/code\u003e\u003c/strong\u003e - Create internal or external links\u003c/summary\u003e\n\n- **Parameters**: `fromItemId`, `toItemId` or `url`, `relation` (blocks, duplicates, relatedTo)\n- **Use cases**: Dependency tracking, cross-references, external URLs\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eunlink_items\u003c/code\u003e\u003c/strong\u003e - Remove an internal or external link\u003c/summary\u003e\n\n- **Parameters**: `fromItemId`, `toItemId` or `url`\n- **Use cases**: Clean up outdated dependencies\n\n\u003c/details\u003e\n\n### Users\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eget_current_user\u003c/code\u003e\u003c/strong\u003e - Get current user information\u003c/summary\u003e\n\n- **Use cases**: Identity verification, user context\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003elist_project_users\u003c/code\u003e\u003c/strong\u003e - List users in a project\u003c/summary\u003e\n\n- **Parameters**: `projectId`\n- **Use cases**: Find user IDs for assignments, sprint member management\n\n\u003c/details\u003e\n\n### Skills\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003e\u003ccode\u003eread_skill\u003c/code\u003e\u003c/strong\u003e - Read a P4 Plan skill document at runtime\u003c/summary\u003e\n\n- **Parameters**: `skillName`\n- Returns the full Markdown content of the requested skill document. The AI agent **must** call this with `skillName=\"search-queries\"` before composing any `findQuery` for `search_tasks`.\n- Available skills: `project-navigation`, `search-queries`, `task-management`, `planning`, `backlog-refinement`, `bug-tracking`, `custom-fields`, `gantt-scheduling`, `workflows`\n- **Use cases**: Learn correct query syntax, discover tool usage patterns, understand domain concepts\n\n\u003c/details\u003e\n\n## Client Configuration\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eVS Code (Copilot) — via npx (recommended)\u003c/strong\u003e\u003c/summary\u003e\n\nCreate `.vscode/mcp.json` in your workspace:\n\n```json\n{\n    \"servers\": {\n        \"p4-plan\": {\n            \"type\": \"stdio\",\n            \"command\": \"npx\",\n            \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n            \"env\": {\n                \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n                \"P4PLAN_API_URL\": \"http://localhost:4000\"\n            }\n        }\n    }\n}\n```\n\n\u003e **Note:** The `-y` flag auto-confirms the npm install prompt so the server starts without user interaction.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eVS Code (Copilot) — via node (local build)\u003c/strong\u003e\u003c/summary\u003e\n\nIf running from a local clone instead of npm:\n\n```json\n{\n    \"servers\": {\n        \"p4-plan\": {\n            \"type\": \"stdio\",\n            \"command\": \"node\",\n            \"args\": [\"/path/to/MCP/dist/main.js\"],\n            \"env\": {\n                \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n                \"P4PLAN_API_URL\": \"http://localhost:4000\"\n            }\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eVS Code — with secure token prompt\u003c/strong\u003e\u003c/summary\u003e\n\nFor added security, you can use VS Code input prompts to avoid storing tokens in files:\n\n```json\n{\n    \"inputs\": [\n        {\n            \"type\": \"promptString\",\n            \"id\": \"p4-plan-jwt\",\n            \"description\": \"P4 Plan JWT Token\",\n            \"password\": true\n        }\n    ],\n    \"servers\": {\n        \"p4-plan\": {\n            \"type\": \"stdio\",\n            \"command\": \"npx\",\n            \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n            \"env\": {\n                \"P4PLAN_API_AUTH_TOKEN\": \"${input:p4-plan-jwt}\",\n                \"P4PLAN_API_URL\": \"http://localhost:4000\"\n            }\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eClaude Desktop\u003c/strong\u003e\u003c/summary\u003e\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"p4-plan\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n      \"env\": {\n        \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n        \"P4PLAN_API_URL\": \"http://localhost:4000\"\n      }\n    }\n  }\n}\n```\n\nReplace `YOUR_JWT_TOKEN` with a token obtained from the login mutation (see [Obtaining a JWT Token](#obtaining-a-jwt-token)).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eClaude Code (CLI / VS Code extension)\u003c/strong\u003e\u003c/summary\u003e\n\nCreate `.mcp.json` in your project root:\n\n```json\n{\n  \"mcpServers\": {\n    \"p4-plan\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@perforce/p4plan-mcp\"],\n      \"env\": {\n        \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n        \"P4PLAN_API_URL\": \"http://localhost:4000\"\n      }\n    }\n  }\n}\n```\n\nFor a local build, replace `\"command\"` and `\"args\"` with:\n\n```json\n{\n  \"mcpServers\": {\n    \"p4-plan\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/MCP/dist/main.js\"],\n      \"env\": {\n        \"P4PLAN_API_AUTH_TOKEN\": \"YOUR_JWT_TOKEN\",\n        \"P4PLAN_API_URL\": \"http://localhost:4000\"\n      }\n    }\n  }\n}\n```\n\nOr add it via the CLI:\n\n```bash\nclaude mcp add p4-plan \\\n  -e P4PLAN_API_AUTH_TOKEN=YOUR_JWT_TOKEN \\\n  -e P4PLAN_API_URL=http://localhost:4000 \\\n  -- npx -y @perforce/p4plan-mcp\n```\n\n\u003e **Note:** The server name must come **before** the `-e` flags, otherwise the variadic `-e` parser consumes the name as an env value.\n\n**Verify it's running:** type `/mcp` inside Claude Code to check server status.\n\n\u003e **Tip:** Place `.mcp.json` in your project root to share the config with your team (tokens excluded). For personal config, add the server to `~/.claude.json` instead.\n\n\u003c/details\u003e\n\n### Verifying the Connection\n\n1. Ensure the P4 Plan GraphQL API is running\n2. Open VS Code with the workspace containing `.vscode/mcp.json`\n3. Look for \"MCP SERVERS\" in the Extensions sidebar — you should see \"p4-plan\" listed\n4. Start a new Copilot chat and ask \"What tasks are assigned to me?\"\n\n### Environment Variables\n\n- `P4PLAN_API_AUTH_TOKEN` - JWT token for authenticating with the P4 Plan GraphQL API\n- `P4PLAN_API_URL` - P4 Plan GraphQL API URL (default: `http://localhost:4000`)\n- `P4PLAN_ALLOW_SELF_SIGNED_CERTS` - Set to `true` to accept self-signed or untrusted TLS certificates when connecting to the API over HTTPS (default: `false`)\n- `LOG_LEVEL` - Logging level: `debug`, `info`, `warn`, `error` (default: `debug`)\n- `SEARCH_LIMIT` - Maximum number of results returned by `search_tasks` (default: `400`)\n\n## Skills \u0026 Resources\n\nThe server includes **skill files** — domain-specific guides that help AI agents construct correct tool calls. Skills are accessible in two ways:\n\n- **`read_skill` tool** — any MCP client can call `read_skill` with a `skillName` to fetch skill content at runtime. This is the primary access method and works with all clients.\n- **MCP resources** — skills are also registered as MCP resources (e.g., `skill://p4-plan/search-queries`) for clients that support native resource reading.\n\n| Skill              | Purpose                                                     |\n|--------------------|-------------------------------------------------------------|\n| project-navigation | Finding projects, items, and getting started                |\n| search-queries     | P4 Plan Find query syntax (column names, values, operators) |\n| task-management    | Task CRUD, status, assignments, comments, attachments       |\n| planning           | Sprints, releases, commitment, allocations                  |\n| backlog-refinement | Backlog items, estimation, prioritization                   |\n| bug-tracking       | Bugs, severity, QA section                                  |\n| custom-fields      | Custom columns, project-specific metadata                   |\n| gantt-scheduling   | Scheduled tasks, timeline, dependencies                     |\n| workflows          | Workflows, pipelines, status state machines                 |\n\nSee [`skills/README.md`](skills/README.md) for details on using skills with different AI clients.\n\n## Development\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eLocal Testing with npm link\u003c/b\u003e\u003c/summary\u003e\n\nTo test the `npx` experience locally without publishing to npm:\n\n```bash\n# Build and create a global symlink\nnpm run build\nnpm link\n\n# Now test exactly as an end user would\nP4PLAN_API_AUTH_TOKEN=your-jwt-token npx @perforce/p4plan-mcp\n\n# Clean up when done\nnpm unlink -g @perforce/p4plan-mcp\n```\n\nThe symlink persists across rebuilds — just run `npm run build` after code changes.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eAdding New Tools\u003c/b\u003e\u003c/summary\u003e\n\n1. Create or edit a tools file in `src/tools/`\n2. Define the tool with:\n   - `name`: Unique tool identifier\n   - `description`: What the tool does (shown to AI)\n   - `inputSchema`: JSON Schema for parameters\n   - `handler`: Function that executes the tool\n\n3. Register in `ToolsModule`\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eTesting\u003c/b\u003e\u003c/summary\u003e\n\n```bash\n# Unit tests\nnpm run test\n\n# E2E tests (MCP protocol compliance via @modelcontextprotocol/sdk)\nnpm run test:e2e\n```\n\n\u003c/details\u003e\n\n### Logging\n\nThe server uses Winston with two transports:\n\n- **Console (stderr):** Only warnings and errors are written to stderr. In VS Code, these appear in the Output panel under the \"p4-plan\" dropdown. Only `warn` and `error` level messages are shown to keep the output clean.\n- **File:** Full debug logs are written to `logs/P4PlanMCP_\u003ctimestamp\u003e.log`. Use these for detailed troubleshooting.\n\n\u003e **Note:** All console output goes to stderr (never stdout) because stdout is the MCP protocol channel. VS Code labels all stderr output as `[warning]` — this is expected behavior and does not indicate a problem.\n\n## Protocol\n\nThis server uses the **MCP stdio transport** — communication happens over stdin/stdout using JSON-RPC 2.0 messages. The client spawns the server as a child process.\n\n- **Transport:** stdio (stdin/stdout)\n- **Protocol:** JSON-RPC 2.0\n- **Authentication:** `P4PLAN_API_AUTH_TOKEN` environment variable (validated at startup)\n- **SDK:** `@modelcontextprotocol/sdk` with `StdioServerTransport`\n\n## Troubleshooting\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eServer fails to start\u003c/strong\u003e\u003c/summary\u003e\n\n1. **Check P4PLAN_API_AUTH_TOKEN is set:**\n   The server requires a valid JWT token in the `P4PLAN_API_AUTH_TOKEN` environment variable. If missing, it exits immediately with an error.\n\n2. **Check token is valid:**\n   If the token is expired or invalid, the server exits with \"Authentication failed\". Generate a new JWT using the login mutation.\n\n3. **Check GraphQL API is reachable:**\n   The P4 Plan GraphQL API must be accessible at the configured `P4PLAN_API_URL` (default: `http://localhost:4000`).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eServer not detected in VS Code\u003c/strong\u003e\u003c/summary\u003e\n\n1. **Verify mcp.json syntax:**\n   Ensure your `.vscode/mcp.json` is valid JSON. Check for trailing commas.\n\n2. **Check the command is available:**\n   If using `npx`, ensure Node.js is in VS Code's PATH. If `npx` is not found, use the absolute path to `node` instead (see [local build config](#vs-code-copilot--via-node-local-build)).\n\n3. **Reload VS Code window:**\n   Press `Cmd+Shift+P` → \"Developer: Reload Window\"\n\n4. **Start a new chat:**\n   MCP servers are connected when a new chat session starts.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eTools don't work\u003c/strong\u003e\u003c/summary\u003e\n\n1. **Check GraphQL server is running:**\n   The P4 Plan GraphQL API must be accessible at the configured URL.\n\n2. **Check server logs:**\n   In VS Code, check the Output panel → select \"p4-plan\" from the dropdown to see warnings/errors. For full debug logs, check the `logs/` directory.\n\n3. **Verify the JWT hasn't expired:**\n   Generate a new JWT if needed and update your mcp.json config.\n\n\u003c/details\u003e\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE.txt) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperforce%2Fp4plan-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperforce%2Fp4plan-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperforce%2Fp4plan-mcp/lists"}