This guide shows how to let an AI assistant work in your TaskOH tasks. Every path below uses one thing: a personal access token you create on the Integrations page.
Which section do I need?
- Claude Code (terminal) → §4
- Claude Desktop app → §5
- ChatGPT (Custom GPT) → §6
- claude.ai website, Claude Desktop Connectors menu, or ChatGPT Apps/Connectors → not supported yet, see §11
- Writing your own script or app → §7
1. What it is
Your AI assistant can read, create, update, comment on and delete your tasks. It acts as you: it sees the same projects, holds the same role in each, and may do exactly what you may do in the web app. Some of its writes are recorded in the activity log — task created, status / scope / cost changes, comments and deletions (see §10 for the exact list; plain field edits such as title, assignee or labels are not logged) — in the task's Activity tab and the dashboard's Recent activity panel, with a small via API chip, so your team can tell assistant work from your own clicks.
What it is not, today:
- No OAuth sign-in. Assistants connect with a personal access token you paste into their settings (see §11 for what that rules out).
- No access to approvals, estimates, attachments or team management, and no adding or removing project members, through the assistant tools. Those stay in the web app (the assistant can still read a project's member list with
get_context).
2. Before you start
A token has no permissions of its own. It acts as you, with your role in every project you belong to. Your role is per project — check it under the project's Members tab. Being the workspace owner does not by itself give you access to a project you were not added to.
| Your role in a project | What the assistant can do there |
|---|---|
Admin (admin) | Everything: read all tasks, create, update, comment, delete, set labels, scope and billing fields, change client visibility. |
Project manager (project_manager) — the usual team-member role | Same as above. |
Guest (guest) — the client role | Read only the tasks marked client-visible; create requests exactly like the portal's request form (always client-visible, start in the inbox without priority or due date, the team is notified; not possible when the team has switched client requests off for the project), optionally naming a project member as assignee; comment. Cannot update or delete tasks (including re-assigning), and cannot set labels. Hours and fees are shown only when the team has switched on Show hours and fee to client for that task. Sees member names but not their e-mail addresses. |
Anyone can open Integrations and create tokens — owners, team members and clients alike. One token works in every workspace and project you can see; you cannot limit a token to a single project or to read-only use. Some actions are never available to a token, whatever your role: managing tokens, people, or billing, and deleting projects (§10).
Clients: the portal has no Integrations link; use https://app.taskoh.app/integrations directly (§3).
3. Create a token
- Sign in at https://app.taskoh.app and open Integrations in the sidebar. If you use TaskOH through a client portal link (
app.taskoh.app/portal/…), the portal has no sidebar — go straight to https://app.taskoh.app/integrations after signing in.
Clients: you sign in with a link we e-mail you. The button in your invitation works once and expires in 3 days; after that, choose Email me a sign-in link on the sign-in page and open the link we send (valid 15 minutes). No password is needed. If you would rather have one, set it under Account once you are signed in, or use Forgot password? on the sign-in page.
- Click New token.
- Fill in Name — name it after the app or machine that will use it, for example
Claude Code on my laptop(up to 100 characters). - Choose Expires: 30 days, 90 days, 365 days (the default) or Never. Anything using an expired token stops working until you create a new one.
- Click Create token.
- The dialog changes to Copy your new token. Click Copy (it shows Copied), store the token in your password manager (you will paste it into the assistant in the next section), then click I've copied it. You cannot close this step with Escape or by clicking outside — copy first.
The token starts with toh_pat_ and is 72 characters long. You will not see it again: TaskOH stores only a hash and the last four characters. If you lose it, revoke it and create a new one.
Every time a token is created, TaskOH e-mails you (name, last four characters, expiry) so a token made from a hijacked browser session cannot stay hidden. You can hold at most 20 active tokens; revoke unused ones first if you hit the limit.
3.1 Find and revoke tokens later
The Personal access tokens list on the Integrations page shows each token as toh_pat_… plus its last four characters, with Created, Last used (or Never used) and Expires / Expired / No expiry. Expired tokens stay in the list until you revoke them. Last-used time updates at most once every five minutes.
To revoke: open the row's actions menu, choose Revoke…, confirm with Revoke. Anything using that token stops working immediately.
3.2 Naming advice
Create one token per assistant or machine (Claude Code on my laptop, ChatGPT team GPT, Reporting script). Then you can revoke a single one without touching the others, and the Last used column tells you which is still in use.
4. Connect Claude Code
Requires Claude Code 2.1.251 or newer. Run once in a terminal, replacing toh_pat_… with your token:
claude mcp add --transport http taskoh https://api.taskoh.app/mcp --header "Authorization: Bearer toh_pat_…" --scope user
--scope user makes TaskOH available in every project on this machine; omit it to register it for the current project only. The same command is on the Integrations page under Connect an assistant → Claude Code with a Copy button.
The command stores the token in Claude Code's user config file (~/.claude.json at the time of writing) and leaves it in your shell history. On a shared machine, delete that line from your shell's history file afterwards (~/.zsh_history on macOS, ~/.bash_history on most Linux shells), or paste the token into the config file by hand instead of typing it in the terminal.
Verify inside a Claude Code session with /mcp: taskoh is listed as connected with eight tools (get_context, get_my_tasks, search_tasks, get_task, create_task, update_task, add_comment, delete_task). Try "What's on my plate?" — Claude calls get_my_tasks.
Claude asks before running a tool that writes unless you choose Always allow — keep delete_task on ask (§9).
For a shared repository, commit a project-level .mcp.json that reads the token from an environment variable so the token never enters git:
{"mcpServers": {"taskoh": {"type": "http", "url": "https://api.taskoh.app/mcp", "headers": {"Authorization": "Bearer ${TASKOH_TOKEN}"}}}}
Then set TASKOH_TOKEN in your shell profile or a local .env that is git-ignored.
5. Connect Claude Desktop
Claude Desktop's built-in connector settings cannot hold a personal token (see §11), so use the mcp-remote bridge, which runs through Node.js.
- Make sure Node.js is installed: open a terminal (Terminal on macOS, PowerShell on Windows) and run
node --version. If it prints nothing or an error, install the LTS version from https://nodejs.org and reopen the terminal. - In Claude Desktop open Settings → Developer → Edit Config. This opens
claude_desktop_config.json. - Add the
taskohentry below, replacingtoh_pat_…with your token (if the file already has amcpServersobject, add the entry inside it). The same JSON is on the Integrations page under Connect an assistant → Claude Desktop.
{
"mcpServers": {
"taskoh": {
"command": "npx",
"args": [
"mcp-remote",
"https://api.taskoh.app/mcp",
"--header",
"Authorization:${AUTH_HEADER}",
"--transport",
"http-only"
],
"env": {
"AUTH_HEADER": "Bearer toh_pat_…"
}
}
}
}
- Save the file, then quit Claude Desktop completely (macOS: Cmd+Q; Windows: right-click the tray icon → Quit) and reopen it — closing the window is not enough, the config is only read at start. The first start downloads
mcp-remote, so give it a minute before assuming the connection failed. Thetaskohserver should then be listed among the available tools in a new chat.
Notes:
- Keep
Authorization:${AUTH_HEADER}exactly as written, with no space after the colon. The value is expanded fromenv, which avoids a Windows argument-quoting bug. --transport http-onlypins the Streamable HTTP transport TaskOH speaks. Without itmcp-remotemay try the legacy SSE transport, which TaskOH does not support.
6. Connect ChatGPT as a Custom GPT
Creating a GPT may require a paid ChatGPT plan; if you see no Create button, check your plan or ask your workspace admin.
- Explore GPTs → Create (or My GPTs → Create a GPT) → Configure tab → Create new action.
- Authentication → API Key, Auth Type: Bearer, paste
toh_pat_…→ Save. - Schema → Import from URL →
https://api.taskoh.app/openapi.json→ Import. Seven actions appear:
| Action | What it does | Asks for confirmation |
|---|---|---|
list_projects | Your projects with your role in each | No |
list_my_tasks | Your open tasks across projects | No |
list_project_tasks | Tasks of one project, with filters and paging | No |
get_task | One task | No |
create_task | Creates a task in a project | Yes |
update_task | Changes fields of a task | Yes |
add_comment | Adds a comment to a task | Yes |
Then set Privacy policy to https://taskoh.app/privacy.html and save the GPT as Only me or Anyone at your workspace with the link.
Test it: "List my open tasks" runs without confirmation. "Create a task in Acme Portal titled 'Fix Safari login'" asks you to confirm before writing.
The three writing actions are marked consequential, so ChatGPT asks before each one. There is no delete action in the Custom GPT path.
Everyone who uses the GPT acts as the person whose token is pasted into it, and TaskOH records their events under that person's name with the via API chip. Create the token yourself, from your own account, and give the GPT its own token so revoking it disconnects every user at once. Share it only with people you would let use your account.
7. For developers
Not a developer? Skip to §8.
Everything below uses the same token. The full tool and endpoint reference — argument schemas, result shapes, error texts, name-resolution rules — is in the API & MCP reference, also served as plain text at https://api.taskoh.app/llms.txt so you can hand it to an agent.
7.1 Claude API (MCP connector)
Messages API with beta header anthropic-beta: mcp-client-2025-11-20. Pass the raw token; the API adds the Bearer scheme itself:
{"mcp_servers": [{"type": "url", "url": "https://api.taskoh.app/mcp", "name": "taskoh", "authorization_token": "toh_pat_…"}],
"tools": [{"type": "mcp_toolset", "mcp_server_name": "taskoh"}]}
7.2 OpenAI Responses API
Headers are not stored; send them on every request:
{"tools": [{"type": "mcp", "server_label": "taskoh", "server_url": "https://api.taskoh.app/mcp",
"headers": {"Authorization": "Bearer toh_pat_…"}, "require_approval": "never"}]}
7.3 OpenAI Agents SDK (Python)
MCPServerStreamableHttp(params={"url": "https://api.taskoh.app/mcp", "headers": {"Authorization": f"Bearer {token}"}})
7.4 curl smoke test
Check the token before configuring a client:
curl -s https://api.taskoh.app/api/dashboard/my-tasks -H "Authorization: Bearer toh_pat_…"
Expected: {"success":true,"data":[…]} with your open tasks. To check the MCP server:
curl -s -X POST https://api.taskoh.app/mcp -H "Authorization: Bearer toh_pat_…" \
-H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Expected: a JSON-RPC result listing eight tools. Any HTTP client can also call the REST endpoints in https://api.taskoh.app/openapi.json; responses use the {"success": true, "data": …} envelope.
Scripts should send a descriptive User-Agent header (for example my-script/1.0); it is good practice and identifies your client in logs. Since 2026-09-07 the API host no longer rejects Python's built-in urllib default (Python-urllib/3.x). If you ever get a plain-text 403 error code: 1010, see §12.
8. What you can ask
The assistant resolves project, member and label names for you (exact match, case does not matter) and accepts me as the assignee. Examples, with the tool the assistant will use:
8.1 Read
| Ask | Tool |
|---|---|
| "What's on my plate?" | get_my_tasks |
| "Which projects can I see, and what's my role in each?" | get_context |
| "List the open high-priority bugs in Acme Portal." | search_tasks |
| "What's unassigned in Acme Portal?" | search_tasks with assignee: "unassigned" |
| "Summarize task 42 with its comments and history." | get_task with include: ["comments","subtasks","activity"] |
8.2 Create
| Ask | Tool |
|---|---|
| "Create a task in Acme Portal called 'Fix Safari login', high priority, due 2026-09-12, assigned to Maya." | create_task |
| "Add a subtask under task 42: 'Write a regression test'." | create_task with parent_task_id |
| "Log a bug in Acme Portal with the frontend label: images do not load on the pricing page." | create_task with type: "bug" and labels |
8.3 Update
| Ask | Tool |
|---|---|
| "Move task 42 to in review." | update_task |
| "Assign task 42 to me and add the frontend label." | update_task with assignee: "me", add_labels |
| "Mark task 42 out of scope and billable: 2 hours, 300 EUR." | update_task with scope, is_billable, required_minutes, fee_amount, fee_currency |
| "Make task 42 visible to the client." | update_task with client_visible: true |
8.4 Comment
| Ask | Tool |
|---|---|
| "Comment on task 42: deployed to staging. Let maya@example.com know." | add_comment with @maya@example.com in the body |
Mentions use the member's e-mail address (@maya@example.com), not their name. The assistant can look the address up with get_context for the project.
8.5 Delete
| Ask | Tool |
|---|---|
| "Delete task 42." | delete_task (asks first, see §9) |
In a Custom GPT the same requests map to the seven REST actions of §6; ids come from list_projects.
9. What the assistant can and cannot do
| Capability | Available | Note |
|---|---|---|
| Read your open tasks across all projects | Yes | 50 by default, up to 100 if the assistant asks for more; overdue first, done excluded. |
| Search one project's tasks | Yes | Text, status, type, assignee, labels, priority, scope, billing; up to 100 per page. |
| Read one task with comments, subtasks and activity | Yes | First 50 comments and 50 activity events. |
| Create tasks and subtasks | Yes | Every role. Clients' tasks are always client-visible and default to type request. |
| Update tasks | Owner/team only | Clients get Permission denied: edit_task. |
| Set scope and billing fields | Owner/team only | is_billable needs scope: out_of_scope; hours in multiples of 15 minutes; fee as a decimal string with a 3-letter currency. |
| Change client visibility | Owner/team only | client_visible, billing_client_visible. |
| Assign and unassign | Assign at creation: every role; re-assign/unassign: owner/team only | Assignee must be a project member. The assignee is notified on re-assignment (update_task), not when set at creation. |
| Add or remove labels | Owner/team only | Existing labels only — unknown labels are rejected, never created. |
Comment, with @email mentions | Yes | Every role; clients only on client-visible tasks. Mentioned members are notified. |
| Delete a task with its subtasks and comments | Owner/team only | Permanent; refuses without an explicit confirm flag; not in the Custom GPT. See Deleting below. |
| See tasks hidden from clients | Owner/team only | For clients a hidden task simply does not exist (Task 42 not found). |
| Read hours and fees as a client | Only when shared | Shown only if the task is client-visible and Show hours and fee to client is on. |
| Project members | Read-only list | get_context with a project returns its members (id, name, role, and e-mail for the project team). Clients (guests) get names and ids only, never e-mail addresses. Adding or removing members always needs a signed-in browser session. |
| Approvals, estimates, attachments, project settings | No | Not available through the assistant tools or the Custom GPT actions — use the web app. A token still acts as you on the rest of the task API, so treat a leaked token like a leaked account (§10). |
| Create or revoke tokens, change e-mail or password, add or remove members, manage the team, delete a project, change the subscription | No | Always needs a signed-in browser session; a token gets 403 This route requires an interactive session. |
Deleting. Permanent — the task goes with its subtasks and comments, and the tool refuses without an explicit confirm flag. Claude Code and Claude Desktop ask you before running it unless you chose Always allow — keep delete_task on ask. Assistants driven through the developer APIs in §7 do not ask unless you configure approval. Not available in the Custom GPT.
10. Security and privacy
- Storage. TaskOH stores only a SHA-256 hash of the token and its last four characters. The token itself is shown once, in the Copy your new token step, and never again — not in the list, not in the API.
- Revoke is immediate. After Revoke, the next request with that token is refused with
401 Invalid or revoked token. The same happens when a token expires. - A token cannot manage tokens, people or billing. These always require a signed-in browser session, never a token: the Integrations page (listing, creating and revoking tokens), changing your profile or password, adding or removing project members, workspace team management, deleting a project, and Stripe checkout or billing changes. A leaked token therefore cannot mint new tokens, invite someone as a way to keep access, take over the account, or touch the subscription. It can still read and change tasks and comments in every project your role allows, so revoke it as soon as you suspect misuse. Tokens are also never shown a project's public share link.
- What is logged. Every change made with a token is an activity event under your name with via API — task created, status changed, scope changed, planned costs changed, cost sharing changed, comment added, task deleted. Other field edits (title, description, priority, due date, assignee, labels, client visibility…) are not logged. Rejected tokens are logged server-side for abuse prevention (last four characters, client IP address and path — never the token itself; see the privacy policy). Reads produce no activity events (ordinary web-server access logs still apply, see the privacy policy).
- Advice. One token per assistant or machine (§3.2). Set an expiry — 365 days is the default; use 30 or 90 for a trial. Treat the token like a password: it belongs in your password manager and in the assistant's settings — never in chats, tickets, e-mails or code repositories.
- If a token leaks: open Integrations, revoke it, create a new one for the client, and check the dashboard's Recent activity and the affected tasks' Activity tabs for events marked via API that you did not make. Since not every edit is logged (see What is logged), also look over the tasks themselves for changed titles, assignees, labels or visibility.
- Password change. Changing your password does not revoke tokens. Revoke them yourself if you suspect misuse.
11. Not available yet
TaskOH does not offer OAuth sign-in yet. Any client that connects only through an OAuth flow cannot connect today:
- claude.ai and Claude Desktop native connectors (Settings → Connectors → Add custom connector). Adding
https://api.taskoh.app/mcpthere fails to connect. Use Claude Code (§4) or Claude Desktop withmcp-remote(§5). - ChatGPT developer-mode connectors (Settings → Apps, Authentication: OAuth). Use a Custom GPT (§6).
OAuth is on the roadmap; personal access tokens will remain supported.
One exception: some claude.ai organizations already see a beta Request headers section in the custom-connector dialog. If yours does, set Authentication to None and add a header named authorization with the value Bearer toh_pat_…. Caveats: the feature is labelled beta and limited to some organizations, the header is sometimes not sent, and the credential is shared by everyone in your organization — use a dedicated token and revoke it when the OAuth path arrives.
12. Troubleshooting
| Symptom | Cause and fix |
|---|---|
401 Unauthorized — Invalid or revoked token | The token is mistyped, expired or revoked. Create a new one on Integrations. |
401 — Missing Authorization header / Invalid Authorization header format | The header must read Authorization: Bearer toh_pat_… — the word Bearer, a space, the token. The Claude API connector is the exception: give it the raw token without Bearer. |
403 — This route requires an interactive session | You called a token-management, profile or password endpoint with a token. Do that in the web app. |
403 — Only the project team can manage scope and billing | You are a client in that project. Clients cannot set scope or billing fields; leave them out or ask the team. (REST create_task only — in the assistant tools clients cannot update tasks at all.) |
403 — plain text error code: 1010 (no JSON body) | Not a token problem. The answer came from Cloudflare, which sits in front of TaskOH, not from TaskOH itself. Until 2026-09-07 this happened to scripts using Python's built-in urllib; the API host no longer checks the client's User-Agent, so it should not recur. If it does, wait a minute and retry, and send us the cf-ray value from the response headers; check the token separately with the curl test in §7.4. |
| 405 Method Not Allowed | The client sent GET to /mcp, which only accepts POST — for example the URL was opened in a browser or the client used the SSE transport. Use --transport http in Claude Code and --transport http-only with mcp-remote. The URL is exactly https://api.taskoh.app/mcp: no /sse, no trailing slash (a wrong path such as /mcp/sse or /mcp/ answers 404, not 405). |
| 429 Too Many Requests | The assistant made more than 120 requests in a minute with one token. Nothing is broken: it can retry after the minute shown in Retry-After (60 s). If this happens often, ask the assistant to fetch fewer pages or combine edits into one update. Each token has its own limit, so other tokens and the web app are unaffected. |
"Method not found" (JSON-RPC -32601) | Normal during connection: some clients probe server/discover, which TaskOH does not implement, then fall back to the standard handshake. If the client refuses to connect, update it (Claude Code 2.1.251 or newer, latest mcp-remote). |
| Tool not listed / Claude Desktop shows no TaskOH tools | Check npx --version works, that claude_desktop_config.json is valid JSON, and quit the app completely and reopen it (§5 step 4); the first start downloads mcp-remote, so give it a minute. See Claude Desktop's Developer settings for the log location. If the log says spawn npx ENOENT, Claude Desktop cannot find Node: run which npx (macOS) / where npx (Windows) in a terminal and put that full path in "command" instead of npx. In Claude Code, run /mcp and re-run the claude mcp add command if taskoh is missing. |
| Assistant says No project named … (or Project name … is ambiguous) | The name must match exactly (case does not matter) and the project must be one you belong to. Ask the assistant to run get_context (or list_projects in ChatGPT) and use the id. The first error lists your projects, the second the matching candidates with their ids. |
| Assistant says task not found | Wrong id, a task in a project you do not belong to, or — for clients — a task not marked client-visible. |
| Assistant says unknown label or no project member matching | Labels and members are never created by the assistant. The error lists the available names; create the label in the web app first. |
| ChatGPT will not create a GPT | Creating a GPT may require a paid ChatGPT plan (§6); check your plan or ask your workspace admin. |
| ChatGPT schema import fails / "not authenticated" | Paste https://api.taskoh.app/openapi.json exactly and retry. For "not authenticated", re-enter the key under the action's Authentication settings. |
Clipboard did not copy — Couldn't copy the token. Select it and copy it manually. | Select the token text in the dialog and copy it with your keyboard before clicking I've copied it. |
13. FAQ
Does the assistant provider see my TaskOH data?
Yes — whatever the assistant reads is sent to the AI provider (Anthropic, OpenAI) as part of the conversation. Create tokens only for assistants your workspace allows.
Can I give an assistant read-only access, or access to one project only?
No. A token acts as you everywhere. If you need a narrower view, create a separate TaskOH user with the right memberships and make the token there.
Can my client use an assistant too?
Yes. Clients can create tokens; their assistant sees only client-visible tasks, can create requests and comment, and cannot update or delete tasks.
Will the assistant create labels, projects or members?
No. Labels must already exist in the project; unknown names are rejected. Projects and members are managed in the web app.
Does deleting through an assistant leave a trace?
Yes. A Task deleted event with the task's title stays in the dashboard's Recent activity even though the task is gone, marked via API.
How many requests can an assistant make?
120 requests per minute per token, counted across everything the token does (the assistant tools and the REST endpoints together). Above that TaskOH answers 429 Too Many Requests and the assistant has to wait 60 seconds (the Retry-After header) before trying again; the token itself keeps working. The limit is per token, not per network address, so your other tokens are unaffected and several people behind one IP address (for example hosted assistants) do not slow each other down. Assistants that send several commands in one message use up one request per command. The web app is not limited, except that it uses the same allowance when it talks to the assistant endpoint. Result sizes are capped: up to 100 tasks per list, up to 100 per page when searching a project, 50 comments and 50 activity events per task.
What happens when my token expires?
The client gets 401 Invalid or revoked token. The token stays in your list marked Expired until you revoke it; create a new one and update the client.
Which tokens do I have and are they in use?
See the Personal access tokens list on Integrations (§3.1).