tododdle-mcp 3.7.0 → 3.8.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.
@@ -1,19 +1,14 @@
1
1
  import { createWriteStream } from 'node:fs';
2
- import { chmod, lstat, mkdir, mkdtemp, realpath, rm, rmdir } from 'node:fs/promises';
3
- import { lookup } from 'node:dns/promises';
2
+ import { lstat, mkdtemp, realpath, rm, rmdir } from 'node:fs/promises';
3
+ import { lookup as dnsLookup } from 'node:dns/promises';
4
+ import { request as httpsRequest } from 'node:https';
4
5
  import { isIP } from 'node:net';
5
6
  import { basename, dirname, extname, relative, resolve, sep } from 'node:path';
6
7
  import { tmpdir } from 'node:os';
7
- import { Readable, Transform } from 'node:stream';
8
+ import { Transform } from 'node:stream';
8
9
  import { pipeline } from 'node:stream/promises';
9
10
  const URL_TIMEOUT_MS = 60_000;
10
11
  const MAX_REDIRECTS = 5;
11
- export async function ensureManagedUploadRoot(root) {
12
- await mkdir(root, { recursive: true, mode: 0o700 });
13
- if (process.platform !== 'win32')
14
- await chmod(root, 0o700);
15
- return realpath(root);
16
- }
17
12
  const mimeTypes = {
18
13
  '.csv': 'text/csv',
19
14
  '.gif': 'image/gif',
@@ -47,16 +42,29 @@ function sanitizeFileName(value) {
47
42
  async function prepareLocalSource(input, roots, managedRoot, maxBytes) {
48
43
  if (!input.filePath)
49
44
  throw new Error('filePath is required');
50
- const resolvedFile = await realpath(resolve(input.filePath));
51
- const resolvedRoots = await Promise.all(roots.map((root) => realpath(resolve(root))));
52
- const resolvedManagedRoot = managedRoot ? await ensureManagedUploadRoot(managedRoot) : null;
45
+ const requestedPath = resolve(input.filePath);
46
+ // Reject a symlink as the final path component before following it.
47
+ const requestedStats = await lstat(requestedPath);
48
+ if (!requestedStats.isFile())
49
+ throw new Error('Local upload source must be a regular file');
50
+ const resolvedFile = await realpath(requestedPath);
51
+ const resolvedRoots = await Promise.all(roots.map((root) => realpath(resolve(root)).catch(() => null)));
52
+ const resolvedManagedRoot = managedRoot
53
+ ? await realpath(resolve(managedRoot)).catch(() => null)
54
+ : null;
53
55
  const isManagedFile = Boolean(resolvedManagedRoot && isInsideRoot(resolvedFile, resolvedManagedRoot));
54
- if (!isManagedFile && !resolvedRoots.some((root) => isInsideRoot(resolvedFile, root))) {
55
- throw new Error('Local file is outside ToDoddle managed staging and approved upload roots');
56
+ if (!isManagedFile &&
57
+ !resolvedRoots.some((root) => root !== null && isInsideRoot(resolvedFile, root))) {
58
+ throw new Error('Local file must be in the system temporary directory or an approved upload root');
56
59
  }
57
60
  const stats = await lstat(resolvedFile);
58
61
  if (!stats.isFile())
59
62
  throw new Error('Local upload source must be a regular file');
63
+ if (process.platform !== 'win32' && typeof process.getuid === 'function') {
64
+ if (stats.uid !== process.getuid()) {
65
+ throw new Error('Local upload source must be owned by the current user');
66
+ }
67
+ }
60
68
  if (stats.size <= 0 || stats.size > maxBytes)
61
69
  throw new Error('Local file size is not allowed');
62
70
  const fileName = sanitizeFileName(input.fileName || basename(resolvedFile));
@@ -97,29 +105,68 @@ function isPrivateAddress(address) {
97
105
  (a === 192 && b === 168) ||
98
106
  (a === 100 && b >= 64 && b <= 127));
99
107
  }
100
- async function validatePublicUrl(url) {
108
+ const defaultResolver = (hostname) => dnsLookup(hostname, { all: true });
109
+ function assertPublicAddresses(addresses) {
110
+ if (addresses.length === 0 || addresses.some(({ address }) => isPrivateAddress(address))) {
111
+ throw new Error('Upload source URL resolves to a private or reserved address');
112
+ }
113
+ }
114
+ /**
115
+ * Builds a `net` lookup function that validates every resolved address at connect time.
116
+ * The socket connects only to addresses this function returns, so a DNS answer that changes
117
+ * between validation and connection (DNS rebinding) cannot reach a private address.
118
+ */
119
+ export function createValidatingLookup(resolver = defaultResolver) {
120
+ return (hostname, options, callback) => {
121
+ resolver(hostname).then((addresses) => {
122
+ try {
123
+ assertPublicAddresses(addresses);
124
+ }
125
+ catch (error) {
126
+ callback(error);
127
+ return;
128
+ }
129
+ if (options?.all)
130
+ callback(null, addresses);
131
+ else
132
+ callback(null, addresses[0].address, addresses[0].family);
133
+ }, (error) => callback(error));
134
+ };
135
+ }
136
+ function validateUrlShape(url) {
101
137
  if (url.protocol !== 'https:')
102
138
  throw new Error('Only HTTPS upload sources are allowed');
103
139
  if (url.username || url.password)
104
140
  throw new Error('Upload source URLs cannot contain credentials');
105
- const addresses = isIP(url.hostname)
106
- ? [{ address: url.hostname }]
107
- : await lookup(url.hostname, { all: true });
108
- if (addresses.length === 0 || addresses.some(({ address }) => isPrivateAddress(address))) {
109
- throw new Error('Upload source URL resolves to a private or reserved address');
110
- }
141
+ const literal = url.hostname.replace(/^\[|\]$/g, '');
142
+ if (isIP(literal))
143
+ assertPublicAddresses([{ address: literal }]);
111
144
  }
112
- async function fetchWithSafeRedirects(initialUrl) {
145
+ function requestPinned(url, resolver) {
146
+ return new Promise((resolvePromise, reject) => {
147
+ const request = httpsRequest(url, {
148
+ method: 'GET',
149
+ lookup: createValidatingLookup(resolver),
150
+ timeout: URL_TIMEOUT_MS,
151
+ signal: AbortSignal.timeout(URL_TIMEOUT_MS),
152
+ headers: { 'user-agent': 'tododdle-mcp' },
153
+ }, resolvePromise);
154
+ request.on('timeout', () => request.destroy(new Error('Upload source request timed out')));
155
+ request.on('error', reject);
156
+ request.end();
157
+ });
158
+ }
159
+ export async function fetchWithSafeRedirects(initialUrl, resolver = defaultResolver) {
113
160
  let url = new URL(initialUrl);
114
161
  for (let redirects = 0; redirects <= MAX_REDIRECTS; redirects += 1) {
115
- await validatePublicUrl(url);
116
- const response = await fetch(url, {
117
- redirect: 'manual',
118
- signal: AbortSignal.timeout(URL_TIMEOUT_MS),
119
- });
120
- if (![301, 302, 303, 307, 308].includes(response.status))
121
- return response;
122
- const location = response.headers.get('location');
162
+ validateUrlShape(url);
163
+ const response = await requestPinned(url, resolver);
164
+ const status = response.statusCode ?? 0;
165
+ if (![301, 302, 303, 307, 308].includes(status)) {
166
+ return { status, headers: response.headers, stream: response, url: url.href };
167
+ }
168
+ response.resume();
169
+ const location = response.headers.location;
123
170
  if (!location)
124
171
  throw new Error('Upload source redirect is missing a location');
125
172
  url = new URL(location, url);
@@ -130,13 +177,17 @@ async function prepareUrlSource(input, maxBytes) {
130
177
  if (!input.sourceUrl)
131
178
  throw new Error('sourceUrl is required');
132
179
  const response = await fetchWithSafeRedirects(input.sourceUrl);
133
- if (!response.ok || !response.body)
180
+ if (response.status < 200 || response.status > 299) {
181
+ response.stream.resume();
134
182
  throw new Error(`Upload source returned ${response.status}`);
135
- const declaredLength = Number(response.headers.get('content-length') || 0);
136
- if (declaredLength > maxBytes)
183
+ }
184
+ const declaredLength = Number(response.headers['content-length'] || 0);
185
+ if (declaredLength > maxBytes) {
186
+ response.stream.destroy();
137
187
  throw new Error('Remote file exceeds the maximum upload size');
188
+ }
138
189
  const directory = await mkdtemp(resolve(tmpdir(), 'tododdle-upload-'));
139
- const sourceName = basename(new URL(response.url || input.sourceUrl).pathname) || 'download';
190
+ const sourceName = basename(new URL(response.url).pathname) || 'download';
140
191
  const fileName = sanitizeFileName(input.fileName || sourceName);
141
192
  const stagedPath = resolve(directory, fileName);
142
193
  let bytes = 0;
@@ -150,7 +201,7 @@ async function prepareUrlSource(input, maxBytes) {
150
201
  },
151
202
  });
152
203
  try {
153
- await pipeline(Readable.fromWeb(response.body), limiter, createWriteStream(stagedPath, { flags: 'wx', mode: 0o600 }));
204
+ await pipeline(response.stream, limiter, createWriteStream(stagedPath, { flags: 'wx', mode: 0o600 }));
154
205
  if (bytes <= 0)
155
206
  throw new Error('Remote file is empty');
156
207
  return {
@@ -158,7 +209,7 @@ async function prepareUrlSource(input, maxBytes) {
158
209
  fileName,
159
210
  fileSize: bytes,
160
211
  contentType: input.contentType ||
161
- response.headers.get('content-type')?.split(';')[0] ||
212
+ response.headers['content-type']?.split(';')[0] ||
162
213
  inferContentType(fileName),
163
214
  cleanup: async () => rm(directory, { recursive: true, force: true }),
164
215
  };
@@ -1 +1 @@
1
- {"version":3,"file":"upload-source.js","sourceRoot":"","sources":["../src/upload-source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload-source.js","sourceRoot":"","sources":["../src/upload-source.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tododdle-mcp",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "Agent-first task, project context, and time tracking for ToDoddle",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "provenance": true
53
53
  },
54
54
  "dependencies": {
55
- "@modelcontextprotocol/sdk": "^1.30.0",
55
+ "@modelcontextprotocol/sdk": "^1.32.1",
56
56
  "zod": "^3.24.1"
57
57
  },
58
58
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tododdle-supervisor
3
- description: Use current ToDoddle supervision assessments to guide coding work at meaningful decision boundaries. Apply when supervised execution is requested and a compatible decision backend is available through ToDoddle; use tododdle-workflow alone when it is not.
3
+ description: Use current ToDoddle supervision assessments to guide coding work at meaningful decision boundaries. Apply when supervised execution is requested and a compatible decision or supervision provider is available through ToDoddle; use tododdle-workflow alone when it is not.
4
4
  ---
5
5
 
6
6
  # ToDoddle Supervisor
@@ -9,9 +9,11 @@ Read [tododdle-workflow](../tododdle-workflow/SKILL.md) first. Follow its author
9
9
 
10
10
  ## Check Availability
11
11
 
12
- Use only the `tododdle` MCP. Never call Jev, OpenJev, or another evaluator directly, and never handle its credentials.
12
+ Use only the `tododdle` MCP. Never call an external decision or supervision provider directly, and never handle its credentials.
13
13
 
14
- Treat supervision as available for a Ticket only when `get_supervisor_state` succeeds and returns a current assessment from the project’s configured decision evaluator. A current assessment must postdate the Ticket state and meaningful event it evaluates. Accept `external-system-one` or another evaluator type that project Context explicitly approves. Do not infer availability from an evaluator name.
14
+ Treat supervision as available for a Ticket only when `get_supervisor_state` succeeds and returns a current assessment from the project’s configured decision evaluator. A current assessment must postdate the Ticket state and meaningful event it evaluates. Accept only evaluator types and assessment schemas that project Context explicitly approves. Apply the same checks to every provider. Do not infer availability from a provider name, evaluator type, or product announcement.
15
+
16
+ Compatible systems can include decision APIs, supervision services, model reviewers, and deterministic rules. Provider adapters map their output to ToDoddle assessments. A System One adapter is one example, not a required wire format. Jev and OpenAI Decisions are candidate integrations; neither name proves that an adapter is configured or supported.
15
17
 
16
18
  Treat supervision as unavailable when the tool is missing, the call fails, no approved assessment exists, or the latest assessment is stale, incomplete, or conflicting. Do not call `record_assessment` to create your own guidance. Do not poll. Continue with `tododdle-workflow` when supervision is optional. If project rules require a supervised decision, preserve the current state and add an escalation instead of guessing.
17
19
 
@@ -56,7 +56,7 @@ For detailed project structure and execution rules, read [project-work.md](refer
56
56
  1. Run appropriate verification.
57
57
  2. Add one typed `HANDOFF` comment with `## Outcome`, `## Verification`, and `## Remaining` when useful. Include stable links and immutable commit, release, document, or artifact IDs. Never store expiring URLs.
58
58
  3. Call `finish_agent_run` once with a short outcome and durable evidence. Use `SUCCEEDED`, `FAILED`, or `CANCELLED`. Reuse its idempotency key if delivery is uncertain.
59
- 4. Compare the ticket creator with the authenticated Agent Connection user, not the assignee. If they match, set `COMPLETE` after the result is achieved and verified. If they differ, move the ticket to its existing `REVIEW` status and hand off to the creator or an explicitly named human reviewer. Keep it in `REVIEW` until that person records acceptance, then set `COMPLETE`. Do not add a ticket status.
59
+ 4. Compare the ticket creator with the authenticated Agent Connection user, not the assignee. If they match, set `COMPLETE` after the result is achieved and verified. If they differ, move the ticket to its existing `REVIEW` status and hand off to the creator or an explicitly named human reviewer. Keep it in `REVIEW` until that person records acceptance, then set `COMPLETE`. Do not add a ticket status. The server enforces this: an agent that sets `COMPLETE` on a ticket another user created gets `403 permission_denied`. Set `REVIEW` and call `create_review_request`. When a run is active, pass `runId` and `projectId` on `move_ticket`, `archive_ticket`, attribute tools, and time tools.
60
60
  5. Agent Run success and supervision assessment are evidence, not human acceptance. A run result never changes ticket status. A review request is separate from ticket status; archive is separate cleanup.
61
61
  6. Use `release_ticket` only when stopping without a terminal result. It records the run as cancelled.
62
62
  7. Keep incomplete work active and state what remains.
@@ -69,6 +69,7 @@ When resuming, read the agent inbox, handle the reply, then reload the linked it
69
69
  - **Time tracking:** Read [time-tracking.md](references/time-tracking.md).
70
70
  - **Scheduled checks:** Read [scheduled-workflows.md](references/scheduled-workflows.md).
71
71
  - **Support cases:** Read [support-cases.md](references/support-cases.md).
72
+ - **Releases or Testbench rounds:** Read [releases.md](references/releases.md).
72
73
 
73
74
  ## Missing Access
74
75
 
@@ -5,13 +5,13 @@ Read this file only when uploading or reviewing a ToDoddle file.
5
5
  ## Upload a Local File
6
6
 
7
7
  - Use `upload_project_document` or `attach_file_to_ticket` for approved files.
8
- - For a clipboard image, create a private directory with `mktemp -d` inside `<system-temp>/tododdle-mcp-uploads`. Copy the image into it and keep a suitable extension. Do not alter the original.
9
- - If a source is outside managed staging or optional approved roots, copy it into the managed staging directory. Never move the original.
10
- - After confirmed success, the local MCP deletes the staged file and its empty operation directory.
8
+ - For a clipboard image, create a private directory with `mktemp -d` in the system temporary directory. Copy the image into it and keep a suitable extension. Do not alter the original.
9
+ - Files must be regular files (no symlinks) in the system temporary directory or an optional approved root, and owned by the current user. If a source is elsewhere, copy it into a private directory in the system temporary directory. Never move the original.
10
+ - After confirmed success, the local MCP deletes the staged file and its empty parent directory.
11
11
  - If upload fails or is uncertain, keep the staged file for retry and report its path.
12
- - Never delete the user’s original, a pre-existing file, or a file outside managed staging.
12
+ - Never delete the user’s original, a pre-existing file, or a file outside the system temporary directory that the agent did not create.
13
13
 
14
- `TODODDLE_UPLOAD_ROOTS` is optional. Use it only for Docker, sandboxes, or approved permanent directories. Never approve the full system temporary directory.
14
+ `TODODDLE_UPLOAD_ROOTS` is optional. Use it only for Docker, sandboxes, or approved permanent directories. The system temporary directory is always allowed.
15
15
 
16
16
  ## Upload Through Hosted MCP
17
17
 
@@ -32,7 +32,7 @@ Read this file only when creating project structure or when execution needs thes
32
32
 
33
33
  - Use `list_review_requests` with one project and narrow filters. Read one request with `get_review_request` before changing it.
34
34
  - A formal review request is optional. It does not change ticket status or block work.
35
- - Compare the ticket creator with the authenticated Agent Connection user, not the assignee. If they match, mark the ticket `COMPLETE` after the result is achieved and verified. If they differ, move it to its existing `REVIEW` status and hand it off to the creator or a named human reviewer. Keep it in `REVIEW` until that person records acceptance, then mark it `COMPLETE`. Use a formal review request when useful; a clear creator or reviewer response can also record acceptance. Do not infer acceptance from an Agent Run or supervisor result. Do not add a ticket status.
35
+ - Compare the ticket creator with the authenticated Agent Connection user, not the assignee. If they match, mark the ticket `COMPLETE` after the result is achieved and verified. If they differ, move it to its existing `REVIEW` status and hand it off to the creator or a named human reviewer. Keep it in `REVIEW` until that person records acceptance, then mark it `COMPLETE`. Use a formal review request when useful; a clear creator or reviewer response can also record acceptance. Do not infer acceptance from an Agent Run or supervisor result. Do not add a ticket status. The server enforces this: setting `COMPLETE` on a ticket another user created returns `403 permission_denied`, so set `REVIEW` and call `create_review_request`.
36
36
  - Use `list_project_members` before selecting reviewers. Do not guess user IDs.
37
37
  - Create a review only for an accessible ticket, document, board, or Context artifact. Supply an idempotency key for every create, review comment, and checklist addition. Reuse the same key only when retrying that same operation.
38
38
  - Only a named reviewer can use `respond_to_review_request`. Use that reviewer’s current `updatedAt` value as `expectedUpdatedAt`.
@@ -0,0 +1,35 @@
1
+ # Releases and Testbench Rounds
2
+
3
+ Releases group tickets for one shipped version. Use the release tools only when the selected ticket or the user asks for release work.
4
+
5
+ ## Access
6
+
7
+ - Release reads need `releases:read`. Release writes need `releases:write`.
8
+ - Testbench reads need `testbench:read`. Testbench writes need `testbench:write`.
9
+ - Every call needs a project grant. Writes, and all Testbench calls, need project owner or admin access.
10
+ - `409 BETA_DISABLED` means Testbench is off for the project. Report it. Do not try to turn it on.
11
+
12
+ ## Read
13
+
14
+ - Use `list_releases` with `status`, `search`, or `includeArchived` to find a release. Follow `hasMore` with the next `page` only when you need it.
15
+ - Use `get_release` for one release. It returns up to 50 ticket summaries, the total `ticketCount`, and linked Testbench rounds. `tickets` and `ticketCount` are `null` without `tasks:read`, and `testbenchRounds` is `null` without `testbench:read` and Testbench operator access. Treat `null` as "not visible to this connection", not as "none".
16
+ - Use `list_testbench_rounds` to find a round and its current `revision`.
17
+
18
+ ## Change
19
+
20
+ - `create_release` creates a `PENDING` release. Pass a stable `idempotencyKey` so a retry does not create a second release.
21
+ - `update_release` edits version, title, build, environment, build link, and text metadata. Pass `expectedRevision` from the latest read. Reload after a `409 CONFLICT`. Archived releases cannot be edited.
22
+ - Link a ticket with `create_ticket` or `update_ticket` and `releaseId`. Set `releaseId` to `null` to remove it. Filter tickets with `list_tickets` and `releaseId`, or `none`.
23
+ - `set_round_release` links a `DRAFT` round to a release, or removes the link with `releaseId: null`. Pass the round `revision` as `expectedRevision`. It never publishes the round or sends email.
24
+
25
+ ## Status, Archive, and Restore Need Approval
26
+
27
+ - Use `request_release_status_change` to publish, abandon, return to pending, archive, or restore a release. Give a short reason and the latest `expectedRevision`.
28
+ - The tool does not change the release. A person approves or rejects the request in AIr Traffic Control. Nothing changes until then.
29
+ - The result shows `result: PENDING_APPROVAL` and `changed: false`. Do not report the release as published, abandoned, archived, or restored. Share the `uiUrl` when a person needs to decide.
30
+ - A repeated identical request returns the same approval. Do not send many requests to push a decision.
31
+ - To see the outcome later, read the release with `get_release`.
32
+
33
+ ## Agent Runs
34
+
35
+ These routes carry no Ticket ID. When you hold a run, pass `runId` and the run's `taskId` so the server can check the run envelope. Reads use `READ_PROJECT_DATA`. Writes use `UPDATE_INTERNAL_WORKFLOW`.
@@ -9,8 +9,8 @@ Support cases stay linked to internal Tickets. Use `list_support_cases` to find
9
9
  - Use `get_support_module` to read Support status and limits. The External API checks that the caller is a project owner or admin.
10
10
  - Use `get_support_attachment_url` only when needed. Its short-lived private URL is sensitive. Do not put it in a comment or log.
11
11
  - Read the latest case `revision` before a status change or reply. Use `update_support_case` for case status or priority. This does not change the internal Ticket status.
12
- - Use `preview_support_reply` before a customer-visible reply. It checks send eligibility and returns the exact text, recipient display name, and delivery target. It does not send a message.
13
- - Then call `reply_to_support_case` to send. Set `confirmSend` to `true` only for `REQUESTER_VISIBLE`. Omit it for `INTERNAL_NOTE`. Private notes do not send email.
12
+ - Use `preview_support_reply` before a customer-visible reply. It checks send eligibility and returns the exact text, recipient display name, and delivery target. It does not send a message. It also returns `preview.approval` (`required`, `policy` of `HUMAN_APPROVAL_REQUIRED` or `DIRECT_SEND_ALLOWED`, and `message`). Use it to know the outcome before you reply.
13
+ - Then call `reply_to_support_case`. Internal notes are immediate. A customer-visible reply needs human approval by default. In that case the tool returns `result: PENDING_APPROVAL` and `sent: false`. The reply is only a proposal. Do not tell anyone it was sent. Wait for a human decision in ToDoddle, then read `list_support_case_messages` to confirm. Do not retry with a new `idempotencyKey`. `confirmSend` does not bypass approval. Projects that opted in send directly. Set `confirmSend` to `true` only for `REQUESTER_VISIBLE`. Omit it for `INTERNAL_NOTE`. Private notes do not send email.
14
14
  - Every reply needs a stable 8–120 character `idempotencyKey`. Reuse a key only to retry the same actor, content, visibility, and attachments. Reload after a revision conflict. Do not retry with a stale revision or a changed payload under the same key.
15
15
 
16
16
  MCP does not return the requester's email address. For external requesters, the email is a temporary case-access notification; it does not contain the reply text. The support portal handles customer identity and access.