Can an AI agent use Plane (plane.so)?

As of 15 Oct 2026, an AI agent gets into Plane on its own and does 90% of the core work.

Level 4 · Runs on its ownAn agent does the core work and can stop paying on its own.
  • Find: Docs for agents: llms.txt, an OpenAPI and an MCP server; a docs page for each core task.
  • Access: MCP sign-in, sign-up in a browser.
  • Use: 90% of the work.
  • Pay: Payment not tried.
  • Leave: Cancels on its own: Deletes its data, but the login stays.

Ways in: MCP sign-in, 0 of 10 core tasks · Sign-up in a browser, 9 of 10 core tasks

To reach L5 · Autonomous: pay without a person.

What the levels mean

Driven 15 Oct 2026Same level in 3 drives in a rowRules of 15 Oct 2026Claim this page

Written and checked by our agents from this drive's record. How we write.

Who gets in

  • Agents on a serverGet in on their own.
  • Signed agentsThe sign-up page opens.
  • Agents in a person's browserNot measured yet.

Sign-up page checked 15 Oct 2026. Signed agents: the ones Cloudflare verifies. Where agents come from

What an agent can do in Plane (plane.so).

On its own

  • Create, update, close and delete tasks, projects, sprints, modules, wiki pages, epics and cross-project initiatives, all checked by reading the result back
  • Comment on tasks, link them together, log time, attach files, search, and set up labels, states and estimates
  • Connect through the official programmatic assistant (MCP) to do the same things

What it can't, and why

  • Sign up or get an API key without a browserSign-up needs an emailed code and keys are made only in the web interface
  • Assign an AI agent to a taskThe page the product's own docs point to does not exist yet
  • Pay for a plan on its ownCard entry is on a payment page the agent's own rules keep it off
1 more
  • Delete the accountOnly deactivation exists, and signing back in with a code reactivates it
On its own, in a browser

Can an AI agent sign up for Plane on its own?

Yes, in a browser, without a human. app.plane.so/sign-up: email, then a 6-digit code; no CAPTCHA; no sign-up API.

Every way in it offers, as our agent tried them

Ways in
Way inWhat happened
Email and codeGot in, 9 min
Email and passwordNot tried: the same as another way
Continue with GitHubNot tried: no account yet
Continue with GoogleNot tried: no account yet
Sign‑in for apps (OAuth, MCP)Got in, 4 min
Company single sign‑onNot tried: needs a person's account
A key from a personNot tried: needs a person's account
Official server · 11 of 12 calls worked

Does Plane (plane.so) have an MCP server, and can an agent connect to it?

Yes. Plane has an official MCP server. The server lists 30 tools, signs an agent in with OAuth and speaks the 25 Nov 2025 MCP spec.

A new agent can get in on its own: in the drive of 15 Oct 2026, our agent signed up, verified and got its key without a person. Through the MCP server, 11 of our agent's 12 attempts worked.

What the drive found

APIOpenAPIMCP · official–CLIllms.txtWebhooks–Sandbox
On its own, in a browser

How does an AI agent get a Plane (plane.so) API key?

In the drive of 15 Oct 2026, our agent got its Plane API key in a browser, without a person. Personal access token made in Profile > Personal Access Tokens (expiry required in the UI though the docs call it optional); no API or CLI to mint or revoke keys. MCP OAuth (DCR + one consent click) also works.

The login stays

Can an AI agent delete its Plane account?

Not all of it: it deletes its data, but the login stays. Workspace deleted in the UI (data gone, PAT deleted, OAuth token refused); a temp workspace made only to reach the deactivate button may remain.

Payment not tried

Can an AI agent pay for Plane?

Not tried yet.

Chose a plan; the checkout didn't open: Business, $15 a month.

Checkout: Stripe CheckoutNo CAPTCHA at checkout

Ways to pay found: Stripe customer portal (billing.stripe.com).

It has a free plan.

What would let agents pay on their own
  1. Accept x402 or MPP on your API. Answer an unpaid call with 402 and a payment challenge, so an agent pays per call or buys credits without an account or a card.Step-by-step guide
  2. List your plans on Stripe Projects. Agents buy a plan with `stripe projects add`, paid with a token under a spend cap the owner sets (projects.dev).Step-by-step guide

No 402/x402/MPP, no billing API or MCP billing tool. A Business trial starts automatically with no card. Billing page 'Start subscription' shows $15.00/seat/month and 'Start subscription and pay' (not clicked); the card goes on Stripe's hosted portal (billing.stripe.com), which robots.txt closes to all user agents, so our agent stopped there. Pro ($8) is only offered as a trial switch.

Ways to pay checked 15 Oct 2026.

For the team behind Plane.

Where agents stop in Plane (plane.so) today, and the fixes that get them further, highest impact first.

Wall at delete

The fixes, highest impact first

  1. Add an API to mint and revoke scoped tokensStep-by-step guide
  2. Offer a real account delete
  3. Serve MCP (the 28 Jul 2026 spec) and CIMDStep-by-step guide
3 more fixes
  1. Fix the AI agents docs or page
  2. Accept an agent payment rail Step-by-step guide
  3. Return 404 and 401 consistently in API v1
  • Claim it free and reply next to the result.
  • A Drive, $49: your private report, with where agents stop, the evidence and the fixes that move your level.
  • Fixed something? Order a Drive ($49) any time, or the Monthly drive ($29/month).
See the example report
Details

Your API, MCP server or CLI is the product? An Audit ($299) also checks every documented route, MCP tool and CLI command against your docs. Compare plans.

Already claimed it? Open it in your dashboard.

Rather not be driven? Block AgentDrivesAgent in robots.txt or write to us. We stop driving it ourselves; this page stays, with its date.

Embed the badge on your site

Driven · L4 · Runs on its own badge

Behind the level.

The part scores and the measures behind them.

Part scores and the measures · the docs · level history · paid plans

Part scores

  • Holds up: 74 of 100, fair

Agent-ready setup

  • llms.txt: found
  • OpenAPI: found
  • MCP server: found
  • CLI: not found

Not measured in this drive: Docs match (part of an Audit).

The measures

  1. Work done90
  2. Reliability78
  3. Crash test69

The docs

600 of 1,301 pages read. Complete.

  • A getting-started page
  • An auth page
  • Errors listed with their codes
  • Code examples on most pages
  • Newest page updated 16 Oct 2026
  • A page for 10 of 10 core tasks

Read on 15 Oct 2026.

Tried as documented

18 of 20 documented ways to do the core work worked when tried.

Tried as documented
What happenedWays
Worked when tried18
Documented, didn't work1
Not tried (a paid plan, or no way to reach it)1
Worked, but not in the docs0

Level history

  1. 1 Oct 2026L4Runs on its own
  2. 2 Oct 2026L4Runs on its own
  3. 15 Oct 2026L4Runs on its own

Needs a paid plan

Not counted in the level. Our drive used no-card trial (Business, 14 days, started automatically).

Needs a paid plan
CapabilityPlan
Define a workflow with approval gates (custom workflows)Enterprise
Audit logs via APIEnterprise
How Plane handles an agent's mistakes · 9 probes · core run 3×

Malformed requests, a retry, a wrong key and a short burst of reads on our agent's own account, and how Plane answered.

  1. Clear errors70
  2. Recovery88
  3. Safe retries50
  • Silentrepeat create with the same Idempotency-Key headerCreate a work item201 content-type: application/json {"first": 201, "same_id": false}
  • Vaguewell-formed id that does not existCreate a work item403 content-type: application/json {"detail": "You don't have permission to view this workitem"}
  • Vaguewrong API keyCreate a work item403 content-type: application/json {"detail": "Given API token is not valid"}
  • Clearmissing required nameCreate a work item400 content-type: application/json {"name": ["This field is required."]}
  • Clearbad enum priorityCreate a work item400 content-type: application/json {"priority": ["\"super-high\" is not a valid choice."]}
  • Clearrepeat create with same external_id/external_sourceCreate a work item409 content-type: application/json {"first": 201, "second": {"error": "Issue with the same external id and external source already exists", "id": "e978f5cb-8dbc-4ccb-9497-5f0eeb64491b"}}
  • Clearburst of up to 20 GET /users/me/Create a work item200 {"statuses": [200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200], "headers": ["x-ratelimit-remaining: 32", "x-ratelimit-reset: 1792049295"]}
  • Clearinterrupt attachment upload after step 1 (no S3 upload, no confirm)Create a work item200 content-type: application/json {"pending_listed": false, "count": 1}
  • Clearwrong API key on v2Create a work item401 content-type: application/problem+json {"type": "unauthorized", "code": "unauthorized", "detail": "Authentication credentials were not valid."}

For agents and builders.

The drive as data, every checkpoint and all 210 attempts.

How an agent connects · 6 tips
  • Use the REST API with X-API-Key (v2 for bulk ops and problem+json errors) or the MCP PAT endpoint https://mcp.plane.so/http/api-key/mcp with x-workspace-slug
  • New projects made by API have cycles/modules/epics off: PATCH /projects/{id}/features/ first
  • Make creates idempotent with external_id + external_source (409 on repeat); Idempotency-Key is ignored
  • Estimate points must be POSTed as a raw JSON array to /estimate-points/, not in the estimate body
  • Deleted objects can answer 403 instead of 404 in v1: confirm with the list endpoint
  • MCP needs protocol 2025-11-25 (initialize), not 2026-07-28
Every checkpoint, in detail · 9 checkpoints
  1. DocsHeadlessllms.txt with Link headers, OpenAPI 3.1.0 (40 paths) plus a larger v1/v2 reference (982 pages in developers llms.txt), markdown by Accept and .md.
  2. Sign upIn a browserapp.plane.so/sign-up: email, then a 6-digit code; no CAPTCHA; no sign-up API.
  3. VerifyIn a browserThe emailed code verifies the address; it arrived within a minute and is valid 10 minutes.
  4. KeyIn a browserPersonal access token made in Profile > Personal Access Tokens (expiry required in the UI though the docs call it optional); no API or CLI to mint or revoke keys. MCP OAuth (DCR + one consent click) also works.
  5. First callHeadlessGET /api/v1/users/me/ and /workspaces/{slug}/projects/ with X-API-Key: 200.
  6. First actionHeadlessPOST /api/v1/workspaces/{slug}/projects/ 201, read back 200.
  7. PayIn a browserNo 402/x402/MPP, no billing API or MCP billing tool. A Business trial starts automatically with no card. Billing page 'Start subscription' shows $15.00/seat/month and 'Start subscription and pay' (not clicked); the card goes on Stripe's hosted portal (billing.stripe.com), which robots.txt closes to all user agents, so our agent stopped there. Pro ($8) is only offered as a trial switch.
  8. CancelIn a browserThe auto trial needed no card and downgrades to Free by itself; deleting the workspace required 'Cancel your trial first', done in the web UI; billing then showed Free Active, 'Free trial used'. No billing API.
  9. DeleteBlockedWorkspace deleted in the UI (data gone, PAT deleted, OAuth token refused); a temp workspace made only to reach the deactivate button may remain.
The attempt log · 210 attempts
Attempt log
CapabilityRouteResultEvidence
Docs: Read llms.txt, docs_pass verdictapidone ✓https://plane.so/llms.txt 200 text/plain, Link rel=describedby/service-desc; docs_pass verdict complete (600 pages)
robots: robots.txt + Content-Signalapidone ✓plane.so robots: User-agent * Disallow /admin/*; AI agents group Allow /; "Content-Signal: search=yes, ai-train=yes, ai-input=yes" (Cloudflare Content Signals scheme, parses). api.plane.so robots: User-agent: * Disallow: / (crawler rule). No Content-Usage (aipref).
A2A card: /.well-known/agent-card.jsonapidone ✓200 application/json, protocolVersion "0.3.0" (behind A2A 1.0); legacy /.well-known/agent.json 404
AI catalog / MCP server card: /.well-known/ai-catalog.json, <mcp>/server-card, /.well-known/mcp/server-card.jsonapifailed ✓all 404; non-standard /.well-known/mcp.json (200 JSON, 28 tools, endpoints) and /.well-known/ai-agent.json present
Markdown: Accept: text/markdown and .md on docsapidone ✓docs.plane.so and developers.plane.so return content-type text/markdown with vary: Accept; .md URLs 200 text/markdown
OpenAPI: plane.so/openapi.jsonapidone ✓openapi 3.1.0, 40 paths, server https://api.plane.so/api/v1
MCP discover: POST server/discover 2026-07-28 to https://mcp.plane.so/http/mcpapidone ✓401 invalid_token, WWW-Authenticate Bearer resource_metadata=https://mcp.plane.so/.well-known/oauth-protected-resource/http/mcp; PRM 200; AS metadata: registration_endpoint (DCR), no client_id_metadata_document_supported, S256, no device endpoint. Retry with credentials later.
auth.md / ucp: /auth.md, /.well-known/ucpapifailed ✓/auth.md 404 (markdown 404 body), /.well-known/ucp 404
Sign up: app.plane.so/sign-up email → unique codebrowserdone ✓Email field + Continue; no CAPTCHA signals; code mail from team@mailer.plane.so within ~1 min; code accepted → /onboarding/
Verify email: 6-digit login code from inboxbrowserdone ✓Subject "Your unique Plane login code is ••••", valid 10 minutes; entering it verified the email and opened onboarding
Onboarding: Profile + workspace create in onboardingbrowserdone ✓Workspace agentdrives-test-ebe971 created; dashboard shows "Business trial ends in 13d" (trial started automatically, no card asked); a default project "AgentDrives Test" was created
API key: Create Personal Access Token in Profile settings > Personal Access Tokensbrowserdone ✓expiry required (1 week chosen); allowed_rate_limit 60/min
First API call: GET /api/v1/users/me/ and /workspaces/{slug}/projects/ with X-API-Keyapidone ✓200 JSON; user id, email; projects list total_count 1 (cursor pagination)
API key: Use PATapidone ✓GET /api/v1/users/me/ 200; headers x-ratelimit-remaining/x-ratelimit-reset (legacy X- form)
Create a project: POST projectapidone ✓201 {"id": "[id]", "identifier": "AD994", "name": "AD drive project AD994"}
Create a project: GET projectapidone ✓200 {"name": "AD drive project AD994"}
Create a project: PATCH description, GET backapidone ✓200 {"desc": "updated by AgentDrives"}
Create a work item: POST work-itemsapidone ✓201 {"id": "[id]", "sequence_id": 1, "name": "AD test work item", "priority": "medium"}
Create a work item: GET work itemapidone ✓200 {"name": "AD test work item"}
Update or close a work item: PATCH name/priority/state=Done, GET backapidone ✓200 {"state": "[id]", "priority": "high", "completed_at": "2026-10-15T07:07:14.939323Z"}
Update or close a work item: GET after closeapidone ✓200 {"completed_at": "2026-10-15T07:07:14.939323Z"}
Create a work item: GET by readable identifier PROJ-Napidone ✓200 {"id": "[id]"}
Delete a work item: DELETE then GETapidone ✓204 {"get_after": 404, "body": {"error": "The requested resource does not exist."}}
Create a work item: DELETE then GET 404apidone ✓204 {"get_after": 404}
Plan a cycle (sprint) with start/end dates: POST cycles with datesapifailed400 {"non_field_errors": ["Cycles are not enabled for this project"]}
Break work into a module and assign items: POST modulesapifailed400 {"non_field_errors": ["Modules are not enabled for this project"]}
Plan a cycle: Enable cycles/modules/epics/intake on project via PATCH /projects/{id}/features/apidone ✓200 {"epics": true, "modules": true, "cycles": true, "views": true, "pages": true, "intakes": true, "work_item_types": true, "workflows": false, "parallel_cycles": false, "manually_start_end_cycles": false, "project_updates": false, "milestones": true}
Plan a cycle (sprint) with start/end dates: POST cycles with datesapidone ✓201 {"id": "[id]", "name": "AD Sprint 11e5", "start_date": "2026-10-19T00:00:01Z", "end_date": "2026-11-01T23:59:00Z"}
Plan a cycle: GET cycleapidone ✓200 {"start": "2026-10-19T00:00:01Z", "end": "2026-11-01T23:59:00Z"}
Plan a cycle: PATCH end_date, GET backapidone ✓200 {"end": "2026-11-02T00:00:00Z"}
Plan a cycle: add work item to cycle, list cycle-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_at': '2026-10-15T07:", "listed": true}
Plan a cycle: DELETE cycle, GETapidone ✓204 {"get_after": 404}
Break work into a module and assign items: POST modulesapidone ✓201 {"id": "[id]", "name": "AD Module d470", "status": "planned"}
Module: GET moduleapidone ✓200 {"name": "AD Module d470"}
Module: PATCH status in-progressapidone ✓200 {"status": "in-progress"}
Module: assign 2 items, list module-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_", "listed": [true, true]}
Module: DELETE module, GETapidone ✓204 {"get_after": 404}
Create and edit a wiki page: POST project pageapidone ✓201 {"id": "[id]", "name": "AD spec page"}
Page: GET pageapidone ✓200 {"name": "AD spec page", "html": "<p>Initial spec by AgentDrives</p>"}
Page: PUT title+content, GET backapidone ✓200 {"name": "AD spec page v2", "html": "<p class=\"editor-paragraph-block\" data-spacing-group=\"body\">Edited spec by Agent"}
Page: list project pages shows itapidone ✓200 {"listed": true}
Page: archive then DELETE, GETapidone ✓204 {"archive": 204, "delete": 204, "get_after": 404, "b": ""}
Create an epic and link child work items: POST epicsapidone ✓201 {"id": "[id]", "name": "AD Epic"}
Epic: GET epicapidone ✓200 {"name": "AD Epic"}
Epic: PATCH nameapidone ✓200 {"name": "AD Epic v2"}
Epic: link child item, list epic issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'type_id': '[id]', 'parent': '30300ca2-f1de-472a-8", "listed": true}
Epic: DELETE epic, GETapidone ✓204 {"get_after": 404}
Create an initiative to roll up multiple projects: POST v2 initiativesapidone ✓201 {"id": "[id]", "name": "AD Initiative 6ead"}
Initiative: GET initiativeapidone ✓200 {"name": "AD Initiative 6ead"}
Initiative: PATCH initiativeapidone ✓200 {"resp": "{'id': '[id]', 'name': 'AD Initiative 6ead', 'description': None, 'description_html': '<p>roll-up</p>', 'lead_id': Non", "state": "ACTIVE"}
Initiative: add 2 projects, list initiative projectsapidone ✓200 {"add": "{'added': ['[id]', '[id]'], 'removed': []}", "list": "{'data': [{'id': '[id]', 'name': 'AD drive project AD994', 'description': 'updated by Agent
Initiative: DELETE, GETapidone ✓204 {"get_after": 404}
Create a project: POST projectapidone ✓201 {"id": "[id]", "identifier": "ADF22", "name": "AD drive project ADF22"}
Create a project: GET projectapidone ✓200 {"name": "AD drive project ADF22"}
Create a project: PATCH description, GET backapidone ✓200 {"desc": "updated by AgentDrives"}
Create a project: enable cycles/modules/epics on the project (features PATCH)apidone ✓200 {"cycles": true, "modules": true}
Create a work item: POST work-itemsapidone ✓201 {"id": "[id]", "sequence_id": 1, "name": "AD test work item", "priority": "medium"}
Create a work item: GET work itemapidone ✓200 {"name": "AD test work item"}
Update or close a work item: PATCH name/priority/state=Done, GET backapidone ✓200 {"state": "[id]", "priority": "high", "completed_at": "2026-10-15T07:09:38.577404Z"}
Update or close a work item: GET after closeapidone ✓200 {"completed_at": "2026-10-15T07:09:38.577404Z"}
Create a work item: GET by readable identifier PROJ-Napidone ✓200 {"id": "[id]"}
Delete a work item: DELETE then GETapidone ✓204 {"get_after": 404, "body": {"error": "The requested resource does not exist."}}
Create a work item: DELETE then GET 404apidone ✓204 {"get_after": 404}
Plan a cycle (sprint) with start/end dates: POST cycles with datesapidone ✓201 {"id": "[id]", "name": "AD Sprint 6f26", "start_date": "2026-10-19T00:00:01Z", "end_date": "2026-11-01T23:59:00Z"}
Plan a cycle: GET cycleapidone ✓200 {"start": "2026-10-19T00:00:01Z", "end": "2026-11-01T23:59:00Z"}
Plan a cycle: PATCH end_date, GET backapidone ✓200 {"end": "2026-11-02T00:00:00Z"}
Plan a cycle: add work item to cycle, list cycle-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_at': '2026-10-15T07:", "listed": true}
Plan a cycle: DELETE cycle, GETapifailed204 {"get_after": 403}
Break work into a module and assign items: POST modulesapidone ✓201 {"id": "[id]", "name": "AD Module e7fe", "status": "planned"}
Module: GET moduleapidone ✓200 {"name": "AD Module e7fe"}
Module: PATCH status in-progressapidone ✓200 {"status": "in-progress"}
Module: assign 2 items, list module-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_", "listed": [true, true]}
Module: DELETE module, GETapidone ✓204 {"get_after": 404}
Plan a cycle: re-verify the same DELETE via listapidone ✓GET cycles list no longer contains the deleted cycle; GET by id answered 403 "You don't have permission to view this cycle" (trial 1 answered 404 for the same situation)
Create and edit a wiki page: POST project pageapidone ✓201 {"id": "[id]", "name": "AD spec page"}
Page: GET pageapidone ✓200 {"name": "AD spec page", "html": "<p>Initial spec by AgentDrives</p>"}
Page: PUT title+content, GET backapidone ✓200 {"name": "AD spec page v2", "html": "<p class=\"editor-paragraph-block\" data-spacing-group=\"body\">Edited spec by Agent"}
Page: list project pages shows itapidone ✓200 {"listed": true}
Page: archive then DELETE, GETapidone ✓204 {"archive": 204, "delete": 204, "get_after": 404, "b": ""}
Create an epic and link child work items: POST epicsapidone ✓201 {"id": "[id]", "name": "AD Epic"}
Epic: GET epicapidone ✓200 {"name": "AD Epic"}
Epic: PATCH nameapidone ✓200 {"name": "AD Epic v2"}
Epic: link child item, list epic issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'type_id': '[id]', 'parent': '0d475c48-9aad-414e-b", "listed": true}
Epic: DELETE epic, GETapidone ✓204 {"get_after": 404}
Create an initiative to roll up multiple projects: POST v2 initiativesapidone ✓201 {"id": "[id]", "name": "AD Initiative 7270"}
Initiative: GET initiativeapidone ✓200 {"name": "AD Initiative 7270"}
Initiative: PATCH initiativeapidone ✓200 {"resp": "{'id': '[id]', 'name': 'AD Initiative 7270', 'description': None, 'description_html': '<p>roll-up</p>', 'lead_id': Non", "state": "ACTIVE"}
Initiative: add 2 projects, list initiative projectsapidone ✓200 {"add": "{'added': ['[id]', '[id]'], 'removed': []}", "list": "{'data': [{'id': '[id]', 'name': 'AD drive project AD994', 'description': 'updated by Agent
Initiative: DELETE, GETapidone ✓204 {"get_after": 404}
Create a project: DELETE project, GETapifailed204 {"get_after": 403, "b": "{'detail': \"You don't have permission to view this project\"}"}
Create a project: re-verify the same DELETE via projects listapidone ✓projects list contains deleted project: False; GET by id 403 "You don't have permission to view this project" instead of 404
First real action: POST /api/v1/workspaces/{slug}/projects/ then GET it backapidone ✓201 project [id] created; GET 200 returns it
Create a project: POST projectapidone ✓201 {"id": "[id]", "identifier": "AD2B3", "name": "AD drive project AD2B3"}
Create a project: GET projectapidone ✓200 {"name": "AD drive project AD2B3"}
Create a project: PATCH description, GET backapidone ✓200 {"desc": "updated by AgentDrives"}
Create a project: enable cycles/modules/epics on the project (features PATCH)apidone ✓200 {"cycles": true, "modules": true}
Create a work item: POST work-itemsapidone ✓201 {"id": "[id]", "sequence_id": 1, "name": "AD test work item", "priority": "medium"}
Create a work item: GET work itemapidone ✓200 {"name": "AD test work item"}
Update or close a work item: PATCH name/priority/state=Done, GET backapidone ✓200 {"state": "[id]", "priority": "high", "completed_at": "2026-10-15T07:11:14.150287Z"}
Update or close a work item: GET after closeapidone ✓200 {"completed_at": "2026-10-15T07:11:14.150287Z"}
Create a work item: GET by readable identifier PROJ-Napidone ✓200 {"id": "[id]"}
Delete a work item: DELETE then GETapidone ✓204 {"get_after": 404, "body": {"error": "The requested resource does not exist."}}
Create a work item: DELETE then GET 404apidone ✓204 {"get_after": 404}
Plan a cycle (sprint) with start/end dates: POST cycles with datesapidone ✓201 {"id": "[id]", "name": "AD Sprint 786b", "start_date": "2026-10-19T00:00:01Z", "end_date": "2026-11-01T23:59:00Z"}
Plan a cycle: GET cycleapidone ✓200 {"start": "2026-10-19T00:00:01Z", "end": "2026-11-01T23:59:00Z"}
Plan a cycle: PATCH end_date, GET backapidone ✓200 {"end": "2026-11-02T00:00:00Z"}
Plan a cycle: add work item to cycle, list cycle-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_at': '2026-10-15T07:", "listed": true}
Plan a cycle: DELETE cycle, GETapidone ✓204 {"get_after": 404}
Break work into a module and assign items: POST modulesapidone ✓201 {"id": "[id]", "name": "AD Module 104d", "status": "planned"}
Module: GET moduleapidone ✓200 {"name": "AD Module 104d"}
Module: PATCH status in-progressapidone ✓200 {"status": "in-progress"}
Module: assign 2 items, list module-issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'sub_issues_count': 0, 'created_", "listed": [true, true]}
Module: DELETE module, GETapidone ✓204 {"get_after": 404}
Create and edit a wiki page: POST project pageapidone ✓201 {"id": "[id]", "name": "AD spec page"}
Page: GET pageapidone ✓200 {"name": "AD spec page", "html": "<p>Initial spec by AgentDrives</p>"}
Page: PUT title+content, GET backapidone ✓200 {"name": "AD spec page v2", "html": "<p class=\"editor-paragraph-block\" data-spacing-group=\"body\">Edited spec by Agent"}
Page: list project pages shows itapidone ✓200 {"listed": true}
Page: archive then DELETE, GETapidone ✓204 {"archive": 204, "delete": 204, "get_after": 404, "b": ""}
Create an epic and link child work items: POST epicsapidone ✓201 {"id": "[id]", "name": "AD Epic"}
Epic: GET epicapidone ✓200 {"name": "AD Epic"}
Epic: PATCH nameapidone ✓200 {"name": "AD Epic v2"}
Epic: link child item, list epic issuesapidone ✓200 {"add": "[{'id': '[id]', 'deleted_by': None, 'type_id': '[id]', 'parent': '97ccaa3f-7c89-4a29-a", "listed": true}
Epic: DELETE epic, GETapidone ✓204 {"get_after": 404}
Create an initiative to roll up multiple projects: POST v2 initiativesapidone ✓201 {"id": "[id]", "name": "AD Initiative 3811"}
Initiative: GET initiativeapidone ✓200 {"name": "AD Initiative 3811"}
Initiative: PATCH initiativeapidone ✓200 {"resp": "{'id': '[id]', 'name': 'AD Initiative 3811', 'description': None, 'description_html': '<p>roll-up</p>', 'lead_id': Non", "state": "ACTIVE"}
Initiative: add 2 projects, list initiative projectsapidone ✓200 {"add": "{'added': ['[id]', '[id]'], 'removed': []}", "list": "{'data': [{'id': '[id]', 'name': 'AD drive project AD994', 'description': 'updated by Agent
Initiative: DELETE, GETapidone ✓204 {"get_after": 404}
Create a project: DELETE project, GET by id + listapidone ✓204 {"get_after": 403, "b": "{'detail': \"You don't have permission to view this project\"}", "in_list": false}
Comment on a work item: POST comment, list commentsapidone ✓201 {"id": "[id]", "listed": true}
Link or relate two work items: POST linkapidone ✓201 {"id": "[id]", "listed": true}
Link or relate two work items: POST relation blockingapidone ✓201 [{"id": "[id]", "project_id": "[id]", "sequence_id": 8, "relation_type": "blocked_by", "name": "AD secondary item 2", "type_id": "[id]", "is_epic": false, "state_id": "[id]
Log time against a work item: POST worklog 30 min, listapifailed404 {"resp": "{'message': 'Worklog is not enabled for the project'}", "list": "{'message': 'Worklog is not enabled for the project'}"}
Search work items: GET work-items/search?search=secondaryapidone ✓200 "{'issues': [{'name': 'AD secondary item 2', 'id': '[id]', 'sequence_id': 8, 'project__identifier': 'AD994', 'project_id': '[id]', 'workspace__slug': 'agentdrives-test-ebe971', 'type_id':"
Log time against a work item: PATCH project is_time_tracking_enabled, POST worklog 30, listapidone ✓201 {"resp": "{'id': '[id]', 'created_at': '2026-10-15T07:13:01.558395Z', 'updated_at': '2026-10-15T07:13:01.558407Z', 'description'", "list": "[{'id': '[id]', 'created_at': '2026-10-15T07:13:01.558395Z', 'updated_at': '2026-10-15T0"}
Set estimate points and assign to a work item: POST estimate (3 points), set project estimate, PATCH work item estimate_pointapifailedPOST estimate 201 with estimate_points in body, but GET estimate-points returned [] (points not created from the create body); work item estimate_point stays null
Create and assign labels and custom states: POST label + POST state, assign both to itemapidone ✓POST label 201, POST state 200 (not 201), PATCH item labels+state; GET item shows label ad-label (as expanded objects) and state AD Review
Define custom work item types and properties: POST work-item-typesapidone ✓201 {"id": "[id]", "name": "AD Bug", "error": null, "detail": null}
Set estimate points and assign to a work item: POST estimate-points (raw array per docs example), PATCH work item estimate_point=3, GETapidone ✓200 {"estimate_point": "[id]", "ok": true}
Attach a file to a work item: POST attachments (upload creds) → POST file to S3 → PATCH is_uploaded → listapidone ✓200 {"s3": "204", "complete": 204, "listed": true}
Submit a request via intake and triage: POST intake-issues, listapidone ✓201 {"id": "[id]", "listed": true}
Customers: POST customersapifailed403 {"error": "Customer feature is not enabled for this workspace"}
Create a teamspace: POST v2 teamspacesapidone ✓201 {"id": "[id]", "name": "AD Team", "error": null, "detail": null, "message": null}
Create a customer profile and link requests: PATCH workspace features customers=true, POST customer, POST request with work item, listapidone ✓201 {"cust": 201, "req": 201, "listed": true}
Invite and manage workspace members: POST v2 invitations to our own second inbox, listapidone ✓201 {"resp": "{'id': '[id]', 'email': 'the agent's inbox', 'role': 'member', 'accepted': False, 'responded_at': None, 'messa", "listed": true}
Bulk-edit properties across selected work items: POST v2 bulk-update priority=urgent on 2 items, GET bothapidone ✓200 {"resp": "{'results': [{'index': 0, 'result': 'updated', 'id': '[id]'}, {'index': 1, 'result': 'updated', 'id': '63815079-fc92-4", "p": ["urgent", "urgent"]}
Create a work item template and apply it: POST v2 work-item-templatesapidone ✓201 {"id": "[id]", "resp": "{'id': '[id]', 'name': 'AD template', 'short_description': '', 'description_html': '<p></p>', 'template_type': 'workit"}
MCP discover (with PAT): POST server/discover 2026-07-28 to https://mcp.plane.so/http/api-key/mcp, then initializemcpdone ✓server/discover → HTTP 400 JSON-RPC -32600 "Unsupported protocol version: 2026-07-28. Supported versions: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25" (not -32022: legacy). initialize offering 2026-07-28 → protocolVersion 2025-11-25, serverInfo "Plane MCP Server (header-http)" 3.2.0, SSE reply, no Mcp-Session-Id. tools/list: 30 tools (mcp.json says 28).
Docs claim: Create a project: project(action="create")mcpdone ✓create ok=True; retrieve name=AD MCP project
Docs claim: Create a work item: workitem(action="create")mcpdone ✓create→retrieve {'id': '[id]', 'assignees': [], 'labels': [], 'type_id': 'b1bf060c-7824-4594-b968-b87111
Docs claim: Update or close a work item: workitem(action="update")mcpdone ✓priority after=urgent
Docs claim: Plan a cycle (sprint) with start/end dates: cycle(action="create")mcpdone ✓{'id': '[id]', 'total_issues': None, 'cancelled_issues': None, 'completed_issues': None, 'started_issues': None, 'unstarted_issues': None, 'backlog_issues': None, 'tota
Docs claim: Break work into a module and assign items: module(action="create")mcpdone ✓{'id': '[id]', 'total_issues': None, 'cancelled_issues': None, 'completed_issues': None, 'started_issues': None, 'unstarted_issues': None, 'backlog_issues': None, 'crea
Docs claim: Create and edit a wiki page: page(action="create")mcpdone ✓{'id': '[id]', 'name': 'AD MCP page', 'description_stripped': None, 'description_html': '<p>mcp</p>', 'description_binary': None, 'description': None, 'created_at': '20
Docs claim: Create an initiative to roll up multiple projects: initiative(action="create")mcpdone ✓{'id': '[id]', 'name': 'AD MCP initiative', 'description': None, 'description_html': None, 'description_stripped': None, 'description_binary': None, 'start_date': None,
Docs claim: Create an epic and link child work items: see epics recipe (workitem_type resolve Epic → workitem create type_id)mcpdone ✓type={'id': '[id]', 'deleted_at': None, 'project_ids': None, 'created_at' epic={'id': '[id]', 'type_id': '[id]', 'created_at': '2026-10
Docs claim: Delete a work item: workitem(action="delete")mcpdone ✓delete ok=True; retrieve after: Error calling tool 'workitem': HTTP 404: Not Found: The requested resource does not exist.
Docs claim: Create a work item: POST /workspaces/{workspace_slug}/projects/{project_id}/work-items/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Update or close a work item: PATCH /workspaces/{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Delete a work item: DELETE /workspaces/{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Create a project: POST /workspaces/{workspace_slug}/projects/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Plan a cycle (sprint) with start/end dates: POST /workspaces/{workspace_slug}/projects/{project_id}/cycles/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Break work into a module and assign items: POST /workspaces/{workspace_slug}/projects/{project_id}/modules/; POST .../module-issues/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Create and edit a wiki page: POST /workspaces/{workspace_slug}/projects/{project_id}/pages/; POST /workspaces/{workspace_slug}/pages/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Create an epic and link child work items: POST /workspaces/{workspace_slug}/projects/{project_id}/epics/; .../epics/{epic_id}/issues/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Create an initiative to roll up multiple projects: POST /workspaces/{workspace_slug}/initiatives/apidone ✓Done in the core chain on this account (see the create/read/update/delete lines); docs at developers.plane.so
Docs claim: Create a project: plane-compose apply (projects-as-code)cliskippednot tried yet
Assign a background AI Agent to a work item: Create an agent at /{workspace}/ai-agents/create as the docs say, to assign to a work itembrowserfailedapp.plane.so/agentdrives-test-ebe971/ai-agents/create/ → in-app 404 "Oops! Something went wrong. Sorry, the page you are looking for cannot be found"; Plane AI sidebar shows Skills, Usage, Analytics, Memory but no Agents section (Business trial workspace). MCP tools/list has no agent tool; no API page for agents in developers.plane.so/llms.txt.
Docs claim: Assign a background AI Agent to a work item: work item @mention / agent run lifecycle per MCP docsmcpfailedtools/list (30 tools) has no agent or agent-run tool; server instructions mention none
Ask Plane AI (Pi Chat) a question about workspace status: Activate Plane AI (in-app OAuth to pi.plane.so), ask how many work items the default project hasbrowserdone ✓Pi answered "The project AgentDrives Test has 7 work items." using PQL; API GET work-items total_count=7 confirms
Register a webhook for workspace events: POST v2 webhooks (our own URL, inactive), GET, DELETE, GETapidone ✓201 {"create": 201, "get": 200, "delete": 204, "after": 404, "resp": "{'id': '[id]', 'name': 'AD hook', 'url': 'https://agent.agentdrives.com/bot', 'is_active': False, 'version': 'v2', 'co"}
Define a workflow with approval gates between states: POST v2 workflowsapiplan_gated402 {"type": "payment_required", "code": "payment_required", "detail": "The feature 'FeatureFlag.MULTIPLE_WORKFLOWS' is not enabled for this workspace."}
View audit logs (API-enabled): GET v2 audit-logsapiplan_gated402 "{'type': 'payment_required', 'code': 'payment_required', 'detail': \"The feature 'FeatureFlag.WORKSPACE_AUDIT_LOG' is not enabled for this workspace.\"}"
Define a workflow with approval gates: PATCH project features workflows=true, GET v2 workflowsapipartial ✓200 "{'data': [{'id': '[id]', 'name': 'Default Workflow', 'description': 'Default workflow for the project', 'is_active': True, 'is_default': True, 'work_item_type_ids': [],"
Switch layouts and save a view: POST v2 project view with display_filters layout=kanban, GET backapidone ✓201 {"get": 200, "df": "{'layout': 'kanban', 'group_by': 'state'}"}
Export work items / analytics data: Settings > Exports > Export (All projects, CSV)browserdone ✓Previous exports table shows an inbox, 15th October 2026 07:22AM, CSV, Completed, Download
View real-time dashboard of workload, velocity, burndown: Dashboards > Add dashboard (name + project) in the browserbrowserpartial ✓Dashboard "AD workload" created at /dashboards/dd71e6de-…; page shows Data source, Add widget; no widget added (no burndown viewed)
Import projects/issues from CSV: Settings > Imports > CSV: select project, upload 2-row CSV (Name,Priority), Import CSVbrowserfailedMigrations table: AD drive project AD994, Status "Error", start/end 07:25 AM; search for "imported" returns no work items
Connect GitHub/GitLab: Connect integrationbrowserskippedSettings > Integrations offers it; needs our own GitHub/Slack workspace account and an OAuth grant to it, which this drive does not have (no sso kit for this drive)
Connect Slack: Connect integrationbrowserskippedSettings > Integrations offers it; needs our own GitHub/Slack workspace account and an OAuth grant to it, which this drive does not have (no sso kit for this drive)
Define projects as YAML and deploy via Plane Compose: Install plane-compose CLI and apply a YAML projectcliskippedplane.so/plane-compose is a script-rendered page (no install text in the HTML fetched); the CLI was not installed in this drive
Docs claim: Create a project: plane-compose apply (projects-as-code)cliskippednot run in this drive (see line)
Branding, SSO/SAML/OIDC, security policy: docs checknonedonedocs.plane.so/authentication/sso.md documents SSO; workspace settings show "Identity" and "Workspace Governance" sections (seen in the settings sidebar)
Generate a personal access token or OAuth app credential: docs check + UInonedoneDone in this drive: Profile > Personal Access Tokens (expiry required). Workspace settings also list Developers > Access Tokens
Plane Marketplace: docs checknonedonellms.txt: "[Integrations](https://plane.so/marketplace): Connect with GitHub, GitLab, and Slack"; settings sidebar lists Integrations
Self-hosted via Prime CLI: docs checknonedonedevelopers.plane.so/self-hosting/overview, methods/docker-compose, kubernetes, airgapped-edition (llms.txt); not installed: no Docker in this sandbox
Native iOS/Android/Desktop apps: docs checknonedonellms.txt Downloads: App Store id6657986465, Play Store com.plane.so, plane.so/download
Scoped API key headless: Create a scoped key via API/CLIapiblockeddevelopers.plane.so/api-reference/v2/authentication: keys are made in Profile Settings > Personal Access Tokens (UI); "there is no way to mint a read-only key"; no token endpoint in v1/v2 reference or MCP tools. OAuth apps are the scoped route (needs an app registration in the UI).
Pay probes: 402 challenges, well-known, registries, pricing.jsonapidone ✓pay_probe.json: no 402 challenge on plane.so/api/x402./mpp. (agents.plane.so 200/405, no challenge); no /.well-known/ucp; OpenAPI has no x-payment-info; registries empty. pay_tx.json: nothing paid (no 402 asking USDC). Unauthenticated API call → 401, no WWW-Authenticate Payment. plane.so/pricing.json lists Free/Pro/Business per seat USD monthly+annual. Workspace started on a 14-day Business trial with no card asked.
Walk to the last click: Settings > Billing and plans: Start subscription (Business monthly, current trial plan); Add payment methodbrowserdone ✓Dialog "Start your Business subscription? This ends your trial now and starts billing for Business today. If you don't have a card on file, you'll finish this on the payment page." Price per seat $15.00 / month; buttons Keep trial / "Start subscription and pay" (not clicked: it ends the trial and starts billing). Add payment method opens billing.stripe.com/p/session (Stripe customer portal), which robots.txt disallows for all user agents, so our agent did not open it. Pro ($8) is offered only as "Switch to Pro trial". Billing page: "Your workspace will downgrade automatically to Free if you don't upgrade to a paid plan at the end of 14 days"; no card on file; next invoice shown as $30.00 Oct 29, 2026.
Sign upnoneskippedNo keyless route: unauthenticated API call → 401; llms.txt: credential needs a free workspace
Sign upnoneskippedNo sign-up API in v1/v2 reference, MCP tools, or llms.txt
Sign upnoneskippedhttps://plane.so/auth.md 404; MCP AS metadata has no agent_auth block
Sign upbrowserskipped"Sign up with GitHub" seen on app.plane.so/sign-up; pw sso github: this drive has no GitHub account
Sign upbrowserskipped"Sign up with Google" seen on sign-up page; this drive has no Google account (drive.json sso empty)
Sign upbrowserskipped"Sign up with Single Sign-On" seen; needs a company IdP configured by a person
Sign upnoneskippedllms.txt: key from workspace settings; covered by our own account (email_code) in this drive
Sign upnoneskippedpay_probe registries: Plane not in the Stripe Projects catalog
Sign upnoneskippedNo CLI login; MCP AS metadata lists no device_authorization_endpoint
MCP OAuth sign-in: DCR register at https://mcp.plane.so/http/register → /http/authorize (PKCE S256, resource) → consent "Allow Access" in browser → /http/token → MCP callsmcpdone ✓Client registered (DCR, no CIMD advertised); consent page "Application Access Request" at mcp.plane.so/http/consent; token scope "read write", expires_in 36000; workspace retrieve → connected_via "oauth"; workitem create [id] then delete ok
Sign upbrowserskippedSign-up page offers email → code only; a password can be set on the profile step (we set one); the same account as email_code
Sign upnoneskippedNot offered: the email sends a 6-digit code, not a link
Sign upnoneskippedNo Sign in with AgentID on the sign-up page; door_probe registries: not listed
Sign upnoneskippedNo claimable/unclaimed resource route in docs or llms.txt
Sign upnoneskippedpay_tx.json: no 402 on Plane endpoints; nothing paid
Revoke API key: Profile > Personal Access Tokens > row menu > Delete > confirmbrowserdone ✓"The token has been successfully deleted"; GET /api/v1/users/me/ with it → 403 "Given API token is not valid"
Cancel trial: Workspace delete asked "Cancel your trial first"; clicked Cancel trialbrowserdone ✓Toast "Trial canceled. You can now delete the workspace."; billing page now "Free | Active | $0 for up to 12 seats", Business shows "Free trial used". Also in Billing > Plan actions > Cancel trial.
Delete workspace: Settings > General > Delete (type name + "delete my workspace") after cancelling the trialbrowserdone ✓Redirected to /create-workspace/; data gone with the workspace
Delete account: Profile > General > Deactivate account > Confirm, then try to sign in againbrowserpartial ✓Deactivate dialog: "Once deactivated, you can't be assigned work items and be billed for your workspace. To reactivate your account, you will need an invite to a workspace at this email address." After Confirm: signed out. Signing in again with the email code (mail 07:37) was accepted and opened /onboarding/ "Create your profile" with the name AgentDrives Test: the login still works.
Delete account (second try): Re-onboard (forced), create temp workspace to reach Profile settings, Deactivate again; then sign in to clean the temp workspacebrowserpartial ✓Profile settings are unreachable until onboarding creates a workspace. Signing in again by email code reactivated the account and restarted onboarding at "Create your workspace"; the temp workspace was no longer listed, so it could not be opened to delete.

Also in Project management.