@doist/automations-mcp 0.0.0 → 1.1.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 CHANGED
@@ -1,45 +1,104 @@
1
- # @doist/automations-mcp
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@doist/automations-mcp`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
1
+ # `@doist/automations-mcp`
2
+
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
+ `AutomationsTokenValidationError` with the status on it, which the hosted server treats as
20
+ transient for 5xx.
21
+
22
+ That is the whole published surface. The tools themselves are typed against
23
+ `@doist/automations-sdk`, which is not published, so they are reached through the server rather than
24
+ exported, and the build refuses to emit a declaration that would leave a consumer with an import it
25
+ cannot resolve.
26
+
27
+ ## Chat turns
28
+
29
+ `start-conversation` and `continue-conversation` each run one durable server turn inside the tool
30
+ call, the way `tda chat` does in a process: the call blocks until the agent stops, which can take
31
+ minutes, and reports liveness every ten seconds through `notifications/progress` when the client
32
+ sent a progress token, or a debug log message otherwise. Cancelling the call aborts the upstream
33
+ turn; the partial reply is persisted and `continue-conversation` resumes it. The shared logic is
34
+ `@doist/automations-sdk/chat-turn`, so the CLI and this package cannot drift on how a pending
35
+ action is read or a connection resolved.
36
+
37
+ ## Running it locally
38
+
39
+ Everything here can run against a real account without the hosted server. `AUTOMATIONS_API_KEY` is
40
+ a Todoist personal token or the output of `tda auth token view`; `AUTOMATIONS_BASE_URL` points at
41
+ staging or a local backend and defaults to production.
42
+
43
+ ```bash
44
+ npm run build:core # once, from the monorepo root
45
+ npm run build:mcp # produces apps/mcp/dist
46
+ npm --workspace=apps/mcp run inspect # the MCP inspector over stdio
47
+ npm --workspace=apps/mcp run tool -- find-automations '{"limit": 5}'
48
+ npm --workspace=apps/mcp run tool -- start-conversation '{"message": "Draft an automation that..."}'
49
+ npm --workspace=apps/mcp run tool:list
50
+ ```
51
+
52
+ An MCP client can point at the stdio build directly, with the same environment:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "automations": {
58
+ "command": "node",
59
+ "args": ["/path/to/automations/apps/mcp/dist/main.js"],
60
+ "env": { "AUTOMATIONS_API_KEY": "..." }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Releases
67
+
68
+ `@doist/automations-mcp` is published from `main` by
69
+ [`.github/workflows/release-mcp.yml`](../../.github/workflows/release-mcp.yml), which runs
70
+ semantic-release with the configuration in [`release.config.js`](./release.config.js). The version
71
+ comes from the conventional-commit messages that touched this directory, so nothing is bumped by
72
+ hand and the repository holds no version number of its own. Releases go to the `latest` dist tag:
73
+ the consumer is the hosted server, which pins an exact version. After publishing, the workflow sends
74
+ an `automations-mcp-updated` dispatch to `Doist/todoist-ai-integrations`, whose update workflow
75
+ installs the version, runs its checks, commits and redeploys, so a release reaches `ai.todoist.net`
76
+ without waiting for a dependency PR.
77
+
78
+ The workspace libraries the package uses are not published, so `npm run build` compiles them into
79
+ `dist/` and only the packages under `dependencies` stay external. Because a release is scoped to
80
+ commits under `apps/mcp`, a change confined to one of those libraries does not trigger a release
81
+ even though it changes what gets published; it ships with the next release instead. Publish it
82
+ sooner by landing it together with a change here.
83
+
84
+ ## Adding a tool
85
+
86
+ `src/tool-registry.ts` is the single source of truth for the tool surface; the server, `run-tool`
87
+ and the token-footprint baseline derive from it, and `src/tool-registry.test.ts` fails when the
88
+ views drift.
89
+
90
+ 1. `src/utils/tool-names.ts`: add the name.
91
+ 2. `src/tools/<tool-name>.ts`: the definition, `satisfies AutomationsTool<...>`. Copy
92
+ `find-automations.ts`.
93
+ 3. `src/tool-registry.ts`: add it to the map, in the section it belongs to.
94
+ 4. `src/tools/tool-annotations.test.ts`: add its annotation expectation.
95
+ 5. `src/tools/<tool-name>.test.ts`: tests against a faked `AutomationsApi`.
96
+ 6. `src/mcp-server.ts`: add to `instructions` only when the tool needs cross-tool routing
97
+ guidance; per-tool detail belongs in its own description.
98
+
99
+ Output schemas never use `.nullable()`: nulls are stripped before the SDK validates the output, so
100
+ a nullable field is a validation failure waiting to happen. Use `.optional()` and leave the key
101
+ out. `src/tools/output-schema-nullability.test.ts` enforces it.
102
+
103
+ `src/token-footprint.test.ts` prints what the tool surface costs a model on every `tools/list`. If a
104
+ change pushes the combined fixed cost over its budget, raise the budget in the same PR and say so.