@todoist/automations-mcp 0.0.0-stage → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -2
- package/dist/chunk-S2TVZC6P.js +21096 -0
- package/dist/chunk-S2TVZC6P.js.map +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +7 -0
- package/dist/main.js +23 -0
- package/dist/main.js.map +7 -0
- package/dist/mcp-server.d.ts +11 -0
- package/dist/validate-token.d.ts +22 -0
- package/package.json +73 -5
package/README.md
CHANGED
|
@@ -1,3 +1,119 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@todoist/automations-mcp`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The MCP server for Todoist Automations: the tools that give an agent the same access to a user's
|
|
4
|
+
automations that the `tda` CLI gives, packaged for the hosted MCP server at `ai.todoist.net`. The
|
|
5
|
+
design and the rollout it is part of are in
|
|
6
|
+
[the spec](../../docs/specifications/automations-mcp-package.md).
|
|
7
|
+
|
|
8
|
+
## What it exports
|
|
9
|
+
|
|
10
|
+
`getMcpServer({ token, baseUrl })` builds an `McpServer` over one user's Automations, bound to the
|
|
11
|
+
bearer token it is given: a delegated Todoist OAuth token with the `automations` audience, or a
|
|
12
|
+
Todoist personal token.
|
|
13
|
+
|
|
14
|
+
`validateAutomationsToken(token, baseUrl)` classifies a token before any tool runs, with one
|
|
15
|
+
status-only call to the automations list: `valid`, `invalid` (401) or `forbidden` (403 with an
|
|
16
|
+
`insufficient_scope` challenge). A 403 without that challenge counts as `valid` on purpose: it is a
|
|
17
|
+
refusal consent cannot lift, such as the waiting list, so each tool surfaces the backend's own
|
|
18
|
+
message instead of the client looping through OAuth. Any other status throws
|
|
19
|
+
`TokenValidationError` from `@todoist/mcp-core/host` with the status on it, which the hosted server
|
|
20
|
+
treats as transient for 5xx. Both functions follow the contract every Todoist MCP server shares, from
|
|
21
|
+
`@todoist/mcp-core/host`.
|
|
22
|
+
|
|
23
|
+
That is the whole published surface. The tools themselves are typed against
|
|
24
|
+
`@doist/automations-sdk`, which is not published, so they are reached through the server rather than
|
|
25
|
+
exported, and the build refuses to emit a declaration that would leave a consumer with an import it
|
|
26
|
+
cannot resolve.
|
|
27
|
+
|
|
28
|
+
## Chat turns
|
|
29
|
+
|
|
30
|
+
`start-conversation` and `continue-conversation` each run one durable server turn inside the tool
|
|
31
|
+
call, the way `tda chat` does in a process: the call blocks until the agent stops, which can take
|
|
32
|
+
minutes, and reports liveness every ten seconds through `notifications/progress` when the client
|
|
33
|
+
sent a progress token, or a debug log message otherwise. Cancelling the call aborts the upstream
|
|
34
|
+
turn; the partial reply is persisted and `continue-conversation` resumes it. The shared logic is
|
|
35
|
+
`@doist/automations-sdk/chat-turn`, so the CLI and this package cannot drift on how a pending
|
|
36
|
+
action is read or a connection resolved.
|
|
37
|
+
|
|
38
|
+
## Draft tests
|
|
39
|
+
|
|
40
|
+
`test-draft` starts a test run and, unless `waitMinutes` is 0, polls it until it ends or the wait
|
|
41
|
+
runs out, reporting progress every ten seconds the same way. A run still going at the limit keeps
|
|
42
|
+
running and `get-test-run` reads it later; a cancelled or failed wait names the run for the same
|
|
43
|
+
reason. The start, the polling and the outcome mapping are the SDK's `startDraftTest` and
|
|
44
|
+
`waitForDraftTest`, shared with `tda draft test`.
|
|
45
|
+
|
|
46
|
+
## Running it locally
|
|
47
|
+
|
|
48
|
+
Everything here can run against a real account without the hosted server. `AUTOMATIONS_API_KEY` is
|
|
49
|
+
a Todoist personal token or the output of `tda auth token view`; `AUTOMATIONS_BASE_URL` points at
|
|
50
|
+
staging or a local backend and defaults to production.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm run build:core # once, from the monorepo root
|
|
54
|
+
npm run build:mcp # produces apps/mcp/dist
|
|
55
|
+
npm --workspace=apps/mcp run inspect # the MCP inspector over stdio
|
|
56
|
+
npm --workspace=apps/mcp run tool -- find-automations '{"limit": 5}'
|
|
57
|
+
npm --workspace=apps/mcp run tool -- start-conversation '{"message": "Draft an automation that..."}'
|
|
58
|
+
npm --workspace=apps/mcp run tool:list
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
An MCP client can point at the stdio build directly, with the same environment:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"automations": {
|
|
67
|
+
"command": "node",
|
|
68
|
+
"args": ["/path/to/automations/apps/mcp/dist/main.js"],
|
|
69
|
+
"env": { "AUTOMATIONS_API_KEY": "..." }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Releases
|
|
76
|
+
|
|
77
|
+
Versions before 3.0.0 were published as `@doist/automations-mcp`.
|
|
78
|
+
|
|
79
|
+
`@todoist/automations-mcp` is published from `main` by
|
|
80
|
+
[`.github/workflows/release-mcp.yml`](../../.github/workflows/release-mcp.yml), which runs
|
|
81
|
+
semantic-release with the configuration in [`release.config.js`](./release.config.js). The version
|
|
82
|
+
comes from the conventional-commit messages of the commits that count towards this package, so
|
|
83
|
+
nothing is bumped by hand and the repository holds no version number of its own. The same commits
|
|
84
|
+
make up the release notes and the Comms announcement. Releases go to the `latest` dist tag:
|
|
85
|
+
the consumer is the hosted server, which pins an exact version. After publishing, the workflow sends
|
|
86
|
+
an `automations-mcp-updated` dispatch to `todoist/todoist-ai-integrations`, whose update workflow
|
|
87
|
+
installs the version, runs its checks, commits and redeploys, so a release reaches `ai.todoist.net`
|
|
88
|
+
without waiting for a dependency PR.
|
|
89
|
+
|
|
90
|
+
The workspace libraries the package uses are not published, so `npm run build` compiles them into
|
|
91
|
+
`dist/` and only the packages under `dependencies` stay external. Any change here counts, except
|
|
92
|
+
tests, docs and `package.json` fields that don't change what gets installed. `packages/sdk`,
|
|
93
|
+
`packages/core` and `packages/bitmapist` are shared with the backend and the web app, so a change
|
|
94
|
+
confined to them counts only when its commit is scoped `mcp` or `sdk`. Any other change there still
|
|
95
|
+
ships, with the next release. See
|
|
96
|
+
[Published packages](../../docs/standards/commit-guidelines.md#published-packages) for how to split
|
|
97
|
+
pull requests so each change lands in the right release.
|
|
98
|
+
|
|
99
|
+
## Adding a tool
|
|
100
|
+
|
|
101
|
+
`src/tool-registry.ts` is the single source of truth for the tool surface; the server, `run-tool`
|
|
102
|
+
and the token-footprint baseline derive from it, and `src/tool-registry.test.ts` fails when the
|
|
103
|
+
views drift.
|
|
104
|
+
|
|
105
|
+
1. `src/utils/tool-names.ts`: add the name.
|
|
106
|
+
2. `src/tools/<tool-name>.ts`: the definition, `satisfies AutomationsTool<...>`. Copy
|
|
107
|
+
`find-automations.ts`.
|
|
108
|
+
3. `src/tool-registry.ts`: add it to the map, in the section it belongs to.
|
|
109
|
+
4. `src/tools/tool-annotations.test.ts`: add its annotation expectation.
|
|
110
|
+
5. `src/tools/<tool-name>.test.ts`: tests against a faked `AutomationsApi`.
|
|
111
|
+
6. `src/mcp-server.ts`: add to `instructions` only when the tool needs cross-tool routing
|
|
112
|
+
guidance; per-tool detail belongs in its own description.
|
|
113
|
+
|
|
114
|
+
Output schemas never use `.nullable()`: nulls are stripped before the SDK validates the output, so
|
|
115
|
+
a nullable field is a validation failure waiting to happen. Use `.optional()` and leave the key
|
|
116
|
+
out. `src/tools/output-schema-nullability.test.ts` enforces it.
|
|
117
|
+
|
|
118
|
+
`src/token-footprint.test.ts` prints what the tool surface costs a model on every `tools/list`. If a
|
|
119
|
+
change pushes the combined fixed cost over its budget, raise the budget in the same PR and say so.
|