MCP
DevWorkspace Pro has one MCP server for all its tools. With it, an AI agent, for example Claude Code, can work with your Focus Pad tasks and your Native PHP projects through the Model Context Protocol (MCP).
The server runs only on your computer. It is off by default.
Turn On the Server
- Open Preferences > Focus Pad.
- In MCP server for AI agents, turn on the switch.
- Optional: change the Port. The default is
47821. - Click Save.
The server starts immediately. You do not have to restart DevWorkspace Pro. The bottom of the card shows Running on 127.0.0.1:47821.
If another app uses the port, the card tells you. Type a different port from 1024 to 65535 and click Save.
To stop the server, turn off the switch and click Save.
Connect Claude Code
When the server runs, the card shows the command for Claude Code:
- Click the copy icon next to Connect Claude Code.
- Paste the command in a terminal and press Enter.
The command is:
claude mcp add --transport http --scope user dwp-focuspad http://127.0.0.1:47821/mcp --header "Authorization: Bearer <token>"DevWorkspace Pro puts your token and port in the command when you copy it. --scope user makes the server available in all your projects. You do this step only one time.
To make sure that the connection works, start Claude Code and type /mcp. The list shows dwp-focuspad as connected. Then ask, for example, "Show my Focus Pad collections." The server keeps the name dwp-focuspad for all its tools.
TIP
Tell the agent how to use the board, for example in your CLAUDE.md: "Keep open review items in the Focus Pad collection Job board. Use priority 5 and Pesky every 30 minutes for items that block a release."
Other MCP Clients
Each MCP client that supports the Streamable HTTP transport and custom headers can connect. Use these values:
| Setting | Value |
|---|---|
| Transport | Streamable HTTP |
| URL | The Endpoint in the card, for example http://127.0.0.1:47821/mcp |
| Header | Authorization: Bearer <token>. Copy the token with the copy icon next to Token. |
For example, a JSON configuration file for many clients:
{
"mcpServers": {
"dwp-focuspad": {
"type": "http",
"url": "http://127.0.0.1:47821/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}The server does not use sessions. Each request is complete. Only POST requests are accepted.
Focus Pad Tools
The agent can add tasks, complete them, and set their priority, color, deadline, duration, repeat and Pesky interval. DevWorkspace Pro then reminds you about these tasks in the same way as about tasks that you added yourself. For example:
- Ask the agent to make a Job board collection and to add each open item from a code review.
- The agent sets priority 5 and a deadline on the item that blocks the release, and turns on Pesky every 30 minutes.
- Pesky sends you a desktop notification every 30 minutes until you complete the task.
The agent sees these tools. Their descriptions tell the agent the formats below, so you do not have to explain them.
| Tool | What it does | Arguments |
|---|---|---|
list_collections | Lists the collections, with the number of open tasks (items) and done tasks (done) in each | None |
list_items | Lists the open tasks of one collection, in order, with the Pesky status of each task. Also gives the color names of the collection and your local time. See Done Tasks. | collection, optional includeDone, doneSince |
add_item | Adds a task after the last task of the collection. Returns the task with its id. | collection, text, optional notes, priority, color, due, minutes, pesky, peskyFrom, repeat |
update_item | Changes the text, the notes or the fields of one task | collection, id (or index and expectedText), optional text, notes, priority, color, due, minutes, pesky, peskyFrom, repeat |
complete_item | Marks one task as done, the same as when you complete a task with ⌘-click. See Done Tasks and Repeating Tasks. | collection, id (or index and expectedText) |
delete_item | Deletes one task and the lines nested below it for good, for example a task that was added by mistake. Use complete_item for a task that is done. | collection, id (or index and expectedText) |
create_collection | Makes a new, empty collection | name |
rename_collection | Renames a collection. Its tasks, their fields, its color names, its sort order and the Pesky counts of its tasks stay the same. You cannot rename General. | from, to |
Fields
| Field | Values |
|---|---|
notes | Notes below the task text. Use \n to separate lines. Markdown is allowed, but HTML comments are not. null or "" removes them. |
priority | Whole number from 0 to 5. 5 is the most urgent. 0 removes the priority. |
color | red, orange, brown, green, teal, blue, purple or magenta |
due | Deadline in your local time, in the format YYYY-MM-DDTHHMM, for example 2026-10-08T1430. The agent can also send 2026-10-08T14:30. |
minutes | Duration: how long the task takes, in minutes, from 1 to 1440 |
pesky | Pesky interval in minutes, from 1 to 1440 (24 hours) |
peskyFrom | Pesky start time in your local time, same format as due. Pesky stays quiet until this time, then sends the first notification. |
repeat | { "every": "day" }, or { "every": "week", "days": ["mon", "thu"] } with days from sun, mon, tue, wed, thu, fri, sat. See Repeating Tasks. |
null removes a field. If the agent does not send a field, the field does not change.
list_items also returns these read-only values for each task:
| Value | Meaning |
|---|---|
index | Position of the task in the collection, from 0 |
notes | The notes below the task, or null |
id | A name for the task that does not change. See Item IDs. It is null if the task does not have an id yet. |
doneAt | Local time when the task was completed, or null for an open task |
peskyStatus | null when Pesky is off. Otherwise nudges (the number of notifications that Pesky sent), lastNudgeAt (time of the last notification, or null) and nextNudgeAt (time of the next notification), in your local time |
selected | true if you selected the task in Focus Pad. A checked box in Focus Pad selects a task. It does not complete it. |
order | The order in which you added the task. See Default order. |
githubIssue | The issue number if the task came from a GitHub issue |
Item IDs
Each task has an id, for example k3j9x2ab, and add_item returns the id of the new task. The id does not change when tasks are added, deleted, moved or sorted, or when the task text changes. So the agent can hold on to the id and update the task later, without calling list_items again.
Older tasks get an id the first time you edit the collection in Focus Pad, or when the agent updates the task with update_item.
Safe Edits
Without an id, the agent sends the index of the task and its current text as expectedText. If you moved, sorted or changed tasks after the agent read the list, the text at that index is different. Then DevWorkspace Pro refuses the change, and the agent reads the list again.
This check only compares the text. If two tasks have the same text and they swap places, the check cannot tell, and the agent may change the wrong one. Using the id avoids this.
Done Tasks
complete_item keeps the task in the collection, sets doneAt and stops Pesky for it. Done tasks are hidden in Focus Pad, and list_items leaves them out unless the agent asks for them:
| Argument | Result |
|---|---|
| none | Open tasks only |
includeDone: true | All tasks, open and done |
doneSince: "2026-10-16T0000" | Open tasks, and the tasks that were done at or after this local time |
For a daily check-in, for example, the agent can call list_items with doneSince set to the start of the day. It then sees what you finished today and what is still open.
Note that index counts done tasks too, so the indexes of open tasks may skip numbers.
Repeating Tasks
A task with repeat comes back after it is done. See Repeating Tasks for how it works in Focus Pad. When the task is completed, by the agent or by you:
- A done copy of the task is added just before it, with
doneAt, a newidand norepeat. - The task itself stays open with the same
id, and itspeskyFromandduemove to the next day in the rule, at the same time. SopeskyFromalways holds the start time of the current or the next round. complete_itemreturns the open task with its newpeskyFrom.
Give a repeating task a peskyFrom or a due, so it has a time of day. If it has neither, it stays as it is, and only the done copy is added.
Pesky Status
peskyStatus shows how often Pesky has reminded you about a task. If the count keeps going up, you are probably ignoring that task. The counts start again when you restart DevWorkspace Pro or change the Pesky interval of the task.
Examples
Add a task that Pesky starts to remind you about tomorrow at 10:00:
{
"name": "add_item",
"arguments": {
"collection": "General",
"text": "Call the bank",
"pesky": 30,
"peskyFrom": "2026-10-17T1000"
}
}The result contains the new task:
{
"collection": "General",
"item": {
"index": 4,
"id": "k3j9x2ab",
"text": "Call the bank",
"pesky": 30,
"peskyFrom": "2026-10-17T1000"
}
}Change the task later with its id:
{
"name": "update_item",
"arguments": { "collection": "General", "id": "k3j9x2ab", "priority": 5 }
}Add a task with notes:
{
"name": "add_item",
"arguments": {
"collection": "General",
"text": "Call the bank",
"notes": "Account 1234\nAsk about the transfer fees"
}
}In the collection, the notes sit below the task as an indented paragraph (see Notes):
- [ ] Call the bank <!-- focuspad id=k3j9x2ab -->
Account 1234
Ask about the transfer feeslist_items returns them in notes. If a line starts with a list marker such as - , Focus Pad escapes it (\- ), so it stays part of the notes and does not become a new list item. Bold at the start of a line, for example **Text**, stays as it is.
Add a task that comes back every day at 19:00 and reminds you every 15 minutes until it is done:
{
"name": "add_item",
"arguments": {
"collection": "General",
"text": "Evening review",
"pesky": 15,
"peskyFrom": "2026-10-16T1900",
"repeat": { "every": "day" }
}
}When it is completed, the result shows when it starts next:
{
"name": "complete_item",
"arguments": { "collection": "General", "id": "ev7q2m1x" }
}{
"collection": "General",
"item": {
"id": "ev7q2m1x",
"text": "Evening review",
"pesky": 15,
"peskyFrom": "2026-10-17T1900",
"repeat": { "every": "day" },
"doneAt": null
}
}See what you finished today:
{
"name": "list_items",
"arguments": { "collection": "General", "doneSince": "2026-10-16T0000" }
}A task in the result of list_items, after three notifications:
{
"index": 4,
"id": "k3j9x2ab",
"text": "Call the bank",
"pesky": 30,
"peskyStatus": { "nudges": 3, "lastNudgeAt": "2026-10-17T1100", "nextNudgeAt": "2026-10-17T1130" }
}The examples show only some fields of each task.
Each change keeps all other lines of the collection as they are: headings, notes, other tasks and the color names. Lines in a task, for example nested tasks, notes and code blocks below it, stay with the task. When the agent deletes a task, these lines are deleted too.
The agent cannot make a collection with the name General or with the name of a collection that exists. Upper and lower case letters count as the same.
Native PHP Tools
On macOS, the agent also gets these tools for Native PHP. They do what the DDEV to Native PHP and Convert to DDEV recipes and Preferences > Native PHP do. A move that the agent starts shows in the recipe dialog too.
| Tool | What it does | Arguments |
|---|---|---|
native_php_list_projects | Lists the DDEV projects and the projects already on native PHP. With preflight: true, each project that is not moved yet also gets the recipe checks, notices, PHP and database version options and plan. | optional preflight |
native_php_convert | Moves one project to native PHP, removes its DDEV copy and deletes its .ddev folder, the same as Convert to Native PHP. Returns a job at once. Jobs run one at a time. | project, confirm_remove_ddev: true, optional php_version, db_version |
native_php_job_status | Shows a job: its state, each step, the output, the error and the result. waitingForPassword is true while macOS waits for your password. | job_id |
native_php_convert_to_ddev | Converts a native project to DDEV, the same as Convert to DDEV. It refuses when DDEV or Docker does not run, or another DDEV project has the name. Returns a job. | project |
native_php_site_status | Shows the native sites and services, with the state, PID, restarts and log file of each service. | optional project |
native_php_share_start | Shares a native site with a Cloudflare quick tunnel and returns the URL. See Share a native site. | project, optional confirm_install |
native_php_share_stop | Stops the share. The URL stops working. | project |
native_php_share_status | Shows the running shares: URL, local port and state. | optional project |
native_php_shell_path | Turns Use DWP PHP in my shell on or off, or shows its state. | action: enable, disable or status |
native_php_host_tools | Lists the tools that the DDEV image of the project installs, for example Chrome, ffmpeg, Playwright browsers or Python venvs, and whether your Mac has each one. Lines that DevWorkspace Pro does not know are in needsReview. Changes nothing. | project |
native_php_install_host_tools | Installs the missing host tools on your Mac with Homebrew, npm, npx or a Python venv. | project, confirm: true, optional tools |
native_php_mark_host_line_handled | Marks one needsReview line as handled after you set up the same thing on your Mac. The recipe check then stops blocking on that line. | project, line |
The descriptions tell the agent to ask you before it converts a project to DDEV, shares a site, installs tools or changes your shell file. native_php_convert refuses to run without confirm_remove_ddev: true, which says that you know the DDEV copy and the .ddev folder are removed. native_php_install_host_tools refuses to run without confirm: true.
Security
- Only this computer. The server listens on
127.0.0.1. Other computers on your network cannot connect to it. - Token. Each request must send the token in the
Authorizationheader. A request without the correct token gets the error401and changes nothing. DevWorkspace Pro makes a random token the first time that you turn on the server, and keeps it in the app settings file. - No web pages. The server refuses requests from web pages in your browser.
- Off by default. The server runs only when you turn it on.
- New token. To stop all connected agents, click Regenerate token and confirm. Then copy the new command or token to the agents that you want to keep.
Click the eye icon next to Token to show or hide the token. The command in the card also hides the token until you show it.
Treat the token as a password
Each program on your computer that has the token can read and change your Focus Pad and use the Native PHP tools. Do not put the token in files that you share or commit to Git.
Limits
- DevWorkspace Pro must be open. When it is closed, the server is not available and the agent gets a connection error.
In Focus Pad:
- The agent works with tasks (
- [ ]lines). It cannot delete collections, change headings or notes, or change color names. - Done tasks stay in the collection until they are deleted, and a repeating task adds a new done copy each time it is completed. To clear them out, the agent can use
delete_item, or you can delete them in Focus Pad. - When the agent completes a task that came from a GitHub issue, the issue stays open. To close the issue too, complete the task yourself in Focus Pad.
- Task text from the agent cannot end with
- #and a number, because Focus Pad reads that as a link to a GitHub issue. orderandgithubIssueare read-only.- The agent sees a change that you make in Focus Pad only when it calls
list_itemsagain. - When the agent changes a task, the Focus Pad window shows the change immediately. Your cursor and scroll position stay where they are. If you type in the same collection at the same moment, one of the two changes can be lost. Wait until the agent completes its change.
- If you create, rename or delete a collection at the same moment as the agent changes a task, the change of the agent can be lost. If this occurs, tell the agent to make the change again.
- Cloud Save and Pesky see the changes of the agent, the same as your changes.