@withpica/mcp-server 2.47.0 → 2.49.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/CHANGELOG.md +50 -0
- package/dist/apps/generated/shared-bundle.d.ts +1 -1
- package/dist/apps/generated/shared-bundle.d.ts.map +1 -1
- package/dist/apps/generated/shared-bundle.js +1 -1
- package/dist/apps/generated/shared-bundle.js.map +1 -1
- package/dist/prompts/creator-question-atlas.d.ts +48 -0
- package/dist/prompts/creator-question-atlas.d.ts.map +1 -0
- package/dist/prompts/creator-question-atlas.js +586 -0
- package/dist/prompts/creator-question-atlas.js.map +1 -0
- package/dist/prompts/index.d.ts +32 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +235 -0
- package/dist/prompts/index.js.map +1 -1
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +108 -10
- package/dist/server.js.map +1 -1
- package/dist/tools/agent-identity.d.ts.map +1 -1
- package/dist/tools/agent-identity.js +15 -0
- package/dist/tools/agent-identity.js.map +1 -1
- package/dist/tools/agreement-types.d.ts.map +1 -1
- package/dist/tools/agreement-types.js +25 -1
- package/dist/tools/agreement-types.js.map +1 -1
- package/dist/tools/agreements.d.ts.map +1 -1
- package/dist/tools/agreements.js +22 -4
- package/dist/tools/agreements.js.map +1 -1
- package/dist/tools/analytics.d.ts.map +1 -1
- package/dist/tools/analytics.js +19 -1
- package/dist/tools/analytics.js.map +1 -1
- package/dist/tools/app-tools.d.ts.map +1 -1
- package/dist/tools/app-tools.js +13 -4
- package/dist/tools/app-tools.js.map +1 -1
- package/dist/tools/assets.d.ts.map +1 -1
- package/dist/tools/assets.js +73 -14
- package/dist/tools/assets.js.map +1 -1
- package/dist/tools/audio-files.d.ts +5 -0
- package/dist/tools/audio-files.d.ts.map +1 -1
- package/dist/tools/audio-files.js +94 -3
- package/dist/tools/audio-files.js.map +1 -1
- package/dist/tools/audit.d.ts.map +1 -1
- package/dist/tools/audit.js +11 -2
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +6 -0
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/bulk.d.ts.map +1 -1
- package/dist/tools/bulk.js +8 -2
- package/dist/tools/bulk.js.map +1 -1
- package/dist/tools/calendar.d.ts.map +1 -1
- package/dist/tools/calendar.js +3 -0
- package/dist/tools/calendar.js.map +1 -1
- package/dist/tools/collaborators.d.ts.map +1 -1
- package/dist/tools/collaborators.js +29 -8
- package/dist/tools/collaborators.js.map +1 -1
- package/dist/tools/comparisons.d.ts.map +1 -1
- package/dist/tools/comparisons.js +6 -0
- package/dist/tools/comparisons.js.map +1 -1
- package/dist/tools/credits.d.ts +18 -0
- package/dist/tools/credits.d.ts.map +1 -1
- package/dist/tools/credits.js +347 -7
- package/dist/tools/credits.js.map +1 -1
- package/dist/tools/custody.d.ts.map +1 -1
- package/dist/tools/custody.js +23 -2
- package/dist/tools/custody.js.map +1 -1
- package/dist/tools/dashboard.d.ts.map +1 -1
- package/dist/tools/dashboard.js +43 -7
- package/dist/tools/dashboard.js.map +1 -1
- package/dist/tools/directory.d.ts.map +1 -1
- package/dist/tools/directory.js +3 -0
- package/dist/tools/directory.js.map +1 -1
- package/dist/tools/discovery.d.ts.map +1 -1
- package/dist/tools/discovery.js +81 -2
- package/dist/tools/discovery.js.map +1 -1
- package/dist/tools/disputes.d.ts.map +1 -1
- package/dist/tools/disputes.js +4 -1
- package/dist/tools/disputes.js.map +1 -1
- package/dist/tools/documents.d.ts.map +1 -1
- package/dist/tools/documents.js +3 -0
- package/dist/tools/documents.js.map +1 -1
- package/dist/tools/duplicates.d.ts.map +1 -1
- package/dist/tools/duplicates.js +6 -0
- package/dist/tools/duplicates.js.map +1 -1
- package/dist/tools/enrichment.d.ts.map +1 -1
- package/dist/tools/enrichment.js +46 -13
- package/dist/tools/enrichment.js.map +1 -1
- package/dist/tools/explainability.d.ts +24 -0
- package/dist/tools/explainability.d.ts.map +1 -0
- package/dist/tools/explainability.js +137 -0
- package/dist/tools/explainability.js.map +1 -0
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/exports.js +18 -3
- package/dist/tools/exports.js.map +1 -1
- package/dist/tools/feedback.d.ts.map +1 -1
- package/dist/tools/feedback.js +4 -1
- package/dist/tools/feedback.js.map +1 -1
- package/dist/tools/forbidden-keywords.d.ts +62 -0
- package/dist/tools/forbidden-keywords.d.ts.map +1 -0
- package/dist/tools/forbidden-keywords.js +99 -0
- package/dist/tools/forbidden-keywords.js.map +1 -0
- package/dist/tools/groups.d.ts.map +1 -1
- package/dist/tools/groups.js +12 -0
- package/dist/tools/groups.js.map +1 -1
- package/dist/tools/import-documents.d.ts.map +1 -1
- package/dist/tools/import-documents.js +10 -1
- package/dist/tools/import-documents.js.map +1 -1
- package/dist/tools/import.d.ts.map +1 -1
- package/dist/tools/import.js +36 -3
- package/dist/tools/import.js.map +1 -1
- package/dist/tools/index.d.ts +99 -4
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +171 -99
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/integrations.d.ts.map +1 -1
- package/dist/tools/integrations.js +28 -8
- package/dist/tools/integrations.js.map +1 -1
- package/dist/tools/labels.d.ts.map +1 -1
- package/dist/tools/labels.js +3 -0
- package/dist/tools/labels.js.map +1 -1
- package/dist/tools/licensing.d.ts.map +1 -1
- package/dist/tools/licensing.js +15 -0
- package/dist/tools/licensing.js.map +1 -1
- package/dist/tools/memory.d.ts.map +1 -1
- package/dist/tools/memory.js +15 -3
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +75 -25
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/multimedia.d.ts.map +1 -1
- package/dist/tools/multimedia.js +15 -0
- package/dist/tools/multimedia.js.map +1 -1
- package/dist/tools/my-recent-questions.d.ts +25 -0
- package/dist/tools/my-recent-questions.d.ts.map +1 -0
- package/dist/tools/my-recent-questions.js +186 -0
- package/dist/tools/my-recent-questions.js.map +1 -0
- package/dist/tools/my-reported-issues.d.ts.map +1 -1
- package/dist/tools/my-reported-issues.js +3 -0
- package/dist/tools/my-reported-issues.js.map +1 -1
- package/dist/tools/notes.d.ts.map +1 -1
- package/dist/tools/notes.js +12 -0
- package/dist/tools/notes.js.map +1 -1
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +28 -4
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/onboarding.d.ts.map +1 -1
- package/dist/tools/onboarding.js +3 -0
- package/dist/tools/onboarding.js.map +1 -1
- package/dist/tools/people.d.ts.map +1 -1
- package/dist/tools/people.js +21 -1
- package/dist/tools/people.js.map +1 -1
- package/dist/tools/projects.d.ts.map +1 -1
- package/dist/tools/projects.js +24 -7
- package/dist/tools/projects.js.map +1 -1
- package/dist/tools/public-filter.d.ts.map +1 -1
- package/dist/tools/public-filter.js +8 -36
- package/dist/tools/public-filter.js.map +1 -1
- package/dist/tools/publishers.d.ts.map +1 -1
- package/dist/tools/publishers.js +6 -0
- package/dist/tools/publishers.js.map +1 -1
- package/dist/tools/purchases.d.ts +11 -10
- package/dist/tools/purchases.d.ts.map +1 -1
- package/dist/tools/purchases.js.map +1 -1
- package/dist/tools/recordings.d.ts.map +1 -1
- package/dist/tools/recordings.js +90 -27
- package/dist/tools/recordings.js.map +1 -1
- package/dist/tools/recovery-hints.d.ts +26 -0
- package/dist/tools/recovery-hints.d.ts.map +1 -1
- package/dist/tools/recovery-hints.js +591 -0
- package/dist/tools/recovery-hints.js.map +1 -1
- package/dist/tools/release-rich.d.ts.map +1 -1
- package/dist/tools/release-rich.js +14 -8
- package/dist/tools/release-rich.js.map +1 -1
- package/dist/tools/releases.d.ts.map +1 -1
- package/dist/tools/releases.js +42 -0
- package/dist/tools/releases.js.map +1 -1
- package/dist/tools/report-issue.d.ts.map +1 -1
- package/dist/tools/report-issue.js +3 -0
- package/dist/tools/report-issue.js.map +1 -1
- package/dist/tools/royalties.d.ts.map +1 -1
- package/dist/tools/royalties.js +18 -3
- package/dist/tools/royalties.js.map +1 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +10 -1
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/send.d.ts.map +1 -1
- package/dist/tools/send.js +9 -0
- package/dist/tools/send.js.map +1 -1
- package/dist/tools/sessions.d.ts.map +1 -1
- package/dist/tools/sessions.js +12 -0
- package/dist/tools/sessions.js.map +1 -1
- package/dist/tools/settings.d.ts.map +1 -1
- package/dist/tools/settings.js +44 -18
- package/dist/tools/settings.js.map +1 -1
- package/dist/tools/share-links.d.ts.map +1 -1
- package/dist/tools/share-links.js +15 -0
- package/dist/tools/share-links.js.map +1 -1
- package/dist/tools/sharing.d.ts +29 -0
- package/dist/tools/sharing.d.ts.map +1 -0
- package/dist/tools/sharing.js +131 -0
- package/dist/tools/sharing.js.map +1 -0
- package/dist/tools/signup.d.ts.map +1 -1
- package/dist/tools/signup.js +4 -1
- package/dist/tools/signup.js.map +1 -1
- package/dist/tools/split-sheets.d.ts.map +1 -1
- package/dist/tools/split-sheets.js +23 -2
- package/dist/tools/split-sheets.js.map +1 -1
- package/dist/tools/storage-config.d.ts.map +1 -1
- package/dist/tools/storage-config.js +8 -2
- package/dist/tools/storage-config.js.map +1 -1
- package/dist/tools/subscription.d.ts.map +1 -1
- package/dist/tools/subscription.js +13 -16
- package/dist/tools/subscription.js.map +1 -1
- package/dist/tools/sync-placements.d.ts.map +1 -1
- package/dist/tools/sync-placements.js +22 -4
- package/dist/tools/sync-placements.js.map +1 -1
- package/dist/tools/team.d.ts.map +1 -1
- package/dist/tools/team.js +15 -0
- package/dist/tools/team.js.map +1 -1
- package/dist/tools/telegram.d.ts.map +1 -1
- package/dist/tools/telegram.js +9 -0
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/uploads.d.ts.map +1 -1
- package/dist/tools/uploads.js +6 -0
- package/dist/tools/uploads.js.map +1 -1
- package/dist/tools/works.d.ts.map +1 -1
- package/dist/tools/works.js +74 -25
- package/dist/tools/works.js.map +1 -1
- package/package.json +4 -4
- package/server.json +2 -2
- package/.claude/settings.local.json +0 -5
package/dist/tools/index.d.ts
CHANGED
|
@@ -40,8 +40,74 @@ export interface NextStepHint {
|
|
|
40
40
|
* lands so every tool is forced to declare its workflow at compile time.
|
|
41
41
|
*/
|
|
42
42
|
export type WorkflowTag = "work-required" | "recording-required" | "work-credits-required" | "recording-credits-required" | "person-required" | "audio-upload-required" | "enrichment-resolve-required" | "agreement-required" | "multimedia-required" | "export-required" | "claim-required" | "session-required" | "split-sheet-required" | "recording-splits-required" | "sync-placement-required" | "infrastructure";
|
|
43
|
+
/**
|
|
44
|
+
* ADR-226 Decision 2 — vernacular intent posture for every tool.
|
|
45
|
+
*
|
|
46
|
+
* - `creator-entry` — Atlas covers it; `Use when the user asks: '...'` block
|
|
47
|
+
* in the description is required (Phase 7 lint enforces).
|
|
48
|
+
* - `internal` — programmatic handoff between tools (e.g. presigned-PUT
|
|
49
|
+
* finalize step). Requires a one-line `vernacular_reason`.
|
|
50
|
+
* - `specialist` — mutating / destructive / not-yet-covered context;
|
|
51
|
+
* invoked by exact name. Requires a one-line `vernacular_reason`.
|
|
52
|
+
*
|
|
53
|
+
* Universal coverage: every tool declares its kind. Phase 7 lint promotes
|
|
54
|
+
* the field to a required-with-blocking check; Phase 3 (this commit)
|
|
55
|
+
* leaves it optional during the bulk-classification ramp and flips it to
|
|
56
|
+
* required in the same commit once all 244 tools have been populated by
|
|
57
|
+
* `scripts/bulk-classify-vernacular-kind.ts`.
|
|
58
|
+
*/
|
|
59
|
+
export type VernacularKind = "creator-entry" | "internal" | "specialist";
|
|
60
|
+
/**
|
|
61
|
+
* ADR-230 — authority tier declared on every tool definition.
|
|
62
|
+
*
|
|
63
|
+
* - `read` — pure query, no state mutation. Maps to readOnlyHint:true,
|
|
64
|
+
* risk_level:"safe", required scope `read:*` (or `write:*`
|
|
65
|
+
* via the read-implies-write rule in `hasScope`).
|
|
66
|
+
* - `draft` — produces a proposal/preview/hint without persisting
|
|
67
|
+
* state. Same hints as `write` (readOnlyHint:false,
|
|
68
|
+
* risk_level:"mutating"). No confirmation token.
|
|
69
|
+
* - `write` — persistent state change. May opt into per-tool
|
|
70
|
+
* confirmation via `previewMode: "two_step_token"`.
|
|
71
|
+
* - `destructive` — irreversible state change (delete / merge / send
|
|
72
|
+
* broadcast / disconnect). destructiveHint:true,
|
|
73
|
+
* risk_level:"destructive", confirmation token required,
|
|
74
|
+
* requires elevated `destructive:*` scope (admin satisfies).
|
|
75
|
+
*
|
|
76
|
+
* The 4-value `tier` is PICA's authority surface. The 3-value `risk_level`
|
|
77
|
+
* on `mcp_audit_log` is derived from `tier` (read→safe, draft|write→mutating,
|
|
78
|
+
* destructive→destructive) — sister of the MCP-standard `readOnlyHint` /
|
|
79
|
+
* `destructiveHint` fields, kept for ADR-199 client compatibility.
|
|
80
|
+
*/
|
|
81
|
+
export type Tier = "read" | "draft" | "write" | "destructive";
|
|
82
|
+
/**
|
|
83
|
+
* ADR-230 — derive the MCP-standard 3-value risk classification from the
|
|
84
|
+
* declared tier. Sourced once at registration and at audit-write time so
|
|
85
|
+
* the contract that hints, audit row, and confirmation requirement all
|
|
86
|
+
* agree is mechanical.
|
|
87
|
+
*/
|
|
88
|
+
export declare function tierToRiskLevel(tier: Tier): "safe" | "mutating" | "destructive";
|
|
89
|
+
/**
|
|
90
|
+
* ADR-230 — derive the required API-key scope from the declared tier.
|
|
91
|
+
*
|
|
92
|
+
* - `read` → `read:<resource>` (write:* satisfies via `hasScope`).
|
|
93
|
+
* - `draft|write` → `write:<resource>`.
|
|
94
|
+
* - `destructive` → `destructive:*` (admin satisfies via `hasScope`); the
|
|
95
|
+
* write:<resource> scope is also required for the
|
|
96
|
+
* underlying write surface.
|
|
97
|
+
*
|
|
98
|
+
* Returns the *additional* scope tier beyond per-resource. Resource scope
|
|
99
|
+
* is composed at call-site by `lib/services/mcp-scopes.ts`.
|
|
100
|
+
*/
|
|
101
|
+
export declare function tierToScopeKind(tier: Tier): "read" | "write" | "destructive";
|
|
43
102
|
export interface ToolDefinition {
|
|
44
103
|
name: string;
|
|
104
|
+
/**
|
|
105
|
+
* ADR-230 — authority tier. Required for every customer-facing tool.
|
|
106
|
+
* Sourced from per-tool declaration; drives MCP hints, audit-log
|
|
107
|
+
* `risk_level`, confirmation-token requirement, and required scope.
|
|
108
|
+
* See {@link Tier} above for semantics.
|
|
109
|
+
*/
|
|
110
|
+
tier: Tier;
|
|
45
111
|
description: string;
|
|
46
112
|
/**
|
|
47
113
|
* ADR-214 — workflow(s) this tool belongs to. See `WorkflowTag` above.
|
|
@@ -50,6 +116,21 @@ export interface ToolDefinition {
|
|
|
50
116
|
* part of any user-facing workflow.
|
|
51
117
|
*/
|
|
52
118
|
workflows: WorkflowTag | WorkflowTag[];
|
|
119
|
+
/**
|
|
120
|
+
* ADR-226 Decision 2 — vernacular intent posture. See `VernacularKind`
|
|
121
|
+
* above. Optional during Phase 3 ramp; Phase 7 lint flips it to a
|
|
122
|
+
* required-with-blocking check once every tool is populated.
|
|
123
|
+
*/
|
|
124
|
+
vernacular_kind?: VernacularKind;
|
|
125
|
+
/**
|
|
126
|
+
* ADR-226 Decision 2 — required when `vernacular_kind` is `'internal'`
|
|
127
|
+
* or `'specialist'`. One-line documentation of why the tool is not a
|
|
128
|
+
* creator-vernacular entry point (e.g. "Invoked after presigned PUT
|
|
129
|
+
* completes" or "Specialist context; not yet covered by the Creator
|
|
130
|
+
* Question Atlas"). Phase 7 lint enforces presence on non-`creator-entry`
|
|
131
|
+
* kinds.
|
|
132
|
+
*/
|
|
133
|
+
vernacular_reason?: string;
|
|
53
134
|
inputSchema: {
|
|
54
135
|
type: string;
|
|
55
136
|
properties: Record<string, any>;
|
|
@@ -118,6 +199,16 @@ export interface ToolDefinition {
|
|
|
118
199
|
export type ToolCategory = "catalog" | "enrichment" | "business" | "discovery" | "media" | "comms" | "settings";
|
|
119
200
|
export interface ToolMetadata {
|
|
120
201
|
category: ToolCategory;
|
|
202
|
+
/**
|
|
203
|
+
* @deprecated ADR-230 — use the declared `tier` on the tool
|
|
204
|
+
* definition (`ToolDefinition.tier` — required by lint Rule 13) as
|
|
205
|
+
* the source of truth. `risk` is retained as a quiet fallback for
|
|
206
|
+
* the unlikely case of a tool that bypasses lint (legacy tolerance
|
|
207
|
+
* inside `ToolRegistry.listTools`) and to drive the
|
|
208
|
+
* `injectMetadataIntoDescription` annotations + `retry_safe` hints
|
|
209
|
+
* exposed via `getToolMetadata`. Do NOT add new consumers; route
|
|
210
|
+
* tier-aware logic through the tool definition's declared `tier`.
|
|
211
|
+
*/
|
|
121
212
|
risk: "safe" | "mutating" | "destructive";
|
|
122
213
|
retry_safe: boolean;
|
|
123
214
|
display_name: string;
|
|
@@ -196,10 +287,14 @@ export declare class ToolRegistry {
|
|
|
196
287
|
* Register all available tools
|
|
197
288
|
*/
|
|
198
289
|
private registerAllTools;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
290
|
+
/**
|
|
291
|
+
* ADR-230 — declared tier lookup by tool name. Used by the HTTP MCP
|
|
292
|
+
* dispatcher (`app/api/mcp/route.ts`) to enforce the elevated
|
|
293
|
+
* `destructive:*` scope on top of the resource-level scope from
|
|
294
|
+
* `lib/services/mcp-scopes`. Returns undefined for unknown tools or
|
|
295
|
+
* tools that haven't declared tier yet (legacy tolerance).
|
|
296
|
+
*/
|
|
297
|
+
getToolTier(name: string): Tier | undefined;
|
|
203
298
|
/**
|
|
204
299
|
* List all available tools with write-safety prefixes injected.
|
|
205
300
|
* When discoveryMode is enabled, only the 5 handshake-visible tools are returned.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -43,9 +43,12 @@ import { SubscriptionTools } from "./subscription.js";
|
|
|
43
43
|
import { OnboardingTools } from "./onboarding.js";
|
|
44
44
|
import { ReportIssueTools } from "./report-issue.js";
|
|
45
45
|
import { MyReportedIssuesTools } from "./my-reported-issues.js";
|
|
46
|
+
import { MyRecentQuestionsTools } from "./my-recent-questions.js";
|
|
46
47
|
import { AgentIdentityTools } from "./agent-identity.js";
|
|
47
48
|
import { RoyaltiesTools } from "./royalties.js";
|
|
48
49
|
import { ShareLinksTools } from "./share-links.js";
|
|
50
|
+
import { SharingTools } from "./sharing.js";
|
|
51
|
+
import { ExplainabilityTools } from "./explainability.js";
|
|
49
52
|
import { DisputesTools } from "./disputes.js";
|
|
50
53
|
import { CustodyTools } from "./custody.js";
|
|
51
54
|
import { PurchasesTools } from "./purchases.js";
|
|
@@ -65,6 +68,46 @@ import { getToolMetadata } from "./metadata.js";
|
|
|
65
68
|
import { getRecoveryHint } from "./recovery-hints.js";
|
|
66
69
|
import { generateConfirmationToken, validateAndConsumeToken, } from "@withpica/mcp-utils";
|
|
67
70
|
import { buildSessionState, incrementSessionMutations, resetSinceLastBriefing, } from "@withpica/mcp-utils";
|
|
71
|
+
/**
|
|
72
|
+
* ADR-230 — derive the MCP-standard 3-value risk classification from the
|
|
73
|
+
* declared tier. Sourced once at registration and at audit-write time so
|
|
74
|
+
* the contract that hints, audit row, and confirmation requirement all
|
|
75
|
+
* agree is mechanical.
|
|
76
|
+
*/
|
|
77
|
+
export function tierToRiskLevel(tier) {
|
|
78
|
+
switch (tier) {
|
|
79
|
+
case "read":
|
|
80
|
+
return "safe";
|
|
81
|
+
case "draft":
|
|
82
|
+
case "write":
|
|
83
|
+
return "mutating";
|
|
84
|
+
case "destructive":
|
|
85
|
+
return "destructive";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* ADR-230 — derive the required API-key scope from the declared tier.
|
|
90
|
+
*
|
|
91
|
+
* - `read` → `read:<resource>` (write:* satisfies via `hasScope`).
|
|
92
|
+
* - `draft|write` → `write:<resource>`.
|
|
93
|
+
* - `destructive` → `destructive:*` (admin satisfies via `hasScope`); the
|
|
94
|
+
* write:<resource> scope is also required for the
|
|
95
|
+
* underlying write surface.
|
|
96
|
+
*
|
|
97
|
+
* Returns the *additional* scope tier beyond per-resource. Resource scope
|
|
98
|
+
* is composed at call-site by `lib/services/mcp-scopes.ts`.
|
|
99
|
+
*/
|
|
100
|
+
export function tierToScopeKind(tier) {
|
|
101
|
+
switch (tier) {
|
|
102
|
+
case "read":
|
|
103
|
+
return "read";
|
|
104
|
+
case "draft":
|
|
105
|
+
case "write":
|
|
106
|
+
return "write";
|
|
107
|
+
case "destructive":
|
|
108
|
+
return "destructive";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
68
111
|
/**
|
|
69
112
|
* Build a tool description with metadata injected.
|
|
70
113
|
* Format: "[category] original description"
|
|
@@ -370,6 +413,21 @@ export class ToolRegistry {
|
|
|
370
413
|
myReportedIssuesTools.getTools().forEach((tool) => {
|
|
371
414
|
this.tools.set(tool.definition.name, tool);
|
|
372
415
|
});
|
|
416
|
+
// My-recent-questions tool (ADR-226 Phase 5 — pica_my_recent_questions)
|
|
417
|
+
// — user-scoped read of the Phase 4 substrate (assistant_interactions
|
|
418
|
+
// joined with mcp_sessions for client identity). Atlas-resolved entry
|
|
419
|
+
// for "what did I ask the AI?".
|
|
420
|
+
//
|
|
421
|
+
// ADR-230 post-ship cleanup — the tier resolver is the registry's
|
|
422
|
+
// own `getToolTier` shape (declared `tier` on each tool definition).
|
|
423
|
+
// Lint Rule 13 makes tier required for every customer MCP tool, so
|
|
424
|
+
// this resolver returns a populated value for all known tools and
|
|
425
|
+
// `undefined` only for unknown / meta tools — `dominantTier` falls
|
|
426
|
+
// back to "read" in that case.
|
|
427
|
+
const myRecentQuestionsTools = new MyRecentQuestionsTools(pica, (name) => this.tools.get(name)?.definition.tier);
|
|
428
|
+
myRecentQuestionsTools.getTools().forEach((tool) => {
|
|
429
|
+
this.tools.set(tool.definition.name, tool);
|
|
430
|
+
});
|
|
373
431
|
// Agent identity tools (ADR-185 Part 1 — session-auth-only MCP surface).
|
|
374
432
|
// The three tools refuse grant-auth callers at the HTTP API layer;
|
|
375
433
|
// the stdio path carries an API key so behaviour is identical either
|
|
@@ -388,6 +446,16 @@ export class ToolRegistry {
|
|
|
388
446
|
shareLinksTools.getTools().forEach((tool) => {
|
|
389
447
|
this.tools.set(tool.definition.name, tool);
|
|
390
448
|
});
|
|
449
|
+
// Sharing trace tool (ADR-232 § Decision 2)
|
|
450
|
+
const sharingTools = new SharingTools(pica);
|
|
451
|
+
sharingTools.getTools().forEach((tool) => {
|
|
452
|
+
this.tools.set(tool.definition.name, tool);
|
|
453
|
+
});
|
|
454
|
+
// Explainability tools (ADR-232 § Decision 3)
|
|
455
|
+
const explainabilityTools = new ExplainabilityTools(pica);
|
|
456
|
+
explainabilityTools.getTools().forEach((tool) => {
|
|
457
|
+
this.tools.set(tool.definition.name, tool);
|
|
458
|
+
});
|
|
391
459
|
// Disputes tools (ADR-139 Step 3)
|
|
392
460
|
const disputesTools = new DisputesTools(pica);
|
|
393
461
|
disputesTools.getTools().forEach((tool) => {
|
|
@@ -449,72 +517,15 @@ export class ToolRegistry {
|
|
|
449
517
|
});
|
|
450
518
|
}
|
|
451
519
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
"_disconnect",
|
|
462
|
-
];
|
|
463
|
-
static MUTATING_PATTERNS = [
|
|
464
|
-
"_create",
|
|
465
|
-
"_update",
|
|
466
|
-
"_bulk_update",
|
|
467
|
-
"_invite",
|
|
468
|
-
"_link",
|
|
469
|
-
"_send_",
|
|
470
|
-
"_import_",
|
|
471
|
-
"_execute",
|
|
472
|
-
"_ingest",
|
|
473
|
-
"_enrich",
|
|
474
|
-
"_verify",
|
|
475
|
-
"_mark_",
|
|
476
|
-
"_review",
|
|
477
|
-
"_purchase",
|
|
478
|
-
"_submit",
|
|
479
|
-
"_generate",
|
|
480
|
-
"_set_default",
|
|
481
|
-
"_duplicate",
|
|
482
|
-
"_toggle",
|
|
483
|
-
"_save",
|
|
484
|
-
"_upload",
|
|
485
|
-
"_complete",
|
|
486
|
-
"_analyze",
|
|
487
|
-
"_analyse",
|
|
488
|
-
"_identify",
|
|
489
|
-
"_resend",
|
|
490
|
-
"_notify",
|
|
491
|
-
];
|
|
492
|
-
// Read-only tools that match mutating patterns by name but are actually safe
|
|
493
|
-
static SAFE_OVERRIDES = new Set([
|
|
494
|
-
"pica_collaborators_invites_list",
|
|
495
|
-
"pica_enrichment_candidates",
|
|
496
|
-
"pica_enrichment_compare",
|
|
497
|
-
"pica_find_duplicates",
|
|
498
|
-
"pica_import_analyze",
|
|
499
|
-
"pica_import_validate",
|
|
500
|
-
"pica_import_fields",
|
|
501
|
-
"pica_import_template",
|
|
502
|
-
"pica_import_documents_query",
|
|
503
|
-
"pica_import_documents_inspect",
|
|
504
|
-
"pica_send_query",
|
|
505
|
-
"pica_share_links_list",
|
|
506
|
-
]);
|
|
507
|
-
classifyTool(name) {
|
|
508
|
-
if (ToolRegistry.SAFE_OVERRIDES.has(name)) {
|
|
509
|
-
return "safe";
|
|
510
|
-
}
|
|
511
|
-
if (ToolRegistry.DESTRUCTIVE_PATTERNS.some((p) => name.includes(p))) {
|
|
512
|
-
return "destructive";
|
|
513
|
-
}
|
|
514
|
-
if (ToolRegistry.MUTATING_PATTERNS.some((p) => name.includes(p))) {
|
|
515
|
-
return "mutating";
|
|
516
|
-
}
|
|
517
|
-
return "safe";
|
|
520
|
+
/**
|
|
521
|
+
* ADR-230 — declared tier lookup by tool name. Used by the HTTP MCP
|
|
522
|
+
* dispatcher (`app/api/mcp/route.ts`) to enforce the elevated
|
|
523
|
+
* `destructive:*` scope on top of the resource-level scope from
|
|
524
|
+
* `lib/services/mcp-scopes`. Returns undefined for unknown tools or
|
|
525
|
+
* tools that haven't declared tier yet (legacy tolerance).
|
|
526
|
+
*/
|
|
527
|
+
getToolTier(name) {
|
|
528
|
+
return this.tools.get(name)?.definition.tier;
|
|
518
529
|
}
|
|
519
530
|
/**
|
|
520
531
|
* List all available tools with write-safety prefixes injected.
|
|
@@ -536,9 +547,14 @@ export class ToolRegistry {
|
|
|
536
547
|
return toolsToList.map((tool) => {
|
|
537
548
|
let definition = tool.definition;
|
|
538
549
|
const metadata = getToolMetadata(definition.name);
|
|
539
|
-
//
|
|
540
|
-
|
|
541
|
-
|
|
550
|
+
// ADR-230 — declared tier is the source of truth for hints + risk.
|
|
551
|
+
// Lint Rule 13 enforces tier presence on every customer MCP tool;
|
|
552
|
+
// metadata.risk is a quiet fallback for the unlikely case of a tool
|
|
553
|
+
// that bypasses lint.
|
|
554
|
+
const declaredTier = definition.tier;
|
|
555
|
+
const isDestructive = declaredTier
|
|
556
|
+
? declaredTier === "destructive"
|
|
557
|
+
: metadata?.risk === "destructive";
|
|
542
558
|
if (isDestructive) {
|
|
543
559
|
definition = {
|
|
544
560
|
...definition,
|
|
@@ -566,6 +582,26 @@ export class ToolRegistry {
|
|
|
566
582
|
},
|
|
567
583
|
};
|
|
568
584
|
}
|
|
585
|
+
// ADR-230 — derive hints from declared tier when present (every
|
|
586
|
+
// tool registered in mcp-server/src/tools/*.ts has tier as of
|
|
587
|
+
// PR-1; the metadata branch stays as a defensive code path).
|
|
588
|
+
if (declaredTier && metadata) {
|
|
589
|
+
return {
|
|
590
|
+
...definition,
|
|
591
|
+
description: injectMetadataIntoDescription(tool.definition.description, metadata),
|
|
592
|
+
annotations: {
|
|
593
|
+
title: metadata.display_name,
|
|
594
|
+
readOnlyHint: declaredTier === "read",
|
|
595
|
+
destructiveHint: declaredTier === "destructive",
|
|
596
|
+
idempotentHint: declaredTier !== "destructive" && metadata.retry_safe,
|
|
597
|
+
openWorldHint: false,
|
|
598
|
+
// ADR-199 extended annotation classes — read by ChatGPT/Claude.ai
|
|
599
|
+
// connectors directly. Derived from declared tier so the four
|
|
600
|
+
// surfaces (hint, riskLevel, audit row, scope) all agree.
|
|
601
|
+
...this.deriveExtendedAnnotations(definition, metadata, undefined, declaredTier),
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
}
|
|
569
605
|
if (metadata) {
|
|
570
606
|
return {
|
|
571
607
|
...definition,
|
|
@@ -574,27 +610,27 @@ export class ToolRegistry {
|
|
|
574
610
|
title: metadata.display_name,
|
|
575
611
|
readOnlyHint: metadata.risk === "safe",
|
|
576
612
|
destructiveHint: metadata.risk === "destructive",
|
|
577
|
-
idempotentHint: metadata.risk
|
|
613
|
+
idempotentHint: metadata.risk !== "destructive" && metadata.retry_safe,
|
|
578
614
|
openWorldHint: false,
|
|
579
|
-
// ADR-199 extended annotation classes — read by ChatGPT/Claude.ai
|
|
580
|
-
// connectors directly. Derived from existing metadata so existing
|
|
581
|
-
// tools get this for free without per-tool edits.
|
|
582
615
|
...this.deriveExtendedAnnotations(definition, metadata),
|
|
583
616
|
},
|
|
584
617
|
};
|
|
585
618
|
}
|
|
586
|
-
//
|
|
587
|
-
|
|
619
|
+
// ADR-230 — tools without a TOOL_METADATA entry (the 5 lobby
|
|
620
|
+
// meta-tools — sign_in/out/discover/tool_details/execute) still
|
|
621
|
+
// declare tier. Source hints from declared tier; default to read
|
|
622
|
+
// when tier is somehow missing (lint blocks; defensive only).
|
|
623
|
+
const tierForHints = declaredTier ?? "read";
|
|
588
624
|
const annotations = {
|
|
589
625
|
title: definition.name,
|
|
590
|
-
readOnlyHint:
|
|
591
|
-
destructiveHint:
|
|
626
|
+
readOnlyHint: tierForHints === "read",
|
|
627
|
+
destructiveHint: tierForHints === "destructive",
|
|
592
628
|
idempotentHint: false,
|
|
593
629
|
openWorldHint: false,
|
|
594
|
-
// ADR-199: derive the extended classes
|
|
595
|
-
//
|
|
596
|
-
//
|
|
597
|
-
...this.deriveExtendedAnnotations(definition, null,
|
|
630
|
+
// ADR-199: derive the extended classes from declared tier so the
|
|
631
|
+
// category/risk surface stays aligned with the rest of the
|
|
632
|
+
// hint/audit/scope chain.
|
|
633
|
+
...this.deriveExtendedAnnotations(definition, null, undefined, tierForHints),
|
|
598
634
|
};
|
|
599
635
|
// No risk prefix needed — annotations handle this structurally
|
|
600
636
|
return { ...definition, annotations };
|
|
@@ -609,9 +645,16 @@ export class ToolRegistry {
|
|
|
609
645
|
* edits required for the retrofit. Future tool authors can override by
|
|
610
646
|
* setting fields directly on definition.annotations.
|
|
611
647
|
*/
|
|
612
|
-
deriveExtendedAnnotations(definition, metadata,
|
|
648
|
+
deriveExtendedAnnotations(definition, metadata, _classification, declaredTier) {
|
|
613
649
|
const name = definition.name;
|
|
614
|
-
|
|
650
|
+
// ADR-230 — declared tier is the source of truth. metadata.risk
|
|
651
|
+
// remains a quiet fallback for any tool that bypasses lint Rule 13.
|
|
652
|
+
// (The `_classification` parameter is retained as an unused
|
|
653
|
+
// positional slot so legacy call signatures continue to compile;
|
|
654
|
+
// its value is now ignored — classifyTool was removed in PR-3.)
|
|
655
|
+
const risk = declaredTier
|
|
656
|
+
? tierToRiskLevel(declaredTier)
|
|
657
|
+
: (metadata?.risk ?? "safe");
|
|
615
658
|
// Side-effecting external systems: telegram, send-hub, comms, broadcasts.
|
|
616
659
|
// Pattern-derived so new tools inherit without edits.
|
|
617
660
|
const externalSideEffectPatterns = [
|
|
@@ -631,10 +674,16 @@ export class ToolRegistry {
|
|
|
631
674
|
// the agent wants to confirm — the gap report flagged this as a useful
|
|
632
675
|
// class for ChatGPT to surface in the UI.
|
|
633
676
|
const requiresFollowUpInspection = risk === "mutating" || risk === "destructive";
|
|
677
|
+
// ADR-230 — destructive tier always requires confirmation. Other tiers
|
|
678
|
+
// never do via this annotation (per-tool opt-in for `write` tier is
|
|
679
|
+
// expressed through `previewMode: "two_step_token"`, not here).
|
|
680
|
+
const requiresConfirmation = declaredTier
|
|
681
|
+
? declaredTier === "destructive"
|
|
682
|
+
: risk === "destructive";
|
|
634
683
|
return {
|
|
635
684
|
riskLevel: risk,
|
|
636
685
|
category: metadata?.category,
|
|
637
|
-
requiresConfirmation
|
|
686
|
+
requiresConfirmation,
|
|
638
687
|
createsExternalSideEffects,
|
|
639
688
|
returnsPaginated,
|
|
640
689
|
requiresFollowUpInspection,
|
|
@@ -1011,10 +1060,22 @@ export class ToolRegistry {
|
|
|
1011
1060
|
throw new ToolExecutionError(`Tool not found: ${name}`);
|
|
1012
1061
|
}
|
|
1013
1062
|
const metadata = getToolMetadata(name);
|
|
1063
|
+
// ADR-230 — declared tier is the source of truth for the freshness +
|
|
1064
|
+
// confirmation gates and the audit-log surfaces. Fall back to
|
|
1065
|
+
// metadata.risk only if the tool somehow lacks tier (lint blocks
|
|
1066
|
+
// missing tier on creator + team + directory MCPs as of PR-2).
|
|
1067
|
+
const declaredTier = tool.definition.tier;
|
|
1068
|
+
const fallbackRisk = metadata?.risk ?? "safe";
|
|
1069
|
+
const auditTier = declaredTier ??
|
|
1070
|
+
(fallbackRisk === "safe"
|
|
1071
|
+
? "read"
|
|
1072
|
+
: fallbackRisk === "destructive"
|
|
1073
|
+
? "destructive"
|
|
1074
|
+
: "write");
|
|
1075
|
+
const auditRiskLevel = tierToRiskLevel(auditTier);
|
|
1076
|
+
const isDestructive = auditTier === "destructive";
|
|
1014
1077
|
// ── Session freshness gate (ADR-151) ──
|
|
1015
|
-
if (
|
|
1016
|
-
this.config &&
|
|
1017
|
-
!this.config.lobbyMode) {
|
|
1078
|
+
if (isDestructive && this.config && !this.config.lobbyMode) {
|
|
1018
1079
|
const creds = readCredentials(this.config.credentialsPath);
|
|
1019
1080
|
if (creds?.authenticated_at) {
|
|
1020
1081
|
const authAge = Date.now() - new Date(creds.authenticated_at).getTime();
|
|
@@ -1032,12 +1093,15 @@ export class ToolRegistry {
|
|
|
1032
1093
|
}
|
|
1033
1094
|
}
|
|
1034
1095
|
}
|
|
1035
|
-
// ── Destructive confirmation gate ──
|
|
1036
|
-
if (
|
|
1096
|
+
// ── Destructive confirmation gate (ADR-230 — keyed on declared tier) ──
|
|
1097
|
+
if (isDestructive) {
|
|
1037
1098
|
const confirmationToken = args.confirmation_token;
|
|
1038
1099
|
if (!confirmationToken) {
|
|
1039
|
-
// First call — generate preview and return confirmation challenge
|
|
1040
|
-
|
|
1100
|
+
// First call — generate preview and return confirmation challenge.
|
|
1101
|
+
// ADR-230 PR-4 — token state lives in Postgres for HTTP MCP under
|
|
1102
|
+
// Fluid Compute (or in-memory for stdio); both paths via the
|
|
1103
|
+
// active ConfirmationStore singleton, so callers stay unchanged.
|
|
1104
|
+
const token = await generateConfirmationToken(name, args);
|
|
1041
1105
|
const preview = await this.buildDestructivePreview(name, args);
|
|
1042
1106
|
const response = {
|
|
1043
1107
|
content: [
|
|
@@ -1063,6 +1127,7 @@ export class ToolRegistry {
|
|
|
1063
1127
|
?.logToolExecution({
|
|
1064
1128
|
tool_name: name,
|
|
1065
1129
|
tool_category: metadata?.category || "unknown",
|
|
1130
|
+
tier: "destructive",
|
|
1066
1131
|
risk_level: "destructive",
|
|
1067
1132
|
parameters: this.sanitizeParams(args),
|
|
1068
1133
|
result_status: "confirmation_required",
|
|
@@ -1074,8 +1139,9 @@ export class ToolRegistry {
|
|
|
1074
1139
|
.catch(() => { }); // Never block on audit
|
|
1075
1140
|
return response;
|
|
1076
1141
|
}
|
|
1077
|
-
// Second call — validate token
|
|
1078
|
-
|
|
1142
|
+
// Second call — validate token (Postgres-backed under Fluid Compute
|
|
1143
|
+
// since ADR-230 PR-4; the active store handles cross-instance state).
|
|
1144
|
+
const validation = await validateAndConsumeToken(confirmationToken, name, args);
|
|
1079
1145
|
if (!validation.valid) {
|
|
1080
1146
|
return {
|
|
1081
1147
|
content: [
|
|
@@ -1108,10 +1174,10 @@ export class ToolRegistry {
|
|
|
1108
1174
|
}
|
|
1109
1175
|
}
|
|
1110
1176
|
// ADR-208 Primitive B — ambient session-state on write-tool results.
|
|
1111
|
-
// Read tools (`
|
|
1112
|
-
//
|
|
1113
|
-
//
|
|
1114
|
-
const isWriteTool =
|
|
1177
|
+
// Read tools (`tier: "read"`) skip this entirely so the high-volume
|
|
1178
|
+
// read path stays cheap. `result.isError === true` also skips because
|
|
1179
|
+
// a failed mutation didn't change catalog state.
|
|
1180
|
+
const isWriteTool = auditRiskLevel !== "safe";
|
|
1115
1181
|
if (isWriteTool && result && !result.isError) {
|
|
1116
1182
|
await this.attachSessionState(result, name);
|
|
1117
1183
|
}
|
|
@@ -1137,7 +1203,8 @@ export class ToolRegistry {
|
|
|
1137
1203
|
?.logToolExecution({
|
|
1138
1204
|
tool_name: name,
|
|
1139
1205
|
tool_category: metadata?.category || "unknown",
|
|
1140
|
-
|
|
1206
|
+
tier: auditTier,
|
|
1207
|
+
risk_level: auditRiskLevel,
|
|
1141
1208
|
parameters: this.sanitizeParams(args),
|
|
1142
1209
|
result_status: "success",
|
|
1143
1210
|
execution_time_ms: Date.now() - startTime,
|
|
@@ -1163,10 +1230,15 @@ export class ToolRegistry {
|
|
|
1163
1230
|
?.logToolExecution({
|
|
1164
1231
|
tool_name: name,
|
|
1165
1232
|
tool_category: metadata?.category || "unknown",
|
|
1166
|
-
|
|
1233
|
+
tier: auditTier,
|
|
1234
|
+
risk_level: auditRiskLevel,
|
|
1167
1235
|
parameters: this.sanitizeParams(args),
|
|
1168
1236
|
result_status: "error",
|
|
1169
1237
|
error_code: parsed.error,
|
|
1238
|
+
// Stage A — forward the parsed body's message so mcp_audit_log
|
|
1239
|
+
// captures the underlying cause. Without this every error row had
|
|
1240
|
+
// error_message=null, leaving UNKNOWN_ERROR rows opaque.
|
|
1241
|
+
error_message: typeof parsed.message === "string" ? parsed.message : undefined,
|
|
1170
1242
|
execution_time_ms: Date.now() - startTime,
|
|
1171
1243
|
caller_identity: this.callerContext.callerIdentity,
|
|
1172
1244
|
transport: this.callerContext.transport,
|