tascan-mcp 3.10.0 → 3.11.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 +17 -2
- package/index.js +1 -1
- package/package.json +1 -1
- package/tools.cjs +17 -2
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ Add as a custom connector in Claude (Settings > Connectors). When you first use
|
|
|
107
107
|
| Tool | Description | Type |
|
|
108
108
|
|------|-------------|------|
|
|
109
109
|
| `tascan_list_tasks` | List all tasks in an event | Read |
|
|
110
|
-
| `tascan_get_task` | Get task details including completions | Read |
|
|
110
|
+
| `tascan_get_task` | Get task details including completions; each completion carries `photo_url` (raw storage path) + `photo_signed_url` (fetchable, ~1h, `null` when no photo) | Read |
|
|
111
111
|
| `tascan_add_tasks` | Bulk-create tasks in an event | Create |
|
|
112
112
|
| `tascan_update_task` | Update task title, type, flags, order | Update |
|
|
113
113
|
| `tascan_delete_task` | Delete a task and its completions | Delete |
|
|
@@ -125,7 +125,7 @@ Add as a custom connector in Claude (Settings > Connectors). When you first use
|
|
|
125
125
|
| `tascan_generate_qr` | Generate a QR code for an event | Create |
|
|
126
126
|
| `tascan_apply_template` | Apply a pre-built template to an event | Create |
|
|
127
127
|
| `tascan_list_templates` | List available task templates | Read |
|
|
128
|
-
| `tascan_get_report` | Get completion report for an event (optional `include_responses` returns submitted response data) | Read |
|
|
128
|
+
| `tascan_get_report` | Get completion report for an event (optional `include_responses` returns submitted response data plus a per-task `photos[]` list of `{ path, signed_url, completed_at, worker_name }`) | Read |
|
|
129
129
|
| `tascan_generate_report` | Mint a shareable Completion / Service (client-branded, acknowledgeable) / Project / Evidence Pack link; optionally text it | Write |
|
|
130
130
|
| `tascan_list_reports` | Existing report links for a list or project with acknowledgment status | Read |
|
|
131
131
|
| `tascan_invite_worker` | Consented intro to a marketplace worker: TaScan texts them, YES adds them to your org + sends the list, NO keeps them anonymous | Write |
|
|
@@ -262,6 +262,21 @@ API keys are scoped to your organization and support rate limiting (60 requests/
|
|
|
262
262
|
- Photo-required tasks won't show as complete until the photo uploads
|
|
263
263
|
- Check the event's response mode (single vs. multi-response)
|
|
264
264
|
|
|
265
|
+
**Photo evidence links**
|
|
266
|
+
- `photo_url` is the raw storage object path (stable, never changes). `photo_signed_url` is a fetchable HTTPS link that expires after ~1 hour (server default `TASCAN_PHOTO_URL_TTL=3600`). Re-run the read tool for a fresh link; never store the signed URL.
|
|
267
|
+
- `photo_signed_url: null` with a non-null `photo_url` means signing was unavailable at read time (storage hiccup). The read still succeeds — retry for the link.
|
|
268
|
+
|
|
269
|
+
## Changelog
|
|
270
|
+
|
|
271
|
+
### v3.11.0 — 2026-09-11
|
|
272
|
+
- **Signed photo URLs in every completion payload.** Photo evidence was invisible to AI agents: `photo_url` was a bare private-bucket path with no host or token. Every read path that returns a completion now also returns `photo_signed_url` (short-lived, default 1h, tunable via `TASCAN_PHOTO_URL_TTL`), `null` when there is no photo. Covered: `tascan_get_task` (task + subtask completions), `tascan_get_report` (new per-task `photos[]` when `include_responses` is true, replacing the bare `[+photo]` marker), `tascan_list_subtasks`, `tascan_query_responses`, `tascan_list_issues` / issue analysis (issue + injury photos), `tascan_zone_compliance` (PPE checkpoint photos), `tascan_condition_history` (assessment + baseline photos).
|
|
273
|
+
- One batched storage signing call per response (a 40-task list fires one request, not 40). Signing failures log and degrade to `photo_signed_url: null` with the raw path intact; the tool call never fails.
|
|
274
|
+
- Single shared signing helper on the server (`photo-sign-lib`) now backs the API, the photo proxy used by the Completion / Client / Project / Evidence Pack reports, and every AI vision fetcher, so URL construction cannot drift again.
|
|
275
|
+
- Remote endpoint `serverInfo.version` now reads from this package instead of a stale hardcoded string.
|
|
276
|
+
|
|
277
|
+
### v3.10.0 — 2026-09-03
|
|
278
|
+
- 69 tools: invoices, P2P worker payments, hazard zones with AI-verified PPE checkpoints, full RLS lockdown, agent claims.
|
|
279
|
+
|
|
265
280
|
## Privacy Policy
|
|
266
281
|
|
|
267
282
|
TaScan collects and processes task completion data, worker information (name, phone, email), GPS coordinates (with consent), and photos uploaded during task completion. Data is stored securely in Supabase with row-level security policies. API access is authenticated and rate-limited.
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tascan-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"mcpName": "io.github.snowbikemike/tascan-mcp",
|
|
5
5
|
"description": "TaScan MCP Server — Closed-loop autonomous operations protocol. 69 tools for projects, tasks, workers, QR codes, NFC tags, worker marketplace with consented SMS invites, geofenced zones with rules (work site / hazard + AI-verified PPE checkpoints / containment / restricted, breach alerts, zone compliance audit), AI condition assessment, worker passports, verification-gated gig payments, client invoicing from verified work (overtime / day rate / per diem / expenses), shareable report links (completion, client service report, project, evidence pack), cross-entity search, duplicate-worker detection, worker identity merge, AI issue analysis, and autonomous remediation dispatch. 15 patents filed (470+ claims). Task. Scan. Done.",
|
|
6
6
|
"type": "module",
|
package/tools.cjs
CHANGED
|
@@ -395,7 +395,7 @@ const TOOLS = [
|
|
|
395
395
|
},
|
|
396
396
|
{
|
|
397
397
|
name: 'tascan_get_task',
|
|
398
|
-
description: 'Get details of a specific task including completions',
|
|
398
|
+
description: 'Get details of a specific task including completions and subtasks. Each completion carries photo_url (raw storage path, stable) and photo_signed_url (short-lived fetchable URL, ~1h; null when no photo) so you can actually view the photo evidence.',
|
|
399
399
|
inputSchema: {
|
|
400
400
|
type: 'object',
|
|
401
401
|
properties: { task_id: { type: 'string', description: 'Task ID' } },
|
|
@@ -733,7 +733,7 @@ const TOOLS = [
|
|
|
733
733
|
},
|
|
734
734
|
{
|
|
735
735
|
name: 'tascan_get_report',
|
|
736
|
-
description: 'Get completion report for a task list (event) including task status, completions, workers, and photos. Set include_responses to also return the actual submitted response data (numbers, text, choices) for each completed task.',
|
|
736
|
+
description: 'Get completion report for a task list (event) including task status, completions, workers, and photos. Set include_responses to also return the actual submitted response data (numbers, text, choices) for each completed task plus a per-task photos list with fetchable signed URLs (short-lived, ~1h) for the photo evidence.',
|
|
737
737
|
inputSchema: {
|
|
738
738
|
type: 'object',
|
|
739
739
|
properties: {
|
|
@@ -762,7 +762,14 @@ const TOOLS = [
|
|
|
762
762
|
text += ` -> ${value != null ? value : '(no value)'}${note ? ' — ' + note : ''} (${resp.worker_name}, ${resp.completed_at})\n`;
|
|
763
763
|
}
|
|
764
764
|
}
|
|
765
|
+
// Photo evidence: retrievable signed URLs (task.photos = [{ path, signed_url, completed_at, worker_name }])
|
|
766
|
+
if (args.include_responses && task.photos && task.photos.length > 0) {
|
|
767
|
+
for (const ph of task.photos) {
|
|
768
|
+
text += ` photo: ${ph.signed_url || ph.path + ' (signing unavailable)'} (${ph.worker_name}, ${ph.completed_at})\n`;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
765
771
|
}
|
|
772
|
+
if (args.include_responses) text += '\nphotos: signed URLs expire (~1h) — re-run this tool for fresh links.\n';
|
|
766
773
|
return text;
|
|
767
774
|
}
|
|
768
775
|
},
|
|
@@ -793,8 +800,11 @@ const TOOLS = [
|
|
|
793
800
|
text += `${when} · ${resp.list_name} · ${label}: ${value != null ? value : '(no value)'}`;
|
|
794
801
|
if (note) text += ` — ${note}`;
|
|
795
802
|
text += ` (${resp.worker_name})\n`;
|
|
803
|
+
// Photo evidence: fetchable signed URL (falls back to the raw path if signing was unavailable)
|
|
804
|
+
if (resp.photo_url) text += ` photo: ${resp.photo_signed_url || resp.photo_url + ' (signing unavailable)'}\n`;
|
|
796
805
|
}
|
|
797
806
|
if (r.responses.length === 0) text += '(no responses found)\n';
|
|
807
|
+
else if (r.responses.some(x => x.photo_url)) text += '\nphotos: signed URLs expire (~1h) — re-run this tool for fresh links.\n';
|
|
798
808
|
return text;
|
|
799
809
|
}
|
|
800
810
|
},
|
|
@@ -818,8 +828,10 @@ const TOOLS = [
|
|
|
818
828
|
text += `${i+1}. [${iss.status.toUpperCase()}] ${iss.title}\n`;
|
|
819
829
|
text += ` ID: ${iss.id} | Type: ${iss.type} | Category: ${iss.category} | Severity: ${iss.severity || 'unset'}\n`;
|
|
820
830
|
if (iss.tasks) text += ` Task: ${iss.tasks.title}\n`;
|
|
831
|
+
if (iss.photo_url) text += ` Photo: ${iss.photo_signed_url || iss.photo_url + ' (signing unavailable)'}\n`;
|
|
821
832
|
text += ` Reported: ${iss.created_at}\n\n`;
|
|
822
833
|
});
|
|
834
|
+
if (issues.some(x => x.photo_url)) text += 'photos: signed URLs expire (~1h) — re-run this tool for fresh links.\n';
|
|
823
835
|
return text;
|
|
824
836
|
}
|
|
825
837
|
},
|
|
@@ -1473,7 +1485,10 @@ const TOOLS = [
|
|
|
1473
1485
|
text += `\n${s.created_at.slice(0, 16).replace('T', ' ')} — ${s.condition_score ?? '?'}/100 (${s.condition_grade || '?'})`;
|
|
1474
1486
|
if (s.delta_score != null) text += ` [${s.delta_score > 0 ? '+' : ''}${s.delta_score}]`;
|
|
1475
1487
|
if (s.summary) text += `\n ${s.summary}`;
|
|
1488
|
+
if (s.photo_url) text += `\n photo: ${s.photo_signed_url || s.photo_url + ' (signing unavailable)'}`;
|
|
1476
1489
|
});
|
|
1490
|
+
if (a.baseline_photo_url) text += `\n\nbaseline photo: ${a.baseline_photo_signed_url || a.baseline_photo_url + ' (signing unavailable)'}`;
|
|
1491
|
+
if (a.baseline_photo_url || (a.assessments || []).some(s => s.photo_url)) text += '\n\nphotos: signed URLs expire (~1h) — re-run this tool for fresh links.';
|
|
1477
1492
|
return text;
|
|
1478
1493
|
}
|
|
1479
1494
|
},
|