@withpica/mcp-server 2.98.0 → 2.99.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +4 -4
  3. package/dist/lib/changelog.generated.d.ts +2 -2
  4. package/dist/lib/changelog.generated.d.ts.map +1 -1
  5. package/dist/lib/changelog.generated.js +2 -2
  6. package/dist/lib/changelog.generated.js.map +1 -1
  7. package/dist/prompts/creator-question-atlas.d.ts.map +1 -1
  8. package/dist/prompts/creator-question-atlas.js +14 -2
  9. package/dist/prompts/creator-question-atlas.js.map +1 -1
  10. package/dist/prompts/index.js +1 -1
  11. package/dist/resources/index.d.ts.map +1 -1
  12. package/dist/resources/index.js +0 -3
  13. package/dist/resources/index.js.map +1 -1
  14. package/dist/resources/required-schemas.generated.d.ts +1 -1
  15. package/dist/resources/required-schemas.generated.d.ts.map +1 -1
  16. package/dist/resources/required-schemas.generated.js +1 -0
  17. package/dist/resources/required-schemas.generated.js.map +1 -1
  18. package/dist/skills/skills.generated.js +6 -6
  19. package/dist/skills/skills.generated.js.map +1 -1
  20. package/dist/tools/collaborators.d.ts.map +1 -1
  21. package/dist/tools/collaborators.js +27 -3
  22. package/dist/tools/collaborators.js.map +1 -1
  23. package/dist/tools/credits.d.ts +4 -1
  24. package/dist/tools/credits.d.ts.map +1 -1
  25. package/dist/tools/credits.js +6 -93
  26. package/dist/tools/credits.js.map +1 -1
  27. package/dist/tools/deprecations.d.ts +65 -7
  28. package/dist/tools/deprecations.d.ts.map +1 -1
  29. package/dist/tools/deprecations.js +96 -96
  30. package/dist/tools/deprecations.js.map +1 -1
  31. package/dist/tools/discovery.d.ts +28 -2
  32. package/dist/tools/discovery.d.ts.map +1 -1
  33. package/dist/tools/discovery.js +61 -27
  34. package/dist/tools/discovery.js.map +1 -1
  35. package/dist/tools/documents.d.ts +2 -2
  36. package/dist/tools/documents.d.ts.map +1 -1
  37. package/dist/tools/documents.js +2 -88
  38. package/dist/tools/documents.js.map +1 -1
  39. package/dist/tools/duplicates.d.ts +2 -0
  40. package/dist/tools/duplicates.d.ts.map +1 -1
  41. package/dist/tools/duplicates.js +107 -0
  42. package/dist/tools/duplicates.js.map +1 -1
  43. package/dist/tools/integrity.d.ts.map +1 -1
  44. package/dist/tools/integrity.js +65 -8
  45. package/dist/tools/integrity.js.map +1 -1
  46. package/dist/tools/metadata.d.ts.map +1 -1
  47. package/dist/tools/metadata.js +41 -121
  48. package/dist/tools/metadata.js.map +1 -1
  49. package/dist/tools/notes.d.ts +3 -4
  50. package/dist/tools/notes.d.ts.map +1 -1
  51. package/dist/tools/notes.js +3 -39
  52. package/dist/tools/notes.js.map +1 -1
  53. package/dist/tools/projects.d.ts +3 -4
  54. package/dist/tools/projects.d.ts.map +1 -1
  55. package/dist/tools/projects.js +3 -27
  56. package/dist/tools/projects.js.map +1 -1
  57. package/dist/tools/public-filter.d.ts.map +1 -1
  58. package/dist/tools/public-filter.js +3 -6
  59. package/dist/tools/public-filter.js.map +1 -1
  60. package/dist/tools/recovery-hints.d.ts.map +1 -1
  61. package/dist/tools/recovery-hints.js +24 -23
  62. package/dist/tools/recovery-hints.js.map +1 -1
  63. package/dist/tools/releases.d.ts +2 -4
  64. package/dist/tools/releases.d.ts.map +1 -1
  65. package/dist/tools/releases.js +6 -210
  66. package/dist/tools/releases.js.map +1 -1
  67. package/dist/tools/rights.d.ts +9 -0
  68. package/dist/tools/rights.d.ts.map +1 -1
  69. package/dist/tools/rights.js +196 -3
  70. package/dist/tools/rights.js.map +1 -1
  71. package/dist/tools/royalties.d.ts +5 -5
  72. package/dist/tools/royalties.d.ts.map +1 -1
  73. package/dist/tools/royalties.js +2 -53
  74. package/dist/tools/royalties.js.map +1 -1
  75. package/dist/tools/statements.js +1 -1
  76. package/dist/tools/statements.js.map +1 -1
  77. package/dist/tools/version-guard.d.ts +16 -4
  78. package/dist/tools/version-guard.d.ts.map +1 -1
  79. package/dist/tools/version-guard.js +22 -8
  80. package/dist/tools/version-guard.js.map +1 -1
  81. package/dist/tools/works.d.ts.map +1 -1
  82. package/dist/tools/works.js +24 -11
  83. package/dist/tools/works.js.map +1 -1
  84. package/package.json +2 -2
  85. package/server.json +2 -2
@@ -1,6 +1,18 @@
1
1
  // Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
2
2
  /**
3
- * The one alias registry. Populated per-consolidation in later phases.
3
+ * The one alias registry. Populated per-consolidation; EMPTY as of
4
+ * mcp-server 2.99.0.
5
+ *
6
+ * REMOVAL (mcp-server 2.99.0, founder decision 2026-09-29): the last eleven
7
+ * aliases were removed — their entries here, their TOOL_METADATA mirrors,
8
+ * and any standalone ToolDefinitions that still sat beside the canonical
9
+ * tools. Prod `agent_events` over the 60 days to 2026-09-29: 4 calls in all
10
+ * (pica_recording_credits_bulk_update 2, last 08-17; pica_releases_get 1,
11
+ * 08-01; pica_royalties_summary 1, 09-14; the other eight zero). Calling any
12
+ * of them now gets TOOL_NOT_FOUND whose message names its replacement; the
13
+ * replacement also leads `did_you_mean` when the caller can call it. The
14
+ * name → replacement mapping is RETIRED_TOOLS below — the one copy.
15
+ * The dated notes below are the history of how that deadline moved.
4
16
  *
5
17
  * REMOVAL SWEEP (mcp-server 2.93.0, 2026-07-12): the first batch of WS5
6
18
  * deprecated names were traffic-gated against prod `agent_events` (30-day
@@ -9,10 +21,11 @@
9
21
  * ToolDefinition, TOOL_METADATA, cost-model, and required-schemas companion
10
22
  * rows all went with them: `pica_projects_get`, `pica_notes_get`,
11
23
  * `pica_sessions_list`, `pica_sessions_get`, `pica_statements_get`,
12
- * `pica_share_links_list`. The ten aliases below still carry real live
13
- * traffic, so they STAY callable — their `removal_target` is consciously
14
- * extended (the "expire loudly" lint would otherwise block this publish at
15
- * 2.93.0). Re-run the traffic gate before that release.
24
+ * `pica_share_links_list`. The ten aliases that then remained still carried
25
+ * real live traffic, so they STAYED callable — their `removal_target` was
26
+ * consciously extended (the "expire loudly" lint would otherwise have blocked
27
+ * the 2.93.0 publish), with the traffic check to be re-run before the new
28
+ * target. They were finally removed in 2.99.0 (above).
16
29
  *
17
30
  * ⚠️ `removal_target` HERE IS DOCUMENTATION, NOT THE GATE (noted 2026-08-13).
18
31
  * `checkDeprecationExpiry` in `scripts/lint-mcp-tools.ts` reads the value from
@@ -40,107 +53,94 @@
40
53
  * 2.98.0 shipped the ADR-321 Phase 2 release without removals).
41
54
  */
42
55
  export const TOOL_ALIASES = [
43
- // Retired 2026-09-25 (ADR-321 Phase 0, founder decision): the old gap list
44
- // ran its own judgement — PRS/PPL/MCPS hard-coded, a missing row read as
45
- // "not registered with PRS", first 1,000 works only. Its society-income
46
- // questions now go to pica_royalties_blockers, the one judgement the song
47
- // page and /inspect/money use. Unmatched payments stay with
48
- // pica_royalties_unmatched. Dropped with it: "released but no Spotify link"
49
- // and "no tunecode" (not society-income blockers). Traffic: 2 calls from 2
50
- // orgs in the 90 days to 2026-09-25 (agent_events). gap_type/priority have
51
- // no equivalent and are dropped; work_id and limit carry over.
52
- {
53
- deprecated: "pica_royalties_summary",
54
- canonical: "pica_royalties_blockers",
55
- removal_target: "2.99.0",
56
- adaptArgs: (a) => ({ work_id: a.work_id, limit: a.limit }),
57
- },
58
- // Tier 1 (MCP tool-surface consolidation): pica_releases_attach_track is
59
- // now a superset (identifier_type+value / items[] / single-track) — see
60
- // ReleasesTools.attachTrack. Both siblings below are strict subsets of it.
61
- // FLAGGED (kept): 160 (_by_identifier) + 6 (_bulk) calls/30d in prod.
62
- {
63
- deprecated: "pica_releases_attach_track_by_identifier",
64
- canonical: "pica_releases_attach_track",
65
- removal_target: "2.99.0",
56
+ // Empty since mcp-server 2.99.0 — every alias has been removed (history in
57
+ // the comment above). Add a new entry here, with its TOOL_METADATA mirror,
58
+ // for the next deprecation.
59
+ ];
60
+ export const RETIRED_TOOLS = {
61
+ // mcp-server 2.99.0 (founder, 2026-09-29) — the last eleven aliases.
62
+ pica_releases_list: {
63
+ replacement: "pica_releases_query",
64
+ removed_in: "2.99.0",
66
65
  },
67
- {
68
- deprecated: "pica_releases_bulk_attach_tracks",
69
- canonical: "pica_releases_attach_track",
70
- removal_target: "2.99.0",
71
- adaptArgs: (a) => ({
72
- release_id: a.release_id,
73
- items: a.tracks,
74
- dry_run: a.dry_run,
75
- }),
66
+ pica_releases_get: {
67
+ replacement: "pica_releases_inspect",
68
+ removed_in: "2.99.0",
76
69
  },
77
- // Tier 1 (MCP tool-surface consolidation): releases aligned to the
78
- // ADR-149 query/inspect pattern. Both identity — args map 1:1.
79
- // FLAGGED (kept): _list 63 + _get 17 calls/30d in prod.
80
- {
81
- deprecated: "pica_releases_list",
82
- canonical: "pica_releases_query",
83
- removal_target: "2.99.0",
70
+ pica_releases_bulk_attach_tracks: {
71
+ replacement: "pica_releases_attach_track",
72
+ removed_in: "2.99.0",
73
+ argument_change: "pass the tracks as items[] (the old tracks field)",
84
74
  },
85
- {
86
- deprecated: "pica_releases_get",
87
- canonical: "pica_releases_inspect",
88
- removal_target: "2.99.0",
75
+ pica_releases_attach_track_by_identifier: {
76
+ replacement: "pica_releases_attach_track",
77
+ removed_in: "2.99.0",
78
+ argument_change: "pass identifier_type + value (with track_number) on pica_releases_attach_track",
89
79
  },
90
- // Tier 2 (MCP tool-surface consolidation): projects aligned to the
91
- // ADR-149 query/inspect pattern. Identity — args map 1:1. pica_projects_get
92
- // was REMOVED in the 2.93.0 sweep (0 calls/30d); _list stays (3 calls/30d).
93
- {
94
- deprecated: "pica_projects_list",
95
- canonical: "pica_projects_query",
96
- removal_target: "2.99.0",
80
+ pica_projects_list: {
81
+ replacement: "pica_projects_query",
82
+ removed_in: "2.99.0",
97
83
  },
98
- // Tier 2 (MCP tool-surface consolidation): notes aligned to the
99
- // ADR-149 query/inspect pattern. Identity — args map 1:1. pica_notes_get
100
- // was REMOVED in the 2.93.0 sweep (0 calls/30d); _list stays (4 calls/30d).
101
- {
102
- deprecated: "pica_notes_list",
103
- canonical: "pica_notes_query",
104
- removal_target: "2.99.0",
84
+ pica_notes_list: { replacement: "pica_notes_query", removed_in: "2.99.0" },
85
+ pica_documents_list: {
86
+ replacement: "pica_documents_query",
87
+ removed_in: "2.99.0",
105
88
  },
106
- // Tier 2 (MCP tool-surface consolidation): documents aligned to the
107
- // ADR-149 query/inspect pattern. Both identity — args map 1:1.
108
- // FLAGGED (kept): _list 5 + _read 10 calls/30d in prod.
109
- {
110
- deprecated: "pica_documents_list",
111
- canonical: "pica_documents_query",
112
- removal_target: "2.99.0",
89
+ pica_documents_read: {
90
+ replacement: "pica_documents_inspect",
91
+ removed_in: "2.99.0",
113
92
  },
114
- {
115
- deprecated: "pica_documents_read",
116
- canonical: "pica_documents_inspect",
117
- removal_target: "2.99.0",
93
+ pica_statements_list: {
94
+ replacement: "pica_statements_query",
95
+ removed_in: "2.99.0",
118
96
  },
119
- // Tier 2 (MCP tool-surface consolidation): statements aligned to the
120
- // ADR-149 query/inspect pattern. Identity — args map 1:1 (the canonical
121
- // inspect tool accepts the legacy batch_id field too). pica_statements_get
122
- // was REMOVED in the 2.93.0 sweep (0 calls/30d); _list stays (2 calls/30d).
123
- {
124
- deprecated: "pica_statements_list",
125
- canonical: "pica_statements_query",
126
- removal_target: "2.99.0",
97
+ pica_royalties_summary: {
98
+ replacement: "pica_royalties_blockers",
99
+ removed_in: "2.99.0",
100
+ argument_change: "work_id and limit carry over; gap_type and priority have no equivalent",
127
101
  },
128
- // Task A1 (MCP tool-surface consolidation): pica_recording_credits_update
129
- // is now a superset — dispatches to the bulk path when args.credits is an
130
- // array (see CreditsTools.updateRecordingCredits). Identity — the bulk arg
131
- // shape {release_id, recording_ids, credits, dry_run} is already accepted
132
- // by the superset's inputSchema, so no adaptArgs. FLAGGED (kept): 22
133
- // calls/30d in prod. VARIANT-MERGE ALIAS: when finally removed the
134
- // standalone pica_recording_credits_bulk_update ToolDefinition +
135
- // bulkUpdateRecordingCredits executor in credits.ts must ALSO be deleted,
136
- // or the tool resurrects (same trap as the attach bulk/by_identifier
137
- // aliases above).
138
- {
139
- deprecated: "pica_recording_credits_bulk_update",
140
- canonical: "pica_recording_credits_update",
141
- removal_target: "2.99.0",
102
+ pica_recording_credits_bulk_update: {
103
+ replacement: "pica_recording_credits_update",
104
+ removed_in: "2.99.0",
105
+ argument_change: "pass the credit set as a credits[] array (with release_id or recording_ids)",
142
106
  },
143
- ];
107
+ };
108
+ /** The retired-tool record for a name, if it is one. */
109
+ export function getRetiredTool(name) {
110
+ return Object.prototype.hasOwnProperty.call(RETIRED_TOOLS, name)
111
+ ? RETIRED_TOOLS[name]
112
+ : undefined;
113
+ }
114
+ /**
115
+ * Adjust a not-found answer for a retired name. Pure.
116
+ *
117
+ * `similar` is the similarity-ranked suggestion list the caller already built
118
+ * (at most three names). For a retired name whose replacement `canCall`
119
+ * accepts, the replacement goes FIRST and the list stays at most three long;
120
+ * `note` is the sentence to lead the message with. A replacement the caller
121
+ * cannot call is named in `note` (the mapping is published in the package
122
+ * CHANGELOG) but never added to the suggestions. This function does not
123
+ * filter `similar` itself: each caller builds it from names the caller can
124
+ * call (`canSuggest` in discovery.ts; the `allowedToolNames` pool in
125
+ * app/api/mcp/tool-not-found.ts). For any other name the list comes back
126
+ * unchanged and `note` is null.
127
+ */
128
+ export function retiredToolAnswer(name, similar, canCall) {
129
+ const retired = getRetiredTool(name);
130
+ if (!retired)
131
+ return { suggestions: [...similar], note: null };
132
+ const suggestions = canCall(retired.replacement)
133
+ ? [
134
+ retired.replacement,
135
+ ...similar.filter((n) => n !== retired.replacement),
136
+ ].slice(0, 3)
137
+ : [...similar];
138
+ const note = `${name} was retired in mcp-server ${retired.removed_in}; use ` +
139
+ `${retired.replacement} instead` +
140
+ (retired.argument_change ? ` — ${retired.argument_change}` : "") +
141
+ ".";
142
+ return { suggestions, note };
143
+ }
144
144
  /** True when a tool's metadata marks it deprecated (aliased). Pure. */
145
145
  export function isDeprecatedMeta(meta) {
146
146
  return meta?.deprecated === true;
@@ -1 +1 @@
1
- {"version":3,"file":"deprecations.js","sourceRoot":"","sources":["../../src/tools/deprecations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deprecations.js","sourceRoot":"","sources":["../../src/tools/deprecations.ts"],"names":[],"mappings":"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"}
@@ -148,11 +148,37 @@ export declare class DiscoveryTools {
148
148
  * `[...this.tools.keys()]` (index.ts, where DiscoveryTools is constructed),
149
149
  * which includes the hidden alias clones `expandAliases` registers — so a
150
150
  * typo one letter off an alias (`pica_releases_lists`) was answered with the
151
- * alias (`pica_releases_list`, removal_target 2.96.0) ranked above its own
151
+ * alias (`pica_releases_list`, since removed in 2.99.0) ranked above its own
152
152
  * canonical. Steering a confused caller onto a name we are trying to retire
153
- * is the opposite of what this envelope is for.
153
+ * is the opposite of what this envelope is for. TOOL_ALIASES is empty as of
154
+ * 2.99.0, so the filter currently removes nothing; it stays for the next
155
+ * deprecation.
156
+ *
157
+ * Tools the caller cannot run here are excluded too ({@link canSuggest}).
158
+ * The pool is every REGISTERED name, and on HTTP the route narrows what a
159
+ * caller may run through `setToolVisibility` (audience + scope). Without
160
+ * this filter a caller lacking finance scope was offered hidden
161
+ * statements/royalties tools for a statements typo — the same names the
162
+ * hosted route's suggester (`app/api/mcp/tool-not-found.ts`) never offers,
163
+ * because its pool is the caller's callable set.
154
164
  */
155
165
  private suggestToolNames;
166
+ /** Registered AND callable by this caller on this surface. */
167
+ private canSuggest;
168
+ /**
169
+ * The suggestions and leading note for a name that is not registered. A
170
+ * retired name (RETIRED_TOOLS in deprecations.ts) gets its replacement
171
+ * first (when callable) and a sentence saying what replaced it; any other
172
+ * name gets the similarity ranking unchanged.
173
+ *
174
+ * What is shared with the hosted route (`app/api/mcp/tool-not-found.ts`)
175
+ * is `retiredToolAnswer`, so both name the same replacement — pinned on
176
+ * this side by `src/__tests__/tools/tool-details-contract.test.ts` and on
177
+ * that side by `app/api/mcp/__tests__/tool-not-found.test.ts`. The
178
+ * similarity lists are NOT shared: each side ranks with its own suggester
179
+ * over its own pool, so for non-retired names the two may differ.
180
+ */
181
+ private notFoundAnswer;
156
182
  getTools(): Array<{
157
183
  definition: ToolDefinition;
158
184
  executor: ToolExecutor;
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/tools/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACX,MAAM,YAAY,CAAC;AAwCpB;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,6NACiM,CAAC;AAE7N;;;;;;;;;;;;;;;;GAgBG;AAGH,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CA+EzC,CAAC;AAyBH,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAWD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAk0BzD,CAAC;AAoBF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAsCD,qBAAa,cAAc;IAEvB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,UAAU;IAOlB;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAC;IACtB;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa,CAAC;gBA5Bd,aAAa,EAAE,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,CAAC,EAAE,mBAAmB,KACtB,OAAO,CAAC,UAAU,CAAC,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAC7B;QACE,UAAU,EAAE,cAAc,CAAC;QAC3B,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,YAAY,CAAC;KACzB,GACD,SAAS;IACb;;;;OAIG;IACK,aAAa,CAAC,GAAE,MAAM,MAAM,EAAE,aAAA;IACtC;;;;;;;;;OASG;IACK,aAAa,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,aAAA;IAGnD,OAAO,CAAC,SAAS;IAIjB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IASpB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,gBAAgB;IAqCxB,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IAQzE,OAAO,CAAC,iBAAiB;IAiIzB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,CAAC,cAAc;IAiGtB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,oBAAoB;IAiJ5B,OAAO,CAAC,eAAe;IAwGvB,OAAO,CAAC,gBAAgB;CA+YzB"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/tools/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACX,MAAM,YAAY,CAAC;AAwCpB;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,6NACiM,CAAC;AAE7N;;;;;;;;;;;;;;;;GAgBG;AAGH,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CA+EzC,CAAC;AAyBH,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAWD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAo0BzD,CAAC;AAoBF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAsCD,qBAAa,cAAc;IAEvB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,UAAU;IAOlB;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAC;IACtB;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa,CAAC;gBA5Bd,aAAa,EAAE,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,CAAC,EAAE,mBAAmB,KACtB,OAAO,CAAC,UAAU,CAAC,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAC7B;QACE,UAAU,EAAE,cAAc,CAAC;QAC3B,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,YAAY,CAAC;KACzB,GACD,SAAS;IACb;;;;OAIG;IACK,aAAa,CAAC,GAAE,MAAM,MAAM,EAAE,aAAA;IACtC;;;;;;;;;OASG;IACK,aAAa,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,aAAA;IAGnD,OAAO,CAAC,SAAS;IAIjB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IASpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,OAAO,CAAC,gBAAgB;IAqCxB,8DAA8D;IAC9D,OAAO,CAAC,UAAU;IAIlB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,cAAc;IAStB,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IAQzE,OAAO,CAAC,iBAAiB;IAiIzB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,CAAC,cAAc;IAiGtB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,oBAAoB;IAoJ5B,OAAO,CAAC,eAAe;IAwGvB,OAAO,CAAC,gBAAgB;CAgZzB"}
@@ -5,7 +5,7 @@
5
5
  // only ever CALLED from inside a method here. Do not convert it to a const
6
6
  // arrow function on the other side.
7
7
  import { deriveAnnotations } from "./index.js";
8
- import { getAliasFor } from "./deprecations.js";
8
+ import { getAliasFor, retiredToolAnswer } from "./deprecations.js";
9
9
  import { getToolMetadata } from "./metadata.js";
10
10
  import { RECOVERY_HINTS } from "./recovery-hints.js";
11
11
  import { applyArgAliases } from "./arg-aliases.js";
@@ -253,8 +253,8 @@ export const CATEGORIES = {
253
253
  "pica_credits_update",
254
254
  // pica_recording_credits_update is a superset (batch dispatch on
255
255
  // credits[] across a release's tracklist or an explicit recording
256
- // list, single call) — pica_recording_credits_bulk_update is now a
257
- // hidden alias (deprecations.ts), not listed here.
256
+ // list, single call) — pica_recording_credits_bulk_update, once a
257
+ // hidden alias of it, was removed in mcp-server 2.99.0.
258
258
  "pica_recording_credits_update",
259
259
  // ADR-226 Decision 12 cross-listing — Atlas routes "I want to claim my
260
260
  // credit on X" to natural_domain="credits".
@@ -331,9 +331,8 @@ export const CATEGORIES = {
331
331
  projects: {
332
332
  description: "manage albums, EPs, and work groupings",
333
333
  tools: [
334
- // pica_projects_list/_get are Tier 2 consolidation aliases now —
335
- // subsumed by pica_projects_query/_inspect (see TOOL_ALIASES in
336
- // deprecations.ts); hidden from discovery, still callable.
334
+ // pica_projects_list/_get were Tier 2 consolidation aliases of
335
+ // pica_projects_query/_inspect — _get removed in 2.93.0, _list in 2.99.0.
337
336
  "pica_projects_query",
338
337
  "pica_projects_inspect",
339
338
  "pica_projects_create",
@@ -348,9 +347,8 @@ export const CATEGORIES = {
348
347
  releases: {
349
348
  description: "manage releases with dates, labels, and UPCs",
350
349
  tools: [
351
- // pica_releases_list/_get are Tier 1 consolidation aliases now —
352
- // subsumed by pica_releases_query/_inspect (see TOOL_ALIASES in
353
- // deprecations.ts); hidden from discovery, still callable.
350
+ // pica_releases_list/_get were Tier 1 consolidation aliases of
351
+ // pica_releases_query/_inspect, removed in mcp-server 2.99.0.
354
352
  "pica_releases_query",
355
353
  "pica_releases_inspect",
356
354
  "pica_releases_create",
@@ -358,8 +356,8 @@ export const CATEGORIES = {
358
356
  "pica_releases_delete",
359
357
  // ADR-175 workflow tools
360
358
  // pica_releases_bulk_attach_tracks and pica_releases_attach_track_by_identifier
361
- // are Tier 1 consolidation aliases now — subsumed by pica_releases_attach_track
362
- // (see TOOL_ALIASES in deprecations.ts); hidden from discovery, still callable.
359
+ // were Tier 1 consolidation aliases of pica_releases_attach_track, removed
360
+ // in mcp-server 2.99.0.
363
361
  "pica_releases_move_track",
364
362
  "pica_releases_create_with_tracks",
365
363
  "pica_releases_completeness_check",
@@ -390,9 +388,8 @@ export const CATEGORIES = {
390
388
  notes: {
391
389
  description: "create and manage catalog notes",
392
390
  tools: [
393
- // pica_notes_list/_get are Tier 2 consolidation aliases now —
394
- // subsumed by pica_notes_query/_inspect (see TOOL_ALIASES in
395
- // deprecations.ts); hidden from discovery, still callable.
391
+ // pica_notes_list/_get were Tier 2 consolidation aliases of
392
+ // pica_notes_query/_inspect — _get removed in 2.93.0, _list in 2.99.0.
396
393
  "pica_notes_query",
397
394
  "pica_notes_inspect",
398
395
  "pica_notes_create",
@@ -488,9 +485,8 @@ export const CATEGORIES = {
488
485
  description: "analyse documents with ai",
489
486
  tools: [
490
487
  "pica_documents_analyse",
491
- // pica_documents_list/_read are Tier 2 consolidation aliases now —
492
- // subsumed by pica_documents_query/_inspect (see TOOL_ALIASES in
493
- // deprecations.ts); hidden from discovery, still callable.
488
+ // pica_documents_list/_read were Tier 2 consolidation aliases of
489
+ // pica_documents_query/_inspect, removed in mcp-server 2.99.0.
494
490
  "pica_documents_query",
495
491
  "pica_documents_inspect",
496
492
  "pica_documents_link",
@@ -829,9 +825,9 @@ export const CATEGORIES = {
829
825
  tools: [
830
826
  "pica_royalties_list",
831
827
  "pica_royalties_get",
832
- // pica_statements_list/_get are Tier 2 consolidation aliases now —
833
- // subsumed by pica_statements_query/_inspect (see TOOL_ALIASES in
834
- // deprecations.ts); hidden from discovery, still callable.
828
+ // pica_statements_list/_get were Tier 2 consolidation aliases of
829
+ // pica_statements_query/_inspect — _get removed in 2.93.0, _list in
830
+ // 2.99.0.
835
831
  "pica_statements_query",
836
832
  "pica_statements_inspect",
837
833
  // ADR-226 Decision 12 cross-listing — Atlas routes "import a royalty
@@ -850,8 +846,14 @@ export const CATEGORIES = {
850
846
  },
851
847
  // ADR-321 §9 — programmable rights: agents propose, humans confirm by email.
852
848
  rights: {
853
- description: "programmable rights — propose a song, master or share rule for the parties to confirm, check who has confirmed, and see what money would be held and why",
854
- tools: ["pica_rights_inspect", "pica_rights_status", "pica_rights_propose"],
849
+ description: "programmable rights — propose a song, master or share rule for the parties to confirm, check who has confirmed, see what money would be held and why, and what income would pay each party (computed, never paid)",
850
+ tools: [
851
+ "pica_rights_inspect",
852
+ "pica_rights_status",
853
+ "pica_rights_propose",
854
+ "pica_rights_statements",
855
+ "pica_rights_record_income",
856
+ ],
855
857
  depends_on: [],
856
858
  },
857
859
  selections: {
@@ -1131,12 +1133,22 @@ export class DiscoveryTools {
1131
1133
  * `[...this.tools.keys()]` (index.ts, where DiscoveryTools is constructed),
1132
1134
  * which includes the hidden alias clones `expandAliases` registers — so a
1133
1135
  * typo one letter off an alias (`pica_releases_lists`) was answered with the
1134
- * alias (`pica_releases_list`, removal_target 2.96.0) ranked above its own
1136
+ * alias (`pica_releases_list`, since removed in 2.99.0) ranked above its own
1135
1137
  * canonical. Steering a confused caller onto a name we are trying to retire
1136
- * is the opposite of what this envelope is for.
1138
+ * is the opposite of what this envelope is for. TOOL_ALIASES is empty as of
1139
+ * 2.99.0, so the filter currently removes nothing; it stays for the next
1140
+ * deprecation.
1141
+ *
1142
+ * Tools the caller cannot run here are excluded too ({@link canSuggest}).
1143
+ * The pool is every REGISTERED name, and on HTTP the route narrows what a
1144
+ * caller may run through `setToolVisibility` (audience + scope). Without
1145
+ * this filter a caller lacking finance scope was offered hidden
1146
+ * statements/royalties tools for a statements typo — the same names the
1147
+ * hosted route's suggester (`app/api/mcp/tool-not-found.ts`) never offers,
1148
+ * because its pool is the caller's callable set.
1137
1149
  */
1138
1150
  suggestToolNames(input) {
1139
- const candidates = (this.listToolNames?.() ?? []).filter((name) => getAliasFor(name) === undefined);
1151
+ const candidates = (this.listToolNames?.() ?? []).filter((name) => getAliasFor(name) === undefined && this.canSuggest(name));
1140
1152
  const tokens = new Set(input
1141
1153
  .replace(/^pica_/, "")
1142
1154
  .split("_")
@@ -1163,6 +1175,26 @@ export class DiscoveryTools {
1163
1175
  .slice(0, 3)
1164
1176
  .map((c) => c.name));
1165
1177
  }
1178
+ /** Registered AND callable by this caller on this surface. */
1179
+ canSuggest(name) {
1180
+ return this.getToolDef(name) !== undefined && this.isVisible(name);
1181
+ }
1182
+ /**
1183
+ * The suggestions and leading note for a name that is not registered. A
1184
+ * retired name (RETIRED_TOOLS in deprecations.ts) gets its replacement
1185
+ * first (when callable) and a sentence saying what replaced it; any other
1186
+ * name gets the similarity ranking unchanged.
1187
+ *
1188
+ * What is shared with the hosted route (`app/api/mcp/tool-not-found.ts`)
1189
+ * is `retiredToolAnswer`, so both name the same replacement — pinned on
1190
+ * this side by `src/__tests__/tools/tool-details-contract.test.ts` and on
1191
+ * that side by `app/api/mcp/__tests__/tool-not-found.test.ts`. The
1192
+ * similarity lists are NOT shared: each side ranks with its own suggester
1193
+ * over its own pool, so for non-retired names the two may differ.
1194
+ */
1195
+ notFoundAnswer(input) {
1196
+ return retiredToolAnswer(input, this.suggestToolNames(input), (name) => this.canSuggest(name));
1197
+ }
1166
1198
  getTools() {
1167
1199
  return [
1168
1200
  this.buildDiscoverTool(),
@@ -1457,12 +1489,13 @@ export class DiscoveryTools {
1457
1489
  //
1458
1490
  // Same helper, same envelope keys as the execute branch, so an
1459
1491
  // agent reads one shape wherever the question is asked.
1460
- const suggestions = this.suggestToolNames(args.tool);
1492
+ const { suggestions, note } = this.notFoundAnswer(args.tool);
1461
1493
  const envelope = {
1462
1494
  error: "TOOL_NOT_FOUND",
1463
1495
  error_code: "TOOL_NOT_FOUND",
1464
1496
  tool: args.tool,
1465
1497
  message: `no tool named '${args.tool}'.` +
1498
+ (note ? ` ${note}` : "") +
1466
1499
  (suggestions.length > 0
1467
1500
  ? ` Closest real tools: ${suggestions.join(", ")}.`
1468
1501
  : "") +
@@ -1813,12 +1846,13 @@ export class DiscoveryTools {
1813
1846
  // reads it everywhere else. Unifying the file on one key is a
1814
1847
  // separate change — do it for all six envelopes or none.
1815
1848
  if (!registered) {
1816
- const suggestions = this.suggestToolNames(toolName);
1849
+ const { suggestions, note } = this.notFoundAnswer(toolName);
1817
1850
  const envelope = {
1818
1851
  error: "TOOL_NOT_FOUND",
1819
1852
  error_code: "TOOL_NOT_FOUND",
1820
1853
  tool: toolName,
1821
1854
  message: `${toolName} is not a registered tool.` +
1855
+ (note ? ` ${note}` : "") +
1822
1856
  (suggestions.length > 0
1823
1857
  ? ` Closest real tools: ${suggestions.join(", ")}.`
1824
1858
  : "") +