tascan-mcp 2.2.0 → 2.4.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 +44 -4
- package/index.js +89 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
AI agent integration for [TaScan](https://tascan.io) — the closed-loop autonomous operations protocol. Manage projects, events, tasks, workers, QR codes, templates, completion reports, and AI-powered issue resolution through Claude, GitHub Copilot, or any MCP-compatible AI client.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Task. Scan. Done.**
|
|
6
6
|
|
|
7
7
|
## What is TaScan?
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ When something breaks, AI analyzes the issue, generates fix instructions, and di
|
|
|
12
12
|
|
|
13
13
|
Industries: live events, construction, hospitality, warehousing, property management, healthcare, aviation, FEMA disaster response, and more.
|
|
14
14
|
|
|
15
|
-
**
|
|
15
|
+
**10 Provisional Patents Filed** — 265 claims, ~1000+ pages of specification. USPTO Applications #63/995,189 through #64/001,286.
|
|
16
16
|
|
|
17
17
|
## Quickest Start: Claude.ai / Claude Mobile
|
|
18
18
|
|
|
@@ -83,7 +83,7 @@ https://app.tascan.io/mcp
|
|
|
83
83
|
|
|
84
84
|
Add as a custom connector in Claude (Settings > Connectors). When you first use a tool, you'll be redirected to sign in with your TaScan email and password — just like connecting GitHub or Netlify. OAuth 2.0 with PKCE handles everything automatically.
|
|
85
85
|
|
|
86
|
-
## Tools (
|
|
86
|
+
## Tools (32)
|
|
87
87
|
|
|
88
88
|
### Projects
|
|
89
89
|
| Tool | Description | Type |
|
|
@@ -133,9 +133,22 @@ Add as a custom connector in Claude (Settings > Connectors). When you first use
|
|
|
133
133
|
| `tascan_list_issues` | List field-reported issues with filtering by status, category, severity | Read |
|
|
134
134
|
| `tascan_analyze_issue` | AI classifies issue severity, identifies root cause, and scores urgency | AI |
|
|
135
135
|
| `tascan_recommend_fix` | AI generates ranked remediation tasks with step-by-step instructions | AI |
|
|
136
|
-
| `tascan_dispatch_instruction` | Multi-channel delivery of fix instructions to workers (SMS, push, QR) | Create |
|
|
137
136
|
| `tascan_auto_resolve` | Full closed loop in ONE call — issue in, AI analyzes, fix dispatched, loop closes | AI |
|
|
138
137
|
|
|
138
|
+
### Communications
|
|
139
|
+
| Tool | Description | Type |
|
|
140
|
+
|------|-------------|------|
|
|
141
|
+
| `tascan_dispatch_instruction` | Multi-channel delivery of instructions to workers (SMS, email, QR) | Create |
|
|
142
|
+
| `tascan_send_task_email` | Send task links and notifications via email | Create |
|
|
143
|
+
| `tascan_complete_task` | Mark a task as completed with optional response data | Update |
|
|
144
|
+
|
|
145
|
+
### AI Agent Coordination (Patent #10)
|
|
146
|
+
| Tool | Description | Type |
|
|
147
|
+
|------|-------------|------|
|
|
148
|
+
| `tascan_list_agents` | List registered AI agents in the system | Read |
|
|
149
|
+
| `tascan_register_agent` | Register a new AI agent with capabilities | Create |
|
|
150
|
+
| `tascan_dispatch_to_agent` | Route a task to a specific AI agent for execution | Create |
|
|
151
|
+
|
|
139
152
|
## Usage Examples
|
|
140
153
|
|
|
141
154
|
### Example 1: Set up a construction site inspection
|
|
@@ -213,6 +226,33 @@ Tasks can also be flagged as:
|
|
|
213
226
|
|
|
214
227
|
API keys are scoped to your organization and support rate limiting (60 requests/minute).
|
|
215
228
|
|
|
229
|
+
## Troubleshooting
|
|
230
|
+
|
|
231
|
+
**"Connection failed" or OAuth redirect issues**
|
|
232
|
+
- Verify you're using the correct URL: `https://app.tascan.io/mcp`
|
|
233
|
+
- Clear your browser cache and try reconnecting
|
|
234
|
+
- If using Claude Desktop, restart the app after adding the connector
|
|
235
|
+
|
|
236
|
+
**"Unauthorized" or 401 errors (local npm install)**
|
|
237
|
+
- Regenerate your API key in Admin Portal > Team > API Keys
|
|
238
|
+
- Confirm `TASCAN_API_KEY` is set in your environment (not just in the config file)
|
|
239
|
+
- Keys are organization-scoped — make sure you're using a key from the correct org
|
|
240
|
+
|
|
241
|
+
**Tools not showing up in Claude**
|
|
242
|
+
- Disconnect and reconnect the TaScan connector
|
|
243
|
+
- For Claude Code: run `claude mcp list` to verify the server is registered
|
|
244
|
+
- Check that your TaScan account has an active organization (free tier is fine)
|
|
245
|
+
|
|
246
|
+
**"Rate limited" errors**
|
|
247
|
+
- Default limit is 60 requests/minute per API key
|
|
248
|
+
- Pro and Business tiers have higher limits
|
|
249
|
+
- Batch operations (like `tascan_add_tasks`) are more efficient than individual calls
|
|
250
|
+
|
|
251
|
+
**Task completions not appearing**
|
|
252
|
+
- Workers must submit via the task link (QR scan or direct URL)
|
|
253
|
+
- Photo-required tasks won't show as complete until the photo uploads
|
|
254
|
+
- Check the event's response mode (single vs. multi-response)
|
|
255
|
+
|
|
216
256
|
## Privacy Policy
|
|
217
257
|
|
|
218
258
|
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
|
@@ -46,7 +46,7 @@ async function apiCall(method, path, body) {
|
|
|
46
46
|
// ─── Server Setup ──────────────────────────────────────────
|
|
47
47
|
const server = new McpServer({
|
|
48
48
|
name: 'tascan',
|
|
49
|
-
version: '2.
|
|
49
|
+
version: '2.4.0'
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
|
|
@@ -860,6 +860,94 @@ server.registerTool(
|
|
|
860
860
|
);
|
|
861
861
|
|
|
862
862
|
|
|
863
|
+
// ─── NFC Tag Registry ─────────────────────────────────────
|
|
864
|
+
|
|
865
|
+
// Tool 28: Register NFC Tag
|
|
866
|
+
server.registerTool(
|
|
867
|
+
'tascan_register_tag',
|
|
868
|
+
{
|
|
869
|
+
title: 'Register NFC Tag',
|
|
870
|
+
description: 'Register a physical NFC tag to a project, task list, or specific task. When someone taps the tag, TaScan routes them to the linked resource. Tags use NTAG215 chips and are programmed with NFC Tools Pro.',
|
|
871
|
+
inputSchema: {
|
|
872
|
+
tag_hardware_id: z.string().describe('NFC tag hardware serial number (e.g., "04:CB:6C:51:CE:2A:81")'),
|
|
873
|
+
tag_name: z.string().describe('Friendly name (e.g., "Ballroom A Door", "Breaker Panel 3")'),
|
|
874
|
+
target_type: z.enum(['project', 'task_list', 'task']).describe('What this tag points to'),
|
|
875
|
+
project_id: z.string().optional().describe('Project ID'),
|
|
876
|
+
task_list_id: z.string().optional().describe('Task list ID (required for task_list/task targets)'),
|
|
877
|
+
task_id: z.string().optional().describe('Task ID (required for task targets)'),
|
|
878
|
+
location_description: z.string().optional().describe('Physical location of the tag')
|
|
879
|
+
},
|
|
880
|
+
annotations: { readOnlyHint: false, destructiveHint: false }
|
|
881
|
+
},
|
|
882
|
+
async ({ tag_hardware_id, tag_name, target_type, project_id, task_list_id, task_id, location_description }) => {
|
|
883
|
+
const result = await apiCall('POST', '/tags', {
|
|
884
|
+
tag_hardware_id, tag_name, target_type, project_id, task_list_id, task_id, location_description
|
|
885
|
+
});
|
|
886
|
+
const d = result.data;
|
|
887
|
+
const nfcUrl = 'https://app.tascan.io/scan?tag={TAG-ID}&time={DATETIME}';
|
|
888
|
+
return {
|
|
889
|
+
content: [{
|
|
890
|
+
type: 'text',
|
|
891
|
+
text: `Tag registered: "${d.tag_name}" (${d.tag_hardware_id})\nTarget: ${d.target_type}\nID: ${d.id}\n\nProgram the NFC tag with this URL:\n${nfcUrl}\n\n${JSON.stringify(d, null, 2)}`
|
|
892
|
+
}]
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
// Tool 29: List Tags
|
|
898
|
+
server.registerTool(
|
|
899
|
+
'tascan_list_tags',
|
|
900
|
+
{
|
|
901
|
+
title: 'List NFC Tags',
|
|
902
|
+
description: 'List all registered NFC tags in the organization with their linked projects/task lists and scan counts',
|
|
903
|
+
inputSchema: {},
|
|
904
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
905
|
+
},
|
|
906
|
+
async () => {
|
|
907
|
+
const result = await apiCall('GET', '/tags');
|
|
908
|
+
const tags = result.data;
|
|
909
|
+
if (!tags.length) return { content: [{ type: 'text', text: 'No NFC tags registered.' }] };
|
|
910
|
+
let text = `${tags.length} tag(s) registered:\n\n`;
|
|
911
|
+
tags.forEach((t, i) => {
|
|
912
|
+
text += `${i+1}. "${t.tag_name}" — ${t.tag_hardware_id}\n`;
|
|
913
|
+
text += ` Target: ${t.target_type} | Scans: ${t.scan_count} | Active: ${t.is_active}\n`;
|
|
914
|
+
if (t.projects) text += ` Project: ${t.projects.name}\n`;
|
|
915
|
+
if (t.task_lists) text += ` Task List: ${t.task_lists.name}\n`;
|
|
916
|
+
if (t.location_description) text += ` Location: ${t.location_description}\n`;
|
|
917
|
+
text += '\n';
|
|
918
|
+
});
|
|
919
|
+
return { content: [{ type: 'text', text }] };
|
|
920
|
+
}
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
// Tool 30: Get Scan History
|
|
924
|
+
server.registerTool(
|
|
925
|
+
'tascan_get_scan_history',
|
|
926
|
+
{
|
|
927
|
+
title: 'Get Scan History',
|
|
928
|
+
description: 'Get scan event history for a registered NFC tag — timestamps, GPS coordinates, and accuracy for each scan',
|
|
929
|
+
inputSchema: {
|
|
930
|
+
tag_id: z.string().describe('Tag registry ID (from tascan_list_tags)'),
|
|
931
|
+
limit: z.number().optional().describe('Max results (default 50)')
|
|
932
|
+
},
|
|
933
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
934
|
+
},
|
|
935
|
+
async ({ tag_id, limit }) => {
|
|
936
|
+
const path = `/tags/${tag_id}/scans` + (limit ? `?limit=${limit}` : '');
|
|
937
|
+
const result = await apiCall('GET', path);
|
|
938
|
+
const scans = result.data;
|
|
939
|
+
if (!scans.length) return { content: [{ type: 'text', text: 'No scans recorded for this tag.' }] };
|
|
940
|
+
let text = `${scans.length} scan(s):\n\n`;
|
|
941
|
+
scans.forEach((s, i) => {
|
|
942
|
+
text += `${i+1}. ${s.scanned_at}`;
|
|
943
|
+
if (s.gps_lat && s.gps_lng) text += ` — GPS: ${s.gps_lat.toFixed(6)}, ${s.gps_lng.toFixed(6)} (±${Math.round(s.gps_accuracy || 0)}m)`;
|
|
944
|
+
text += '\n';
|
|
945
|
+
});
|
|
946
|
+
return { content: [{ type: 'text', text }] };
|
|
947
|
+
}
|
|
948
|
+
);
|
|
949
|
+
|
|
950
|
+
|
|
863
951
|
// ─── Start Server ──────────────────────────────────────────
|
|
864
952
|
async function main() {
|
|
865
953
|
const transport = new StdioServerTransport();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tascan-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"mcpName": "io.github.snowbikemike/tascan-mcp",
|
|
5
|
-
"description": "TaScan MCP Server — Closed-loop autonomous operations protocol.
|
|
5
|
+
"description": "TaScan MCP Server — Closed-loop autonomous operations protocol. 30 tools for projects, tasks, workers, QR codes, NFC tag registry, scan verification, AI issue analysis, and autonomous remediation dispatch. 12 patents filed (335+ claims). Task. Scan. Done.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"bin": {
|