| Tool | What it does | Kind |
|---|---|---|
get_access | Who reaches a project or an area | Read · idempotent · no outside service |
get_task_access | Who can see this task | Read · idempotent · no outside service |
list_share_links | List your public links | Read · idempotent · no outside service |
list_shared_targets | What is shared with you | Read · idempotent · no outside service |
list_workspace_guests | The guests of a workspace | Read · idempotent · no outside service |
accept_access_invite | Accept an invitation to a project or an area | Write · idempotent · no outside service |
accept_invite | Accept an invitation | Write · idempotent · no outside service |
create_share_link | Publish a public link | Write · no outside service |
grant_access | Give someone access, by handle or by email | Write · no outside service |
remove_collaborator | Stop sharing with someone | Write · destructive · idempotent · no outside service |
revoke_access | Take someone’s access away | Write · destructive · idempotent · no outside service |
revoke_access_invite | Cancel a pending invitation | Write · destructive · idempotent · no outside service |
revoke_invite | Cancel a pending invitation | Write · destructive · idempotent · no outside service |
revoke_share_link | Take a public link down | Write · destructive · idempotent · no outside service |
set_access_role | Change someone’s level | Write · idempotent · no outside service |
set_collaborator_role | Change a collaborator’s role | Write · idempotent · no outside service |
set_workspace_access | Open or close the target to everyone in its workspace | Write · idempotent · no outside service |
share_task | Share a task with someone | Write · no outside service |
get_access
Who reaches a project or an area. The owner, everyone granted on it with their level, the workspace-wide row, whether a public link is on, how many tasks it holds, and your own role. Pending invitations are listed to those who may manage it (they carry a link that grants access) and never with their link.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/access/{targetKind}/{targetId} |
| CLI | doers access get |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | getAccess |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
access | object | ||
access.role | string | reader, commenter, editor, owner | Yours. |
access.canManage | boolean | The owner, or an owner or admin of the target’s workspace, may change who reaches it. | |
access.owner | object | ||
access.owner.id | string | ||
access.owner.username | string | null | ||
access.owner.name | string | null | ||
access.owner.email | string | null | ||
access.owner.image | string | null | ||
access.owner.membershipId | string | null | The row to patch or delete. null for the owner, who has no membership. | |
access.owner.role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.people | object[] | ||
access.people[].id | string | ||
access.people[].username | string | null | ||
access.people[].name | string | null | ||
access.people[].email | string | null | ||
access.people[].image | string | null | ||
access.people[].accessId | string | The grant to patch or delete. | |
access.people[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.people[].isGuest | boolean | Not seated in the target’s workspace: reaches this one thing, at Can comment at most. | |
access.invites | object[] | Pending, listed to those who may manage; never with a link. | |
access.invites[].id | string | ||
access.invites[].email | string | ||
access.invites[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.invites[].invitePath | string | Where to send them. Carries the token, so treat it as one. | |
access.invites[].createdAt | number | Epoch milliseconds. | |
access.workspace | object | ||
access.workspace.id | string | ||
access.workspace.name | string | ||
access.workspace.access | string | none, view, edit | What everyone in the target’s workspace may do with it: nothing, read, or edit. |
access.workspace.plan | string | free, pro, team | The workspace owner’s plan; Pro never sees the word workspace. |
access.link | object | null | The public link, when one is on; never its address. | |
access.link.id | string | ||
access.link.targetKind | string | task, project, area | What the link points at. |
access.link.targetId | string | ||
access.link.label | string | The name of what is shared, as it stands today. | |
access.link.email | string | null | ||
access.link.createdAt | number | Epoch milliseconds. | |
access.taskCount | integer | 0 to 9007199254740991 |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_access",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "You are reader. 1 with access · everyone in Acme: none."
}
],
"structuredContent": {
"access": {
"role": "reader",
"canManage": true,
"owner": {
"id": "4c102969-7ee3-4871-8d3a-14a2add817c4",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
},
"people": [
{
"id": "c9022680-f888-474e-8b22-74758755bfa0",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79",
"role": "reader",
"isGuest": true
}
],
"invites": [
{
"id": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee",
"email": "ada@acme.example",
"role": "reader",
"invitePath": "Acme/Weekly review",
"createdAt": 1790069400000
}
],
"workspace": {
"id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
"name": "Acme",
"access": "none",
"plan": "free"
},
"link": {
"id": "b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69",
"targetKind": "task",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"label": "Acme",
"email": "ada@acme.example",
"createdAt": 1790069400000
},
"taskCount": 3
}
}
}
}
doers access get --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb
get_task_access
Who can see this task. The owner, everyone it is shared with, and your own role. Pending invitations are included only for the owner: they carry a link that grants access, so they are not something a reader may enumerate.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/tasks/{taskId}/access |
| CLI | doers collaborators get-task-access |
| Touches | taskInvites, taskMembers, user |
| Operation | getTaskAccess |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
canManage | boolean | ||
owner | object | ||
owner.id | string | ||
owner.username | string | null | ||
owner.name | string | null | ||
owner.email | string | null | ||
owner.image | string | null | ||
owner.membershipId | string | null | The row to patch or delete. null for the owner, who has no membership. | |
owner.role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
members | object[] | ||
members[].id | string | ||
members[].username | string | null | ||
members[].name | string | null | ||
members[].email | string | null | ||
members[].image | string | null | ||
members[].membershipId | string | null | The row to patch or delete. null for the owner, who has no membership. | |
members[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
invites | object[] | ||
invites[].id | string | ||
invites[].email | string | ||
invites[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
invites[].invitePath | string | Where to send them. Carries the token, so treat it as one. | |
invites[].createdAt | number | Epoch milliseconds. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_task_access",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "You are reader. 1 collaborator(s), 1 pending."
}
],
"structuredContent": {
"role": "reader",
"canManage": true,
"owner": {
"id": "4c102969-7ee3-4871-8d3a-14a2add817c4",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
},
"members": [
{
"id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
}
],
"invites": [
{
"id": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee",
"email": "ada@acme.example",
"role": "reader",
"invitePath": "Acme/Weekly review",
"createdAt": 1790069400000
}
]
}
}
}
doers collaborators get-task-access --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c
list_share_links
List your public links. Everything you have published a link to, newest first, with the name of what it points at. The link itself is not here and cannot be: only its hash is stored.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/share-links |
| CLI | doers links list-share |
| Touches | areas, projects, shares, tasks |
| Operation | listShareLinks |
Input
This tool takes no arguments.Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
links | object[] | ||
links[].id | string | ||
links[].targetKind | string | task, project, area | What the link points at. |
links[].targetId | string | ||
links[].label | string | The name of what is shared, as it stands today. | |
links[].email | string | null | ||
links[].createdAt | number | Epoch milliseconds. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_share_links",
"arguments": {}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- [b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69] Acme"
}
],
"structuredContent": {
"links": [
{
"id": "b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69",
"targetKind": "task",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"label": "Acme",
"email": "ada@acme.example",
"createdAt": 1790069400000
}
]
}
}
}
doers links list-share
list_shared_targets
What is shared with you. Every project or area you reach and do not own: through a grant, or through the workspace-wide row in a workspace you sit in. Each with your level, whose it is, and where it lives: the “Shared with you” section of the sidebar.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/access/shared |
| CLI | doers access list-shared-targets |
| Touches | areas, projects, targetAccess, tasks, user, workspaceMembers, workspaces |
| Operation | listSharedTargets |
Input
This tool takes no arguments.Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
targets | object[] | ||
targets[].targetId | string | ||
targets[].name | string | ||
targets[].role | string | reader, commenter, editor, owner | Yours on it. |
targets[].sharer | object | Whose it is. | |
targets[].sharer.id | string | ||
targets[].sharer.username | string | null | ||
targets[].sharer.name | string | null | ||
targets[].sharer.email | string | null | ||
targets[].sharer.image | string | null | ||
targets[].workspace | object | Where it lives. | |
targets[].workspace.id | string | ||
targets[].workspace.name | string | ||
targets[].targetKind | string | project, area | |
targets[].project | object (optional) | ||
targets[].project.id | string | ||
targets[].project.name | string | ||
targets[].project.areaId | string | null | ||
targets[].project.status | string | active, done, archived | |
targets[].project.deadline | string | null | ||
targets[].project.notes | string | ||
targets[].project.order | number | Manual position. Fractional values are valid; lower sorts first. | |
targets[].project.accessRole | string (optional) | owner, editor, commenter, reader | Your effective role on this project. |
targets[].area | object (optional) | ||
targets[].area.id | string | ||
targets[].area.name | string | ||
targets[].area.hue | integer | null | 0 to 360 | |
targets[].area.icon | string | null | Phosphor icon name. | |
targets[].area.notes | string | ||
targets[].area.archived | boolean | ||
targets[].area.order | number | Manual position. Fractional values are valid; lower sorts first. | |
targets[].area.accessRole | string (optional) | owner, editor, commenter, reader | Your effective role on this area. |
tasks | object[] | The open tasks of those targets, in their order, up to one page; the paginated list is listTasks with sharedWithMe. Here so a page draws in one read. | |
tasks[].id | string | ||
tasks[].title | string | ||
tasks[].notes | string | ||
tasks[].status | string | open, done, archived | |
tasks[].priority | integer | -9007199254740991 to 9007199254740991 | |
tasks[].when | object | How the task is scheduled (distinct from its deadline). | |
tasks[].when.kind | string | today, anytime, someday, date | |
tasks[].when.date | string (optional) | ||
tasks[].when.hasTime | boolean (optional) | ||
tasks[].when.time | string | null (optional) | ||
tasks[].deadline | string | null | Due date YYYY-MM-DD, or null. | |
tasks[].projectId | string | null | ||
tasks[].areaId | string | null | ||
tasks[].headingId | string | null | Heading grouping the task, or null if it sits above them all. | |
tasks[].tags | string[] | ||
tasks[].checklist | object[] | ||
tasks[].checklist[].id | string | ||
tasks[].checklist[].label | string | ||
tasks[].checklist[].done | boolean | ||
tasks[].completedAt | number | null | ||
tasks[].durationMin | number | null | ||
tasks[].kind | string | task, event | |
tasks[].repeat | object | null | ||
tasks[].repeat.every | integer | 1 to 365 | The multiplier: 2 × week. |
tasks[].repeat.unit | string | day, week, month, year | |
tasks[].repeat.mode | string | calendar, after | calendar: the next one starts from the scheduled date. after: from ticking. |
tasks[].repeat.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
tasks[].visibility | string | public, anonymized, private | Who sees this task on shared and social surfaces: public shows title and project, anonymized shows only the area, private shows nothing. New tasks default to private. |
tasks[].order | number | Manual position. Fractional values are valid; lower sorts first. | |
tasks[].notePath | string | null | 0 to 1024 characters | |
tasks[].conversationPath | string | null | 0 to 1024 characters | |
tasks[].assigneeId | string | null | Who it is assigned to: one person who reaches the task, or nobody. | |
tasks[].assignee | object | null | The same person, as the row draws them. | |
tasks[].assignee.id | string | ||
tasks[].assignee.username | string | null | ||
tasks[].assignee.name | string | null | ||
tasks[].assignee.email | string | null | ||
tasks[].assignee.image | string | null | ||
tasks[].accessRole | string (optional) | owner, editor, commenter, reader | Your effective role on this task. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_shared_targets",
"arguments": {}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- [project 34a04005-bcaf-406e-8c99-0bd9637d9fdb] Acme · reader"
}
],
"structuredContent": {
"targets": [
{
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"name": "Acme",
"role": "reader",
"sharer": {
"id": "e15c6683-d07b-4875-8aa2-028f54d03177",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png"
},
"workspace": {
"id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
"name": "Acme"
},
"targetKind": "project",
"project": {
"id": "244210e4-8437-4655-8980-a70249a99369",
"name": "Acme",
"areaId": "4a91ee5f-0106-42b3-8c11-c168352f0abf",
"status": "active",
"deadline": "2026-09-22",
"notes": "Notes for the Acme launch.",
"order": 0,
"accessRole": "owner"
}
}
],
"tasks": [
{
"id": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"notes": "Notes for the Acme launch.",
"status": "open",
"priority": 2,
"when": {
"kind": "today"
},
"deadline": "2026-09-22",
"projectId": "244210e4-8437-4655-8980-a70249a99369",
"areaId": "4a91ee5f-0106-42b3-8c11-c168352f0abf",
"headingId": "5e60ff5a-c0ec-4f50-8aa9-4ac8a754bc0e",
"tags": ["acme"],
"checklist": [
{
"id": "6da624db-a523-4ba1-8390-1c904a78ea41",
"label": "Acme",
"done": true
}
],
"completedAt": 1790069400000,
"durationMin": 30,
"kind": "task",
"repeat": {
"every": 3,
"unit": "day",
"mode": "calendar"
},
"visibility": "public",
"order": 0,
"notePath": "Acme/Weekly review",
"conversationPath": "Acme/Weekly review",
"assigneeId": "53a9d65d-3627-4bc7-8170-af8d57e84d02",
"assignee": {
"id": "53a9d65d-3627-4bc7-8170-af8d57e84d02",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png"
},
"accessRole": "owner"
}
]
}
}
}
doers access list-shared-targets
list_workspace_guests
The guests of a workspace. Everyone from outside the workspace who reaches something in it, with what they reach. Owner and admins only: a guest takes no seat and is not on the members page.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/workspaces/{workspaceId}/guests |
| CLI | doers access list-workspace-guests |
| Touches | areas, projects, targetAccess, tasks, user, workspaceMembers, workspaces |
| Operation | listWorkspaceGuests |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
workspaceId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
guests | object[] | ||
guests[].id | string | ||
guests[].username | string | null | ||
guests[].name | string | null | ||
guests[].email | string | null | ||
guests[].image | string | null | ||
guests[].reaches | object[] | ||
guests[].reaches[].targetKind | string | project, area | What is shared: a project, or an area and every project in it. |
guests[].reaches[].targetId | string | ||
guests[].reaches[].name | string | ||
guests[].reaches[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_workspace_guests",
"arguments": {
"workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- @ada · 1 thing(s)"
}
],
"structuredContent": {
"guests": [
{
"id": "84983c60-f7da-4dc1-8b86-98621f802c0d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"reaches": [
{
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"name": "Acme",
"role": "reader"
}
]
}
]
}
}
}
doers access list-workspace-guests --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328
accept_access_invite
Accept an invitation to a project or an area. Accepts a link, but only for the account carrying the address it was sent to; forwarded, it grants nothing. Outside the target’s workspace, the level is Can comment at most.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/access-invites/accept |
| CLI | doers access accept-access-invite |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | acceptAccessInvite |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
token | string | yes | 1 to 200 characters | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
targetKind | string | project, area | What is shared: a project, or an area and every project in it. |
targetId | string | ||
role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "accept_access_invite",
"arguments": {
"token": "acme-example-token"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: you can reader on project 34a04005-bcaf-406e-8c99-0bd9637d9fdb."
}
],
"structuredContent": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"role": "reader"
}
}
}
doers access accept-access-invite acme-example-token
accept_invite
Accept an invitation. Accepts a link, but only for the account carrying the address it was sent to. An invitation forwarded to someone else grants them nothing.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/invites/accept |
| CLI | doers collaborators accept-invite |
| Touches | taskInvites, taskMembers, user |
| Operation | acceptInvite |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
token | string | yes | 1 to 200 characters | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
taskId | string | ||
role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "accept_invite",
"arguments": {
"token": "acme-example-token"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: you are reader on 0ebb429f-a86d-481c-8630-fac53db1c91c."
}
],
"structuredContent": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"role": "reader"
}
}
}
doers collaborators accept-invite acme-example-token
create_share_link
Publish a public link. Returns the link inurl, once. Publishing the same target again returns a fresh link and retires the previous one: a link that has been sent somewhere it should not have been is replaced, not reused.
| Kind | Write · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/share-links |
| CLI | doers links create-share |
| Touches | areas, projects, shares, tasks |
| Operation | createShareLink |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind | string | yes | task, project, area | What the link points at. | |
targetId | string | yes | UUID | Identifier of a row. | |
email | string | null | no | email address, 0 to 254 characters | Recorded when the link was sent to one person. Not enforced on opening. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
link | object | ||
link.id | string | ||
link.targetKind | string | task, project, area | What the link points at. |
link.targetId | string | ||
link.label | string | The name of what is shared, as it stands today. | |
link.email | string | null | ||
link.createdAt | number | Epoch milliseconds. | |
url | string | The public address. Shown once and never again. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_share_link",
"arguments": {
"targetKind": "task",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"email": "ada@acme.example"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: published. Send this now: https://acme.example/brief"
}
],
"structuredContent": {
"link": {
"id": "b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69",
"targetKind": "task",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"label": "Acme",
"email": "ada@acme.example",
"createdAt": 1790069400000
},
"url": "https://acme.example/brief"
}
}
}
doers links create-share --target-kind task --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --email ada@acme.example
grant_access
Give someone access, by handle or by email.target is a handle or an email address. A matching account is added at once; an address that matches nobody produces an invitation link to send them. Granting again changes the level. Someone outside the target’s workspace is a guest: the level is capped at Can comment, and clampedToGuest says when it was.
| Kind | Write · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/access/{targetKind}/{targetId} |
| CLI | doers access grant |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | grantAccess |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. | |
target | string | yes | 1 to 254 characters | No description in the registry. | |
role | string | yes | reader, commenter, editor | No description in the registry. |
Output
Output fields
Output fields
Returns
object.Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "grant_access",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"target": "Notes for the Acme launch.",
"role": "reader"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: ada can reader."
}
],
"structuredContent": {
"kind": "member",
"member": {
"id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79",
"role": "reader",
"isGuest": true
},
"clampedToGuest": true
}
}
}
doers access grant --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --target "Notes for the Acme launch." --role reader
remove_collaborator
Stop sharing with someone. Owner only. Access stops on their next request.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | DELETE https://api.doers.sh/v2/tasks/{taskId}/access/{membershipId} |
| CLI | doers collaborators remove |
| Touches | taskInvites, taskMembers, user |
| Operation | removeCollaborator |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId (path) | string | yes | UUID | Identifier of a row. | |
membershipId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
removed | boolean |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "remove_collaborator",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: no longer shared."
}
],
"structuredContent": {
"removed": true
}
}
}
doers collaborators remove --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --membership-id bf5cf59e-3566-4225-8268-c604cbf8df8c
revoke_access
Take someone’s access away. Access stops on their next request.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | DELETE https://api.doers.sh/v2/access/{targetKind}/{targetId}/people/{accessId} |
| CLI | doers access revoke |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | revokeAccess |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. | |
accessId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
revoked | boolean |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_access",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: no longer shared."
}
],
"structuredContent": {
"revoked": true
}
}
}
doers access revoke --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --access-id a0561fd6-49cd-46ba-8784-055f051bad79
revoke_access_invite
Cancel a pending invitation. The link stops working immediately.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/access/{targetKind}/{targetId}/invites/{inviteId}/revoke |
| CLI | doers access revoke-access-invite |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | revokeAccessInvite |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. | |
inviteId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
revoked | boolean |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_access_invite",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"inviteId": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: invitation cancelled."
}
],
"structuredContent": {
"revoked": true
}
}
}
doers access revoke-access-invite --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --invite-id 5014f9af-3a68-4fdd-84a7-75c1c4c532ee
revoke_invite
Cancel a pending invitation. Owner only. The link stops working immediately.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/tasks/{taskId}/invites/{inviteId}/revoke |
| CLI | doers collaborators revoke-invite |
| Touches | taskInvites, taskMembers, user |
| Operation | revokeInvite |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId (path) | string | yes | UUID | Identifier of a row. | |
inviteId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
revoked | boolean |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_invite",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"inviteId": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: invitation cancelled."
}
],
"structuredContent": {
"revoked": true
}
}
}
doers collaborators revoke-invite --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --invite-id 5014f9af-3a68-4fdd-84a7-75c1c4c532ee
revoke_share_link
Take a public link down. The address stops resolving immediately. Anyone holding it sees nothing.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/share-links/{linkId}/revoke |
| CLI | doers links revoke-share |
| Touches | areas, projects, shares, tasks |
| Operation | revokeShareLink |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
linkId (path) | string | yes | UUID | Identifier of a row. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
revoked | boolean |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_share_link",
"arguments": {
"linkId": "b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: link taken down."
}
],
"structuredContent": {
"revoked": true
}
}
}
doers links revoke-share b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69
set_access_role
Change someone’s level. A guest stays at Can comment at most. The owner’s level is not a grant.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PATCH https://api.doers.sh/v2/access/{targetKind}/{targetId}/people/{accessId} |
| CLI | doers access set-access-role |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | setAccessRole |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. | |
accessId (path) | string | yes | UUID | Identifier of a row. | |
role | string | yes | reader, commenter, editor | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
member | object | ||
member.id | string | ||
member.username | string | null | ||
member.name | string | null | ||
member.email | string | null | ||
member.image | string | null | ||
member.accessId | string | The grant to patch or delete. | |
member.role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
member.isGuest | boolean | Not seated in the target’s workspace: reaches this one thing, at Can comment at most. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_access_role",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79",
"role": "reader"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: now reader."
}
],
"structuredContent": {
"member": {
"id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79",
"role": "reader",
"isGuest": true
}
}
}
}
doers access set-access-role --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --access-id a0561fd6-49cd-46ba-8784-055f051bad79 --role reader
set_collaborator_role
Change a collaborator’s role. Owner only. The owner’s own role cannot be changed; it is not a membership.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PATCH https://api.doers.sh/v2/tasks/{taskId}/access/{membershipId} |
| CLI | doers collaborators set-collaborator-role |
| Touches | taskInvites, taskMembers, user |
| Operation | setCollaboratorRole |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId (path) | string | yes | UUID | Identifier of a row. | |
membershipId (path) | string | yes | UUID | Identifier of a row. | |
role | string | yes | reader, commenter, editor | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
member | object | ||
member.id | string | ||
member.username | string | null | ||
member.name | string | null | ||
member.email | string | null | ||
member.image | string | null | ||
member.membershipId | string | null | The row to patch or delete. null for the owner, who has no membership. | |
member.role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_collaborator_role",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: now reader."
}
],
"structuredContent": {
"member": {
"id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
}
}
}
}
doers collaborators set-collaborator-role --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --membership-id bf5cf59e-3566-4225-8268-c604cbf8df8c --role reader
set_workspace_access
Open or close the target to everyone in its workspace. The “Everyone in <workspace>” row:view lets whoever sits in the workspace read it, edit lets them edit, none closes it to all but the people granted. Never reaches anyone outside the workspace.
| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/access/{targetKind}/{targetId}/workspace |
| CLI | doers access set-workspace |
| Touches | areas, projects, shares, targetAccess, targetAccessInvites, tasks, user, workspaces |
| Operation | setWorkspaceAccess |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
targetKind (path) | string | yes | project, area | What is shared: a project, or an area and every project in it. | |
targetId (path) | string | yes | UUID | Identifier of a row. | |
access | string | yes | none, view, edit | What everyone in the target’s workspace may do with it: nothing, read, or edit. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
access | object | ||
access.role | string | reader, commenter, editor, owner | Yours. |
access.canManage | boolean | The owner, or an owner or admin of the target’s workspace, may change who reaches it. | |
access.owner | object | ||
access.owner.id | string | ||
access.owner.username | string | null | ||
access.owner.name | string | null | ||
access.owner.email | string | null | ||
access.owner.image | string | null | ||
access.owner.membershipId | string | null | The row to patch or delete. null for the owner, who has no membership. | |
access.owner.role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.people | object[] | ||
access.people[].id | string | ||
access.people[].username | string | null | ||
access.people[].name | string | null | ||
access.people[].email | string | null | ||
access.people[].image | string | null | ||
access.people[].accessId | string | The grant to patch or delete. | |
access.people[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.people[].isGuest | boolean | Not seated in the target’s workspace: reaches this one thing, at Can comment at most. | |
access.invites | object[] | Pending, listed to those who may manage; never with a link. | |
access.invites[].id | string | ||
access.invites[].email | string | ||
access.invites[].role | string | reader, commenter, editor, owner | Ascending. owner is not grantable: it is what owning the task means. |
access.invites[].invitePath | string | Where to send them. Carries the token, so treat it as one. | |
access.invites[].createdAt | number | Epoch milliseconds. | |
access.workspace | object | ||
access.workspace.id | string | ||
access.workspace.name | string | ||
access.workspace.access | string | none, view, edit | What everyone in the target’s workspace may do with it: nothing, read, or edit. |
access.workspace.plan | string | free, pro, team | The workspace owner’s plan; Pro never sees the word workspace. |
access.link | object | null | The public link, when one is on; never its address. | |
access.link.id | string | ||
access.link.targetKind | string | task, project, area | What the link points at. |
access.link.targetId | string | ||
access.link.label | string | The name of what is shared, as it stands today. | |
access.link.email | string | null | ||
access.link.createdAt | number | Epoch milliseconds. | |
access.taskCount | integer | 0 to 9007199254740991 |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_workspace_access",
"arguments": {
"targetKind": "project",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"access": "none"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: everyone in Acme: none."
}
],
"structuredContent": {
"access": {
"role": "reader",
"canManage": true,
"owner": {
"id": "4c102969-7ee3-4871-8d3a-14a2add817c4",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
},
"people": [
{
"id": "c9022680-f888-474e-8b22-74758755bfa0",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"accessId": "a0561fd6-49cd-46ba-8784-055f051bad79",
"role": "reader",
"isGuest": true
}
],
"invites": [
{
"id": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee",
"email": "ada@acme.example",
"role": "reader",
"invitePath": "Acme/Weekly review",
"createdAt": 1790069400000
}
],
"workspace": {
"id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
"name": "Acme",
"access": "none",
"plan": "free"
},
"link": {
"id": "b1b1bdb4-80c6-4d07-8300-d9bff7d9cb69",
"targetKind": "task",
"targetId": "34a04005-bcaf-406e-8c99-0bd9637d9fdb",
"label": "Acme",
"email": "ada@acme.example",
"createdAt": 1790069400000
},
"taskCount": 3
}
}
}
}
doers access set-workspace --target-kind project --target-id 34a04005-bcaf-406e-8c99-0bd9637d9fdb --access none
share_task
Share a task with someone.target is a username or an email address. A matching account is added immediately; an email that matches nobody produces an invitation link to send them. Sharing again with the same person changes their role rather than adding them twice.
| Kind | Write · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/tasks/{taskId}/access |
| CLI | doers collaborators share-task |
| Touches | taskInvites, taskMembers, user |
| Operation | shareTask |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId (path) | string | yes | UUID | Identifier of a row. | |
target | string | yes | 1 to 254 characters | No description in the registry. | |
role | string | yes | reader, commenter, editor | No description in the registry. |
Output
Output fields
Output fields
Returns
object.Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "share_task",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"target": "Notes for the Acme launch.",
"role": "reader"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: shared with ada."
}
],
"structuredContent": {
"kind": "member",
"member": {
"id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
"username": "ada",
"name": "Acme",
"email": "ada@acme.example",
"image": "https://acme.example/ada.png",
"membershipId": "bf5cf59e-3566-4225-8268-c604cbf8df8c",
"role": "reader"
}
}
}
}
doers collaborators share-task --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --target "Notes for the Acme launch." --role reader