# Alldone.app > Alldone is a productivity app with an AI Chief of Staff: tasks, notes, goals, contacts, chats, > a project wiki, artifacts, Gmail and Google Calendar. AI agents can use it in three ways. Every > way acts as a signed-in Alldone user, with exactly that user's permissions. There is no anonymous > access. ## 1. MCP connector (clients that can add a custom/remote MCP server) - Server URL: https://my.alldone.app/mcpServer (Streamable HTTP, JSON-RPC 2.0) - Auth: OAuth 2.1 with PKCE. Discovery: https://my.alldone.app/.well-known/oauth-protected-resource/mcpServer - Works with Claude (custom connector), Claude Code, Codex, Cursor and other MCP clients. ## 2. WebMCP (browsers with `document.modelContext`) When the user is signed in at https://my.alldone.app, the page registers its tools with WebMCP (`document.modelContext.registerTool`; older Chrome builds: `navigator.modelContext`). A browser agent that supports WebMCP lists and calls them directly. No setup is needed. ## 3. JavaScript in the page (`window.alldone`) Browser agents without WebMCP support (they can run JavaScript in the tab) use the same tools through `window.alldone`. It is an enumerable global (`'alldone' in window`, `Object.keys(window)`), present from the moment the app loads. Check `alldone.state`: - `ready`: the user is signed in and the tools work. - `loading` / `signed_out`: a placeholder with no tools. `alldone.help()` explains what to do, and `await alldone.whenReady()` resolves with the ready API once the user is signed in. You can also listen for the `alldone:agent-api-ready` event. Then: ```js alldone.help() // short usage text const tools = await alldone.listTools() // [{ name, description, inputSchema, annotations }] const projects = await alldone.callTool('get_user_projects', {}) const tasks = await alldone.callTool('get_tasks', { projectId: projects[0]?.id }) await alldone.tools.create_task({ name: 'Call Anna about the offer' }) // shortcut for callTool ``` - After `listTools()`, `Object.keys(alldone.tools)` lists the tool names, and `alldone.help()` names them. - Results are parsed JSON. A failed call throws `AlldoneToolError` (`error.message` explains why). - Agents that inspect the DOM: `