0.x — pre-release, no compatibility promise yet.What this means
For developers
What this is: the protocol details for your own client or agent. When you need it: you are building on the server rather than using an off-the-shelf client.
import asyncio, osfrom mcp import ClientSessionfrom mcp.client.streamable_http import streamablehttp_client
async def main(): headers = {"Authorization": f"Bearer {os.environ['TASKADENCE_TOKEN']}"} async with streamablehttp_client("https://api.taskadence.com/mcp", headers=headers) as (read, write, _): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() print([t.name for t in tools.tools])
asyncio.run(main())import { Client } from "@modelcontextprotocol/sdk/client/index.js";import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(new URL("https://api.taskadence.com/mcp"), { requestInit: { headers: { Authorization: `Bearer ${process.env.TASKADENCE_TOKEN}` } },});const client = new Client({ name: "my-agent", version: "0.1.0" });await client.connect(transport);console.log((await client.listTools()).tools.map((t) => t.name));Transport
Section titled “Transport”Streamable HTTP, one URL for every organization, stateless: each POST carries one JSON-RPC message and gets a JSON
answer — no session id, no server-sent stream. ?readonly=1 and ?groups= narrow the tools on the server
(choosing groups). The stdio packages expose the same tools.
Signing in
Section titled “Signing in”- An access token as a bearer — for your own agents and service accounts. Mint it with the scopes the agent needs; see authentication.
- OAuth 2.1 — for a client acting for people who sign in: server metadata, a client ID metadata document or dynamic registration, PKCE and refresh tokens. The consent screen lists the scopes; the token acts as the person who approved it.
Discovery and registration
Section titled “Discovery and registration”A client needs only the server URL: the 401 points at the metadata. The client then uses a client ID metadata
document (Claude does) or registers itself.
| Step | URL |
|---|---|
| Protected-resource metadata | https://api.taskadence.com/.well-known/oauth-protected-resource/mcp |
| Authorization-server metadata | https://api.taskadence.com/.well-known/oauth-authorization-server |
| Registration | https://api.taskadence.com/oauth/register |
| Authorization | https://api.taskadence.com/oauth/authorize |
| Token | https://api.taskadence.com/oauth/token |
| Revocation | https://api.taskadence.com/oauth/revoke |
Client ID metadata document
Section titled “Client ID metadata document”Your client_id is your JSON document’s https:// URL:
{ "client_id": "https://agent.example.com/oauth/client.json", "client_name": "My agent", "client_uri": "https://agent.example.com", "redirect_uris": ["http://localhost/callback", "http://127.0.0.1/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "none"}| Rule | |
|---|---|
| Advertised | client_id_metadata_document_supported: true, with none in token_endpoint_auth_methods_supported. Taskadence fetches the document when a person authorizes. |
| The URL | https://, a path, no fragment or credentials. The document’s client_id must equal it exactly. |
| The document | application/json, at most 64 KiB, served without a redirect from a public address, answering within 5 seconds. token_endpoint_auth_method must be none; no secret. The other fields follow the registration rules below. |
| Refresh | Taskadence keeps a copy for a day, and fetches it again sooner when a request names a redirect URI the copy lacks. |
| Consent | The screen shows your client_name with the document’s host — “My agent — agent.example.com”. |
| Errors | A document that breaks a rule fails the authorization with invalid_client. |
Dynamic client registration
Section titled “Dynamic client registration”Register once — there is no secret:
curl -s https://api.taskadence.com/oauth/register \ -H "Content-Type: application/json" \ -d '{ "client_name": "My agent", "redirect_uris": ["http://localhost:8765/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "none" }'| Rule | |
|---|---|
| Client type | Public: token_endpoint_auth_method must be none (a secret method is invalid_client_metadata); PKCE with S256 on every authorization. |
| Redirect URIs | 1 to 10, exact strings: https://…, http://localhost or http://127.0.0.1, cursor://, vscode://, vscode-insiders://, claude://. A loopback URI without a port, such as http://localhost/callback, matches that URI on any port. |
| Scopes | scope in the registration or document, else tasks:read tasks:write projects:read teams:read members:read — 37 tools on the default URL. An authorization without scope asks for all of them; the token response’s scope is what the person approved. |
| Consent | Once per client and organization; prompt=consent shows the screen anyway. |
| Limits | Registrations, and new metadata documents, are limited per address; a client no one connects within 30 days is revoked. No read-back or update of a registration — register again. |
| Standards | OAuth 2.1, PKCE (RFC 7636), server metadata (RFC 8414), resource metadata (RFC 9728), registration (RFC 7591), revocation (RFC 7009), client ID metadata documents, the MCP authorization specification. |
Tool annotations
Section titled “Tool annotations”Every tool has a title and all four hints — readOnlyHint, destructiveHint, idempotentHint, openWorldHint.
Use them to confirm changes with your user; destructive tools are the admin group, which also requires admin.
The tools reference has each tool’s input schema.
Rate limits
Section titled “Rate limits”Tool calls go through the API with your token, so its per-token limits apply — 600 requests a minute for a live token, 60 for a test one. See rate limits.
Errors
Section titled “Errors”A failed tool call is a result with isError: true. Its text reads <title>: <detail> (ref <request_id>); its
structured content is the API’s problem — type, status, title, detail, request_id and, for a validation
error, errors — the same problem types as the REST API. A rate-limited call adds
retry_after_seconds; the server never retries. A missing or refused token is an HTTP 401 (above), not a
tool result.
MCP or the SDK?
Section titled “MCP or the SDK?”The Python SDK calls the REST API: use it when your code decides which calls to make. Use MCP when a model decides.
Acting for your product’s users
Section titled “Acting for your product’s users”A “Connect Taskadence” button in another product is an OAuth app: register it under Developers → OAuth apps
(oauth-clients.create) and run the same flow; the token acts for the
person who consented. Server to server, use a service account’s token.