@cliwant/mcp-sam-gov 1.13.0 → 1.13.2

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.ja.md CHANGED
@@ -71,7 +71,7 @@ npm install --omit=dev
71
71
  npm install -g .
72
72
  ```
73
73
 
74
- インストール後 `mcp-sam-gov` が PATH に登録される。ホスト config に追加:
74
+ インストール後 `mcp-sam-gov` が PATH に登録される。ホスト config に追加 (グローバルインストール):
75
75
 
76
76
  ```json
77
77
  {
@@ -81,7 +81,25 @@ npm install -g .
81
81
  }
82
82
  ```
83
83
 
84
- 各ホスト別 config の場所は [Host configurations](./README.md#host-configurations) (英語 README) を参照。
84
+ **グローバルインストールなし (npx)** — clone と `npm install -g` を省略でき、Node.js さえあれば動きます。初回起動時に npx が npm からパッケージを取得してキャッシュします。
85
+
86
+ ```json
87
+ { "mcpServers": { "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] } } }
88
+ ```
89
+
90
+ Claude Code の CLI で登録する場合:
91
+
92
+ ```bash
93
+ claude mcp add sam-gov -- npx -y @cliwant/mcp-sam-gov
94
+ ```
95
+
96
+ Windows でホストが `spawn npx ENOENT` でサーバーを起動できない場合は、npx を `cmd /c` で包んでください:`"command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"]`。
97
+
98
+ > **パッケージ名に注意:** npm パッケージ名はスコープ付きの **`@cliwant/mcp-sam-gov`** です。`mcp-sam-gov` はグローバルインストール時に PATH に置かれる実行ファイル名にすぎず、スコープなしの `mcp-sam-gov` パッケージは npm に存在しません。そのため `npx -y mcp-sam-gov` は 404 で失敗します。`npx -y @cliwant/mcp-sam-gov` を使ってください。
99
+
100
+ VS Code は `.vscode/mcp.json` に `"servers"` キーを使います。英語 README 上部の **Install in VS Code** / **Add to Kiro** バッジからワンクリックでインストールすることもできます。
101
+
102
+ 各ホスト別 config の場所とホスト別の npx 設定例は [Host configurations](./README.md#host-configurations) (英語 README) を参照。
85
103
 
86
104
  ### ⚪ パス 4 — 直接パス (グローバルインストールなし)
87
105
 
@@ -237,6 +255,7 @@ npm はインストール済みユーザーに新バージョンを通知しな
237
255
  |---|---|
238
256
  | Claude Desktop 🔨 メニューに `sam-gov` が表示されない | Claude Desktop を完全終了 (Windows: システムトレイ / macOS: Quit) して再起動。ログ: `%APPDATA%\Claude\logs\mcp*.log` |
239
257
  | `command not found: mcp-sam-gov` | `npm install -g .` が成功したか確認。`npm config get prefix` の結果が PATH にあるか確認 |
258
+ | `spawn npx ENOENT` (Windows, npx 設定) | ホストがシェルを介さずに `npx` を起動したため、Windows が `npx.cmd` を見つけられない。`"command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"]` を使用 |
240
259
  | `MODULE_NOT_FOUND ...dist/server.js` (Windows) | npm の git-dep + symlink バグ。パス 3 (clone + `npm install -g .`) を使用 |
241
260
  | `EPERM: operation not permitted` | `rmdir /s /q "%APPDATA%\npm\node_modules\@cliwant"` (初期バージョンをインストールしたことがある場合は `@govicon"`) 後に再試行 |
242
261
  | ツールが空の結果を返す | SAM.gov のレート制限。1 分待機後に再試行 または `SAM_GOV_API_KEY` 設定 |
package/README.ko.md CHANGED
@@ -71,7 +71,7 @@ npm install --omit=dev
71
71
  npm install -g .
72
72
  ```
73
73
 
74
- 설치 후 `mcp-sam-gov` 가 PATH 등록됨. 호스트 config 에 추가:
74
+ 설치 후 `mcp-sam-gov` 가 PATH 등록됨. 호스트 config 에 추가 (글로벌 설치):
75
75
 
76
76
  ```json
77
77
  {
@@ -81,7 +81,25 @@ npm install -g .
81
81
  }
82
82
  ```
83
83
 
84
- 각 호스트별 config 위치는 [호스트별 설정](./README.md#host-configurations) 참조 (영문 README).
84
+ **글로벌 설치 없이 (npx)** — clone 과 `npm install -g` 를 건너뛰고 Node.js 만 있으면 됩니다. 첫 실행 때 npx 가 npm 에서 패키지를 받아 캐시합니다.
85
+
86
+ ```json
87
+ { "mcpServers": { "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] } } }
88
+ ```
89
+
90
+ Claude Code CLI 로 등록할 때:
91
+
92
+ ```bash
93
+ claude mcp add sam-gov -- npx -y @cliwant/mcp-sam-gov
94
+ ```
95
+
96
+ Windows 에서 호스트가 `spawn npx ENOENT` 로 서버를 못 띄우면 npx 를 `cmd /c` 로 감싸세요: `"command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"]`.
97
+
98
+ > **패키지 이름 주의:** npm 패키지 이름은 scope 가 붙은 **`@cliwant/mcp-sam-gov`** 입니다. `mcp-sam-gov` 는 글로벌 설치 시 PATH 에 생기는 실행 파일 이름일 뿐이고, npm 에 scope 없는 `mcp-sam-gov` 패키지는 없습니다. 그래서 `npx -y mcp-sam-gov` 는 404 로 실패합니다. `npx -y @cliwant/mcp-sam-gov` 를 쓰세요.
99
+
100
+ VS Code 는 `.vscode/mcp.json` 에 `"servers"` 키를 사용합니다. 또는 영문 README 상단의 **Install in VS Code** / **Add to Kiro** 배지로 원클릭 설치할 수 있습니다.
101
+
102
+ 각 호스트별 config 위치와 호스트별 npx 설정 예시는 [호스트별 설정](./README.md#host-configurations) 참조 (영문 README).
85
103
 
86
104
  ### ⚪ 경로 4 — 직접 경로 (글로벌 설치 없음)
87
105
 
@@ -237,6 +255,7 @@ npm은 설치한 사용자에게 새 버전을 알려주지 않으므로, 서버
237
255
  |---|---|
238
256
  | Claude Desktop 🔨 메뉴에 `sam-gov` 안 보임 | Claude Desktop 완전 종료 (Windows: 시스템 트레이 / macOS: Quit) 후 재실행. 로그: `%APPDATA%\Claude\logs\mcp*.log` |
239
257
  | `command not found: mcp-sam-gov` | `npm install -g .` 성공했나 확인. `npm config get prefix` 결과가 PATH 에 있나 확인 |
258
+ | `spawn npx ENOENT` (Windows, npx 설정) | 호스트가 셸 없이 `npx` 를 실행해 Windows 가 `npx.cmd` 를 못 찾은 경우. `"command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"]` 사용 |
240
259
  | `MODULE_NOT_FOUND ...dist/server.js` (Windows) | npm 의 git-dep + symlink 버그. 경로 3 (clone + `npm install -g .`) 사용 |
241
260
  | `EPERM: operation not permitted` | `rmdir /s /q "%APPDATA%\npm\node_modules\@cliwant"` (또는 초기 버전 설치 경험이 있다면 `@govicon"`) 후 재시도 |
242
261
  | 도구 결과 비어있음 | SAM.gov rate limit. 1분 대기 후 재시도 또는 `SAM_GOV_API_KEY` 설정 |
package/README.md CHANGED
@@ -13,6 +13,8 @@ The most comprehensive **keyless-first** MCP server for US federal **and state/l
13
13
  [![Glama score](https://glama.ai/mcp/servers/cliwant/mcp-sam-gov/badges/score.svg)](https://glama.ai/mcp/servers/cliwant/mcp-sam-gov)
14
14
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
15
15
  [![Daily smoke](https://github.com/cliwant/mcp-sam-gov/actions/workflows/daily-smoke.yml/badge.svg)](https://github.com/cliwant/mcp-sam-gov/actions/workflows/daily-smoke.yml)
16
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_MCP-0098FF?logo=visualstudiocode)](https://insiders.vscode.dev/redirect/mcp/install?name=sam-gov&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cliwant%2Fmcp-sam-gov%22%5D%7D)
17
+ [![Add to Kiro](https://img.shields.io/badge/Kiro-Add_MCP-7B3FE4)](https://kiro.dev/launch/mcp/add?name=sam-gov&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cliwant%2Fmcp-sam-gov%22%5D%7D)
16
18
 
17
19
  [English](./README.md) · [한국어](./README.ko.md) · [日本語](./README.ja.md)
18
20
 
@@ -36,7 +38,7 @@ The most comprehensive **keyless-first** MCP server for US federal **and state/l
36
38
 
37
39
  🤖 Claude → sam_get_opportunity { noticeId: "5ef3db5d…" }
38
40
  ✓ Department of Veterans Affairs · Combined Synopsis/Solicitation
39
- POC: Rebecca Gobble <rebecca.gobble@va.gov> +1-410-642-2411
41
+ POC: Contracting Officer <co.name@example.gov> +1-XXX-XXX-XXXX
40
42
  Set-aside: Total Small Business
41
43
  Attachments: 1 ↓ 36C24526Q0460_1.docx (172 KB)
42
44
  SOW preview: "RFQ# 36C24526Q0460 — Bulk Oxygen Tank Rental, Fill, Telemetry…"
@@ -136,6 +138,8 @@ After install, the binary `mcp-sam-gov` is on your PATH. Add this to your host c
136
138
 
137
139
  Specific config locations per host: see [Host configurations](#host-configurations) below.
138
140
 
141
+ **No global install?** Every host config below also has an `npx` variant (`npx -y @cliwant/mcp-sam-gov`) that skips the clone and `npm install -g`. It only needs Node.js.
142
+
139
143
  ### ⚪ Path 4 — Direct path (zero install, just point at the file)
140
144
 
141
145
  Skip installation entirely:
@@ -163,10 +167,19 @@ Then point your host config at the absolute path:
163
167
 
164
168
  ## Host configurations
165
169
 
170
+ Each host below shows two variants. Use one of them:
171
+
172
+ - **Global install**: `"command": "mcp-sam-gov"`. This works only after `npm install -g` (Path 3) has put the `mcp-sam-gov` binary on your PATH.
173
+ - **No global install (npx)**: `"command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"]`. This needs only Node.js. npx downloads the package from npm on first run and caches it.
174
+
175
+ > **Package name:** the npm package is scoped: **`@cliwant/mcp-sam-gov`**. `mcp-sam-gov` is only the name of the binary that a global install puts on your PATH. No unscoped `mcp-sam-gov` package exists on npm, so `npx -y mcp-sam-gov` fails with a 404. Use `npx -y @cliwant/mcp-sam-gov`.
176
+
166
177
  ### Claude Desktop
167
178
 
168
179
  `%APPDATA%\Claude\claude_desktop_config.json` (Windows) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
169
180
 
181
+ Global install:
182
+
170
183
  ```json
171
184
  {
172
185
  "mcpServers": {
@@ -175,45 +188,91 @@ Then point your host config at the absolute path:
175
188
  }
176
189
  ```
177
190
 
191
+ No global install (npx):
192
+
193
+ ```json
194
+ {
195
+ "mcpServers": {
196
+ "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] }
197
+ }
198
+ }
199
+ ```
200
+
201
+ On Windows, if the server fails to start with `spawn npx ENOENT` in `%APPDATA%\Claude\logs\mcp*.log`, wrap npx in `cmd /c`:
202
+
203
+ ```json
204
+ {
205
+ "mcpServers": {
206
+ "sam-gov": { "command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"] }
207
+ }
208
+ }
209
+ ```
210
+
178
211
  (Or skip this entirely — use Path 1's `.mcpb` and it auto-configures.)
179
212
 
180
213
  Restart Claude Desktop fully (system tray quit on Windows / Quit menu on macOS), then look for the 🔨 icon. You should see "sam-gov (152 tools)".
181
214
 
182
215
  ### Claude Code
183
216
 
184
- Per-project `.mcp.json`:
217
+ Per-project `.mcp.json`, global install:
185
218
 
186
219
  ```json
187
220
  { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
188
221
  ```
189
222
 
190
- Or globally:
223
+ No global install (npx):
224
+
225
+ ```json
226
+ { "mcpServers": { "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] } } }
227
+ ```
228
+
229
+ Or with the CLI:
191
230
 
192
231
  ```bash
232
+ # global install
193
233
  claude mcp add sam-gov mcp-sam-gov
234
+
235
+ # no global install (npx)
236
+ claude mcp add sam-gov -- npx -y @cliwant/mcp-sam-gov
194
237
  ```
195
238
 
196
239
  ### Codex CLI
197
240
 
198
241
  `~/.codex/config.toml`:
199
242
 
243
+ Global install:
244
+
200
245
  ```toml
201
246
  [mcp_servers.sam-gov]
202
247
  command = "mcp-sam-gov"
203
248
  args = []
204
249
  ```
205
250
 
251
+ No global install (npx):
252
+
253
+ ```toml
254
+ [mcp_servers.sam-gov]
255
+ command = "npx"
256
+ args = ["-y", "@cliwant/mcp-sam-gov"]
257
+ ```
258
+
206
259
  ### Cursor
207
260
 
208
- Settings → MCP → Add new MCP server:
261
+ Settings → MCP → Add new MCP server. Global install:
209
262
 
210
263
  ```json
211
264
  { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
212
265
  ```
213
266
 
267
+ No global install (npx):
268
+
269
+ ```json
270
+ { "mcpServers": { "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] } } }
271
+ ```
272
+
214
273
  ### Continue
215
274
 
216
- `~/.continue/config.json`:
275
+ `~/.continue/config.json`, global install:
217
276
 
218
277
  ```json
219
278
  {
@@ -225,17 +284,56 @@ Settings → MCP → Add new MCP server:
225
284
  }
226
285
  ```
227
286
 
287
+ No global install (npx):
288
+
289
+ ```json
290
+ {
291
+ "experimental": {
292
+ "modelContextProtocolServer": {
293
+ "transport": { "type": "stdio", "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] }
294
+ }
295
+ }
296
+ }
297
+ ```
298
+
228
299
  ### Gemini CLI
229
300
 
230
- `~/.gemini/settings.json`:
301
+ `~/.gemini/settings.json`, global install:
231
302
 
232
303
  ```json
233
304
  { "mcpServers": { "sam-gov": { "command": "mcp-sam-gov" } } }
234
305
  ```
235
306
 
307
+ No global install (npx):
308
+
309
+ ```json
310
+ { "mcpServers": { "sam-gov": { "command": "npx", "args": ["-y", "@cliwant/mcp-sam-gov"] } } }
311
+ ```
312
+
313
+ ### VS Code
314
+
315
+ Add a `.vscode/mcp.json` at your project root (VS Code uses `"servers"`, not `"mcpServers"`):
316
+
317
+ ```json
318
+ {
319
+ "servers": {
320
+ "sam-gov": {
321
+ "command": "npx",
322
+ "args": ["-y", "@cliwant/mcp-sam-gov"]
323
+ }
324
+ }
325
+ }
326
+ ```
327
+
328
+ Or use the one-click badge at the top of this page to install directly from your browser.
329
+
330
+ ### Kiro
331
+
332
+ Use the one-click badge at the top of this page to add the server. Kiro opens an install dialog pre-filled with the `npx` command.
333
+
236
334
  ### Anything else
237
335
 
238
- If your host speaks MCP over stdio, point it at `mcp-sam-gov`. No host-specific code.
336
+ If your host speaks MCP over stdio, point it at `mcp-sam-gov` (global install) or at `npx -y @cliwant/mcp-sam-gov` (no global install). No host-specific code.
239
337
 
240
338
  ---
241
339
 
@@ -688,6 +786,7 @@ This server is built around one rule: **honest failure over confident fabricatio
688
786
  |---|---|
689
787
  | Claude Desktop 🔨 menu doesn't show `sam-gov` | Fully quit Claude Desktop (system tray on Windows / Quit menu on macOS) and reopen. Check `%APPDATA%\Claude\logs\mcp*.log` |
690
788
  | `command not found: mcp-sam-gov` | Confirm `npm install -g .` succeeded; check that npm's global bin is on PATH (`npm config get prefix`) |
789
+ | `spawn npx ENOENT` (Windows, npx config) | The host started `npx` without a shell, so Windows can't find `npx.cmd`. Use `"command": "cmd", "args": ["/c", "npx", "-y", "@cliwant/mcp-sam-gov"]`. |
691
790
  | `MODULE_NOT_FOUND ...dist/server.js` after `npm install -g github:...` | npm bug with git-dep symlinks on Windows. Use the clone + `npm install -g .` recipe (Path 3) instead. |
692
791
  | `EPERM: operation not permitted, rmdir` during install | Previous failed install left dangling files. Run `rmdir /s /q "%APPDATA%\npm\node_modules\@cliwant"` (or `@govicon` if you installed an early version) then retry. |
693
792
  | `npm install` fails with "private repo" / 404 | The repo is now public — should not happen. If it does, try `git clone https://github.com/cliwant/mcp-sam-gov.git` directly. |
@@ -20,9 +20,25 @@
20
20
  * • Non-nagging. Error links are attached only to the two "something may be
21
21
  * broken" kinds (schema_drift, upstream_unavailable) — never to expected
22
22
  * outcomes (not_found, invalid_input, rate_limited).
23
+ * • Countable. Every prefilled body starts with one fixed HTML comment,
24
+ * `<!-- mcp-sam-gov:tool-report v=<server version> kind=<report kind> -->`
25
+ * (invisible once the issue renders). GitHub drops a prefilled `labels=`
26
+ * for filers without triage rights, so the repo's label-tool-reports
27
+ * workflow reads this marker instead and applies `from-tool`. The marker
28
+ * holds only the server version and the report kind — never a tool
29
+ * argument, query, key, path, or the caller's summary.
23
30
  */
24
31
  export declare const REPO_URL = "https://github.com/cliwant/mcp-sam-gov";
25
32
  export type FeedbackKind = "bug" | "feature" | "wrong_output";
33
+ /** The fixed token the label-tool-reports workflow looks for in an issue body. */
34
+ export declare const TOOL_REPORT_MARKER_TOKEN = "mcp-sam-gov:tool-report";
35
+ /**
36
+ * The one-line, PII-free HTML comment put at the top of every prefilled body:
37
+ * `<!-- mcp-sam-gov:tool-report v=<version> kind=<kind> -->`. A value that does
38
+ * not match its pattern is written as `unknown`. It goes FIRST in the body so a
39
+ * URL cut short at the end still keeps it, and it adds under 100 URL characters.
40
+ */
41
+ export declare function toolReportMarker(kind: string, version: string): string;
26
42
  /**
27
43
  * The prefilled report link attached to a schema_drift / upstream_unavailable
28
44
  * error envelope. Carries ONLY tool + kind + server version — no args, no PII.
@@ -55,10 +71,11 @@ export type FeedbackResult = {
55
71
  * report into a PREFILLED GitHub new-issue URL for the HUMAN to open and submit.
56
72
  * Pure + keyless: no network, no posting. `summary` is caller-supplied free text
57
73
  * and is trusted to be non-sensitive (the description + privacy note say so).
74
+ * `version` is the server version, used only in the tool-report marker.
58
75
  */
59
76
  export declare function feedbackTool(input: {
60
77
  kind?: FeedbackKind;
61
78
  tool?: string;
62
79
  summary?: string;
63
- }): FeedbackResult;
80
+ }, version: string): FeedbackResult;
64
81
  //# sourceMappingURL=feedback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,eAAO,MAAM,QAAQ,2CAA2C,CAAC;AAGjE,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,CAAC;AAkB9D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBrF;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAGrD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,IAAI,CAIN;AAaD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,cAAc,CAgCjB"}
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,eAAO,MAAM,QAAQ,2CAA2C,CAAC;AAGjE,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,CAAC;AAK9D,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAQlE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAItE;AAeD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAuBrF;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAGrD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,IAAI,CAIN;AAaD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE;IACL,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,EACD,OAAO,EAAE,MAAM,GACd,cAAc,CAiChB"}
package/dist/feedback.js CHANGED
@@ -20,10 +20,35 @@
20
20
  * • Non-nagging. Error links are attached only to the two "something may be
21
21
  * broken" kinds (schema_drift, upstream_unavailable) — never to expected
22
22
  * outcomes (not_found, invalid_input, rate_limited).
23
+ * • Countable. Every prefilled body starts with one fixed HTML comment,
24
+ * `<!-- mcp-sam-gov:tool-report v=<server version> kind=<report kind> -->`
25
+ * (invisible once the issue renders). GitHub drops a prefilled `labels=`
26
+ * for filers without triage rights, so the repo's label-tool-reports
27
+ * workflow reads this marker instead and applies `from-tool`. The marker
28
+ * holds only the server version and the report kind — never a tool
29
+ * argument, query, key, path, or the caller's summary.
23
30
  */
24
31
  export const REPO_URL = "https://github.com/cliwant/mcp-sam-gov";
25
32
  const NEW_ISSUE_URL = `${REPO_URL}/issues/new`;
26
33
  const REDACT_NOTE = "⚠️ This is a PUBLIC issue. Do NOT paste API keys, credentials, personal data, or sensitive query values — redact anything private before you submit.";
34
+ /** The fixed token the label-tool-reports workflow looks for in an issue body. */
35
+ export const TOOL_REPORT_MARKER_TOKEN = "mcp-sam-gov:tool-report";
36
+ // Both marker values come from closed sets (SERVER_VERSION, an error kind or a
37
+ // FeedbackKind), but they are still checked here so the marker can never carry
38
+ // anything else, and can never close the HTML comment early.
39
+ const MARKER_KIND_RE = /^[a-z][a-z_]{0,39}$/;
40
+ const MARKER_VERSION_RE = /^\d{1,4}\.\d{1,4}\.\d{1,4}(?:-[0-9A-Za-z.]{1,20})?$/;
41
+ /**
42
+ * The one-line, PII-free HTML comment put at the top of every prefilled body:
43
+ * `<!-- mcp-sam-gov:tool-report v=<version> kind=<kind> -->`. A value that does
44
+ * not match its pattern is written as `unknown`. It goes FIRST in the body so a
45
+ * URL cut short at the end still keeps it, and it adds under 100 URL characters.
46
+ */
47
+ export function toolReportMarker(kind, version) {
48
+ const v = MARKER_VERSION_RE.test(version) ? version : "unknown";
49
+ const k = MARKER_KIND_RE.test(kind) ? kind : "unknown";
50
+ return `<!-- ${TOOL_REPORT_MARKER_TOKEN} v=${v} kind=${k} -->`;
51
+ }
27
52
  /**
28
53
  * Build a GitHub "new issue" URL with a prefilled title/body/labels. Everything
29
54
  * is URL-encoded via URLSearchParams. A prefilled label that does not exist in
@@ -47,6 +72,7 @@ export function reportUrlForError(tool, kind, version) {
47
72
  ? "schema_drift means the government API very likely changed its response shape, so the wrapper needs updating — this is the single most useful thing to report."
48
73
  : "upstream_unavailable is often a transient government-side outage; please report only if it PERSISTS or the endpoint appears to have permanently moved.";
49
74
  const body = [
75
+ toolReportMarker(kind, version),
50
76
  "**Reporting a tool problem** (this link was suggested by the server).",
51
77
  "",
52
78
  `- **Tool:** \`${tool}\``,
@@ -97,8 +123,9 @@ const KIND_LABELS = {
97
123
  * report into a PREFILLED GitHub new-issue URL for the HUMAN to open and submit.
98
124
  * Pure + keyless: no network, no posting. `summary` is caller-supplied free text
99
125
  * and is trusted to be non-sensitive (the description + privacy note say so).
126
+ * `version` is the server version, used only in the tool-report marker.
100
127
  */
101
- export function feedbackTool(input) {
128
+ export function feedbackTool(input, version) {
102
129
  const kind = input.kind ?? "bug";
103
130
  const toolPart = input.tool ? `[${input.tool}] ` : "";
104
131
  const summary = (input.summary ?? "").trim();
@@ -107,25 +134,26 @@ export function feedbackTool(input) {
107
134
  ? "**What I want to be able to do:**"
108
135
  : "**What I did, expected, and got:**";
109
136
  const body = [
110
- `**Type:** ${KIND_TITLE[kind]}`,
111
- input.tool ? `**Tool:** \`${input.tool}\`` : "",
112
- "",
113
- `${lead} ${summary || "_(describe)_"}`,
114
- "",
115
- kind === "feature"
116
- ? "**Why it matters / use case:** _(describe)_"
117
- : "**Steps to reproduce:** _(describe — no sensitive values)_",
118
- "",
119
- REDACT_NOTE,
120
- ]
121
- .filter((line, i) => !(line === "" && i === 2 && !input.tool))
122
- .join("\n");
137
+ toolReportMarker(kind, version),
138
+ ...[
139
+ `**Type:** ${KIND_TITLE[kind]}`,
140
+ input.tool ? `**Tool:** \`${input.tool}\`` : "",
141
+ "",
142
+ `${lead} ${summary || "_(describe)_"}`,
143
+ "",
144
+ kind === "feature"
145
+ ? "**Why it matters / use case:** _(describe)_"
146
+ : "**Steps to reproduce:** _(describe — no sensitive values)_",
147
+ "",
148
+ REDACT_NOTE,
149
+ ].filter((line, i) => !(line === "" && i === 2 && !input.tool)),
150
+ ].join("\n");
123
151
  return {
124
152
  reportUrl: buildIssueUrl({ title, body, labels: KIND_LABELS[kind] }),
125
153
  repo: REPO_URL,
126
154
  willPost: false,
127
155
  instructions: "Open reportUrl in a browser and submit the issue yourself — the server does NOT post anything automatically. Edit the prefilled title/body first if you like.",
128
- privacy: "The link prefills only your summary + tool name — no API keys, query values, or personal data. Keep it that way; the issue is public.",
156
+ privacy: "The link prefills only your summary, tool name, server version and report kind — no API keys, query values, or personal data. Keep it that way; the issue is public.",
129
157
  };
130
158
  }
131
159
  //# sourceMappingURL=feedback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -92,7 +92,7 @@ import { realpathSync } from "node:fs";
92
92
  const SERVER_NAME = "mcp-sam-gov";
93
93
  // Kept in lockstep with package.json / manifest.json / server.json.
94
94
  // Keep in sync with package.json "version" (asserted at release; see CHANGELOG).
95
- const SERVER_VERSION = "1.13.0";
95
+ const SERVER_VERSION = "1.13.2";
96
96
  // ─── Tool input schemas (Zod) ────────────────────────────────────
97
97
  const SamSearchInput = z.object({
98
98
  query: z.string().optional().describe("Free-text title query"),
@@ -5639,7 +5639,7 @@ export const TOOLS = [
5639
5639
  name: "feedback",
5640
5640
  description: "Report a problem, request a feature, or flag a wrong-looking result for THIS server — returns a PREFILLED GitHub issue link (public repo cliwant/mcp-sam-gov) for the USER to open and submit. KEYLESS. The server does NOT post anything: it only builds the link; the human submits it (nothing is sent automatically, no network call). Use when the user reports a bug, says a tool's output looks wrong, or wants a capability this server doesn't have. Input (all optional): `kind` (bug|feature|wrong_output, default bug), `tool` (the tool it's about), `summary` (a short, NON-SENSITIVE title line). Returns { reportUrl, repo, willPost:false, instructions, privacy }. PRIVACY: never put secrets, personal data, or sensitive query values in `summary` — the issue is PUBLIC and the link prefills only your summary + tool + server version.",
5641
5641
  inputSchema: FeedbackInput,
5642
- handler: async (input) => feedback.feedbackTool(input),
5642
+ handler: async (input) => feedback.feedbackTool(input, SERVER_VERSION),
5643
5643
  }),
5644
5644
  ];
5645
5645
  // ─── Server bootstrap ────────────────────────────────────────────