@cliwant/mcp-sam-gov 1.11.0 → 1.13.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 (99) hide show
  1. package/README.ja.md +17 -13
  2. package/README.ko.md +17 -13
  3. package/README.md +25 -16
  4. package/dist/arcgis-feature.d.ts.map +1 -1
  5. package/dist/arcgis-feature.js +11 -0
  6. package/dist/arcgis-feature.js.map +1 -1
  7. package/dist/bls.d.ts.map +1 -1
  8. package/dist/bls.js +6 -1
  9. package/dist/bls.js.map +1 -1
  10. package/dist/bonfire.d.ts +1 -1
  11. package/dist/bonfire.d.ts.map +1 -1
  12. package/dist/bonfire.js +14 -3
  13. package/dist/bonfire.js.map +1 -1
  14. package/dist/census-economic.d.ts.map +1 -1
  15. package/dist/census-economic.js +10 -1
  16. package/dist/census-economic.js.map +1 -1
  17. package/dist/ckan.d.ts.map +1 -1
  18. package/dist/ckan.js +17 -3
  19. package/dist/ckan.js.map +1 -1
  20. package/dist/clinicaltrials.d.ts.map +1 -1
  21. package/dist/clinicaltrials.js +23 -6
  22. package/dist/clinicaltrials.js.map +1 -1
  23. package/dist/echo.d.ts +6 -2
  24. package/dist/echo.d.ts.map +1 -1
  25. package/dist/echo.js +12 -6
  26. package/dist/echo.js.map +1 -1
  27. package/dist/fdic.js +7 -7
  28. package/dist/fdic.js.map +1 -1
  29. package/dist/fema.d.ts.map +1 -1
  30. package/dist/fema.js +13 -1
  31. package/dist/fema.js.map +1 -1
  32. package/dist/grants.d.ts.map +1 -1
  33. package/dist/grants.js +13 -3
  34. package/dist/grants.js.map +1 -1
  35. package/dist/gsa-csv.d.ts +9 -0
  36. package/dist/gsa-csv.d.ts.map +1 -1
  37. package/dist/gsa-csv.js +37 -8
  38. package/dist/gsa-csv.js.map +1 -1
  39. package/dist/nppes.d.ts.map +1 -1
  40. package/dist/nppes.js +17 -4
  41. package/dist/nppes.js.map +1 -1
  42. package/dist/nsf.d.ts.map +1 -1
  43. package/dist/nsf.js +9 -0
  44. package/dist/nsf.js.map +1 -1
  45. package/dist/open-checkbook.d.ts +65 -0
  46. package/dist/open-checkbook.d.ts.map +1 -0
  47. package/dist/open-checkbook.js +166 -0
  48. package/dist/open-checkbook.js.map +1 -0
  49. package/dist/openfda-device.d.ts.map +1 -1
  50. package/dist/openfda-device.js +8 -5
  51. package/dist/openfda-device.js.map +1 -1
  52. package/dist/openfda-drugsfda.d.ts.map +1 -1
  53. package/dist/openfda-drugsfda.js +8 -5
  54. package/dist/openfda-drugsfda.js.map +1 -1
  55. package/dist/openfda.d.ts +21 -0
  56. package/dist/openfda.d.ts.map +1 -1
  57. package/dist/openfda.js +38 -4
  58. package/dist/openfda.js.map +1 -1
  59. package/dist/opengov.d.ts.map +1 -1
  60. package/dist/opengov.js +8 -4
  61. package/dist/opengov.js.map +1 -1
  62. package/dist/server.d.ts +7 -0
  63. package/dist/server.d.ts.map +1 -1
  64. package/dist/server.js +101 -10
  65. package/dist/server.js.map +1 -1
  66. package/dist/socrata.d.ts.map +1 -1
  67. package/dist/socrata.js +14 -7
  68. package/dist/socrata.js.map +1 -1
  69. package/dist/tableau.d.ts +58 -0
  70. package/dist/tableau.d.ts.map +1 -0
  71. package/dist/tableau.js +132 -0
  72. package/dist/tableau.js.map +1 -0
  73. package/dist/usaspending.d.ts +2 -2
  74. package/dist/usaspending.d.ts.map +1 -1
  75. package/dist/usaspending.js +21 -10
  76. package/dist/usaspending.js.map +1 -1
  77. package/package.json +2 -2
  78. package/src/arcgis-feature.ts +11 -0
  79. package/src/bls.ts +8 -1
  80. package/src/bonfire.ts +14 -3
  81. package/src/census-economic.ts +13 -2
  82. package/src/ckan.ts +19 -3
  83. package/src/clinicaltrials.ts +25 -8
  84. package/src/echo.ts +12 -6
  85. package/src/fdic.ts +7 -7
  86. package/src/fema.ts +15 -1
  87. package/src/grants.ts +15 -2
  88. package/src/gsa-csv.ts +38 -7
  89. package/src/nppes.ts +18 -4
  90. package/src/nsf.ts +10 -0
  91. package/src/open-checkbook.ts +183 -0
  92. package/src/openfda-device.ts +10 -4
  93. package/src/openfda-drugsfda.ts +10 -4
  94. package/src/openfda.ts +47 -5
  95. package/src/opengov.ts +8 -4
  96. package/src/server.ts +110 -10
  97. package/src/socrata.ts +14 -7
  98. package/src/tableau.ts +159 -0
  99. package/src/usaspending.ts +21 -10
package/dist/opengov.js CHANGED
@@ -180,10 +180,14 @@ export async function searchSolicitations(args) {
180
180
  upstreamEndpoint: OPENGOV_PROJ_LABEL,
181
181
  });
182
182
  }
183
- // The API paginates by 0-based `page` + `limit`. Map our offset → page.
184
- const page = Math.floor(offset / limit);
185
- const servedOffset = page * limit;
186
- const payload = JSON.stringify({ governmentCode: code, publicView: true, page, limit });
183
+ // The OpenGov /project/list `page` param is 1-BASED — `page=0` CLAMPS to page 1
184
+ // (live-verified 2026-07-20: phoenix offset 0 and offset<limit both returned the
185
+ // SAME first page → a 0-based send duplicates page 1 and shifts every later page,
186
+ // silently dropping the tail while totalAvailable still claims the full count).
187
+ // Map our row `offset` → the 1-based page; servedOffset stays offset-aligned.
188
+ const apiPage = Math.floor(offset / limit) + 1;
189
+ const servedOffset = (apiPage - 1) * limit;
190
+ const payload = JSON.stringify({ governmentCode: code, publicView: true, page: apiPage, limit });
187
191
  let body;
188
192
  try {
189
193
  body = await getOpengov(OPENGOV_PROJECT_LIST_PATH, OPENGOV_PROJ_LABEL, { method: "POST", body: payload });
@@ -1 +1 @@
1
- {"version":3,"file":"opengov.js","sourceRoot":"","sources":["../src/opengov.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opengov.js","sourceRoot":"","sources":["../src/opengov.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAsC,MAAM,WAAW,CAAC;AAEzE,4DAA4D;AAC5D,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,6BAA6B,CAAC;AAC1D,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AACrD,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AACzD,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AACvD,MAAM,kBAAkB,GAAG,8BAA8B,CAAC;AAC1D,MAAM,cAAc,GAAG,sEAAsE,CAAC;AAC9F,MAAM,cAAc,GAAG,wCAAwC,CAAC;AAEhE,0EAA0E;AAC1E,0EAA0E;AAC1E,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,MAAM,mBAAmB,GACvB,+RAA+R,CAAC;AAwBlS,uEAAuE;AACvE,SAAS,UAAU,CAAC,CAAU;IAC5B,OAAO,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED,yEAAyE;AACzE,KAAK,UAAU,UAAU,CACvB,IAAY,EACZ,KAAa,EACb,OAA2C,EAAE;IAE7C,MAAM,GAAG,GAAG,WAAW,YAAY,GAAG,IAAI,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnE,MAAM,IAAI,gBAAgB,CAAC;YACzB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,gCAAgC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,QAAQ,mCAAmC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,gDAAgD;YACzM,SAAS,EAAE,KAAK;YAChB,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GACX,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,OAAO,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;AACtE,CAAC;AAUD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAEhC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,UAAU,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,gBAAgB;YAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,WAAW;YAC1B,MAAM,UAAU,CAAC,iBAAiB,EAAE,0EAA0E,CAAC,CAAC;QAClH,MAAM,CAAC,CAAC;IACV,CAAC;IACD,sEAAsE;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,UAAU,CAAC,iBAAiB,EAAE,iFAAiF,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,IAAiB,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAA4B,CAAC;QACjD,kEAAkE;QAClE,IAAI,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK;YAAE,SAAS;QAC/C,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI;YAAE,SAAS;QAChD,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAC;QAC5D,MAAM,CAAC,GAAsB;YAC3B,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YACnB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACnB,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;SACxB,CAAC;QACF,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;YAAE,SAAS,CAAC,iCAAiC;QAChE,IAAI,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,WAAW;YAAE,SAAS;QAC3E,IAAI,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAS;QACjF,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;IAC7B,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,cAAc,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAEtD,MAAM,KAAK,GAAa;QACtB,6MAA6M;KAC9M,CAAC;IACF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IACjH,CAAC;IAED,OAAO,QAAQ,CACb,EAAE,WAAW,EAAE,IAAI,EAAE,EACrB;QACE,MAAM,EAAE,cAAc;QACtB,WAAW,EAAE,IAAI;QACjB,QAAQ;QACR,cAAc;QACd,cAAc;QACd,cAAc,EAAE,EAAE;QAClB,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE;QAClD,KAAK;KAC0B,CAClC,CAAC;AACJ,CAAC;AASD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAoC;IAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC;IAEvC,+EAA+E;IAC/E,iFAAiF;IACjF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,gBAAgB,CAAC;YACzB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,kCAAkC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0HAA0H;YACzL,SAAS,EAAE,KAAK;YAChB,gBAAgB,EAAE,kBAAkB;SACrC,CAAC,CAAC;IACL,CAAC;IAED,gFAAgF;IAChF,iFAAiF;IACjF,kFAAkF;IAClF,gFAAgF;IAChF,8EAA8E;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAEjG,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,UAAU,CAAC,yBAAyB,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5G,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,gBAAgB;YAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,WAAW;YAC1B,MAAM,UAAU,CAAC,kBAAkB,EAAE,4EAA4E,CAAC,CAAC;QACrH,MAAM,CAAC,CAAC;IACV,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4C,CAAC;IAClE,wEAAwE;IACxE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,kBAAkB,EAAE,yEAAyE,CAAC,CAAC;IAClH,CAAC;IAED,MAAM,aAAa,GAA2B,CAAC,CAAC,QAAsB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACjF,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAA4B,CAAC;QACjD,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,MAAM,WAAW,GAAG,IAAI,CAAC;QACzB,OAAO;YACL,EAAE;YACF,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACnB,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;YACtC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACrB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YACjB,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;YACjC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,CAAC,QAAQ,CAAC;YACpD,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACzC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI;YAC1G,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,cAAc,IAAI,WAAW,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;SAC7E,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC;IAEtC,mFAAmF;IACnF,MAAM,cAAc,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GACX,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,GAAG,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC;IACzF,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAE5D,MAAM,KAAK,GAAa,CAAC,mBAAmB,CAAC,CAAC;IAC9C,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,2CAA2C,YAAY,yCAAyC,KAAK,IAAI,CAAC,CAAC;IACxH,CAAC;IACD,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,gGAAgG,CAAC,CAAC;IAC/G,CAAC;IAED,OAAO,QAAQ,CACb,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,EACvC;QACE,MAAM,EAAE,cAAc;QACtB,WAAW,EAAE,IAAI;QACjB,QAAQ;QACR,cAAc;QACd,cAAc,EAAE,CAAC,gBAAgB,EAAE,YAAY,CAAC;QAChD,cAAc,EAAE,EAAE;QAClB,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE;QAChE,KAAK;KAC0B,CAClC,CAAC;AACJ,CAAC"}
package/dist/server.d.ts CHANGED
@@ -28,6 +28,13 @@ type ToolDef = {
28
28
  };
29
29
  export declare const TOOLS: ToolDef[];
30
30
  export declare function runTool(name: string, args: Record<string, unknown>, sam: SamGovClient): Promise<unknown>;
31
+ export declare function humanizeToolTitle(name: string): string;
32
+ /** Uniform MCP annotations for a tool: derived title + read-only / open-world hints. */
33
+ export declare function toolAnnotations(name: string): {
34
+ title: string;
35
+ readOnlyHint: true;
36
+ openWorldHint: true;
37
+ };
31
38
  /**
32
39
  * Hand-rolled Zod → JSON Schema converter (subset we use).
33
40
  */
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAQH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EAKb,MAAM,oBAAoB,CAAC;AA4iJ5B,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC;IAO1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE;QAAE,GAAG,EAAE,YAAY,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE,CAAC;AAoBF,eAAO,MAAM,KAAK,EAAE,OAAO,EAq1D1B,CAAC;AAkLF,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAkClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkE7E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAQH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EAKb,MAAM,oBAAoB,CAAC;AA0kJ5B,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC;IAO1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE;QAAE,GAAG,EAAE,YAAY,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE,CAAC;AAoBF,eAAO,MAAM,KAAK,EAAE,OAAO,EA22D1B,CAAC;AAmLF,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAkClB;AAyBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CActD;AACD,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,IAAI,CAAC;IACnB,aAAa,EAAE,IAAI,CAAC;CACrB,CAEA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkE7E"}
package/dist/server.js CHANGED
@@ -42,6 +42,8 @@ import * as arcgisHub from "./arcgis-hub.js";
42
42
  import * as opengov from "./opengov.js";
43
43
  import * as bonfire from "./bonfire.js";
44
44
  import * as arcgisFeature from "./arcgis-feature.js";
45
+ import * as tableau from "./tableau.js";
46
+ import * as openCheckbook from "./open-checkbook.js";
45
47
  import * as govinfo from "./govinfo.js";
46
48
  import * as fpds from "./fpds.js";
47
49
  import * as nih from "./nih.js";
@@ -90,7 +92,7 @@ import { realpathSync } from "node:fs";
90
92
  const SERVER_NAME = "mcp-sam-gov";
91
93
  // Kept in lockstep with package.json / manifest.json / server.json.
92
94
  // Keep in sync with package.json "version" (asserted at release; see CHANGELOG).
93
- const SERVER_VERSION = "1.11.0";
95
+ const SERVER_VERSION = "1.13.0";
94
96
  // ─── Tool input schemas (Zod) ────────────────────────────────────
95
97
  const SamSearchInput = z.object({
96
98
  query: z.string().optional().describe("Free-text title query"),
@@ -2301,8 +2303,8 @@ const EchoSearchFacilitiesInput = z.object({
2301
2303
  const EchoFacilityReportInput = z.object({
2302
2304
  registryId: z
2303
2305
  .string()
2304
- .regex(/^[0-9]{9,12}$/)
2305
- .describe("The facility's FRS RegistryID (from echo_search_facilities rows' RegistryID) — an all-digit id, 9–12 digits (e.g. '110059768461'). A bad/unknown id ⇒ not_found (never a fabricated report)."),
2306
+ .regex(/^[A-Za-z0-9]{1,20}$/)
2307
+ .describe("The facility's RegistryID exactly as returned in echo_search_facilities rows — usually a 12-digit FRS id (e.g. '110059768461'), but ECHO also returns state/program ids (e.g. 'DCR000509282') and short ids (e.g. '9434'), which the report accepts. 1–20 letters/digits. A bad/unknown id ⇒ not_found (never a fabricated report)."),
2306
2308
  });
2307
2309
  // ─── api.data.gov keyed trio (Regulations.gov + Congress.gov) — input schemas ──
2308
2310
  // ADR-0007. The project's FIRST KEYED source. The key is read from env
@@ -2572,7 +2574,7 @@ const OpengovSearchSolicitationsInput = z.object({
2572
2574
  // ─── Bonfire (Euna) — keyless per-org open-opportunity RSS (SLED bids) ─
2573
2575
  // SLED bid campaign. Thousands of US state/local govs on Bonfire expose a keyless
2574
2576
  // RSS of open opportunities at {org}.bonfirehub.com/opportunities/rss. Ships a
2575
- // curated 187-org seed directory. Fixed-suffix SSRF. org = charclass slug.
2577
+ // curated 186-org seed directory. Fixed-suffix SSRF. org = charclass slug.
2576
2578
  const BonfireListOrganizationsInput = z.object({
2577
2579
  state: z.string().length(2).optional().describe("2-letter US state filter (client-side), e.g. 'TX', 'CA'. Optional."),
2578
2580
  query: z.string().min(1).max(120).optional().describe("Case-insensitive name substring filter (client-side), e.g. 'county', 'ISD'. Optional."),
@@ -2589,6 +2591,32 @@ const BonfireSearchOpportunitiesInput = z.object({
2589
2591
  limit: z.number().int().min(1).max(200).default(50).describe("Opportunities per page, 1..200, default 50. The RSS is the complete open set; this pages over it."),
2590
2592
  offset: z.number().int().min(0).default(0).describe("0-based offset; page with _meta.pagination.nextOffset. totalAvailable = the exact open-opportunity count."),
2591
2593
  });
2594
+ // ─── Socrata Open Expenditures checkbook (curated portal allowlist — SLED) ─
2595
+ // Row-level vendor-payment search over the keyless /api/checkbook_data.json
2596
+ // app-proxy (the underlying SODA dataset is login-gated — never touched).
2597
+ const OpenCheckbookSearchInput = z.object({
2598
+ portal: z
2599
+ .enum(openCheckbook.OPEN_CHECKBOOK_PORTALS.map((p) => p.key))
2600
+ .describe("The curated Open-Checkbook portal (SSRF allowlist enum). 'sd' = State of South Dakota Open Checkbook (~740,980 vendor payments, ~$8.41B, ~3 most-recent fiscal years)."),
2601
+ year: z.string().min(1).max(40).optional().describe("Fiscal-year filter (EXACT match), e.g. '2025'. Default 'All Years' = the exposed ~3-year window (NOT full history)."),
2602
+ vendor: z.string().min(1).max(200).optional().describe("Vendor name filter (EXACT match, e.g. 'US BANK NA' → 917). A partial/misspelled value returns an honest count:0."),
2603
+ org: z.string().min(1).max(200).optional().describe("Department filter (org1, EXACT match, e.g. 'TRANSPORTATION' → 109,887)."),
2604
+ expenseCategory: z.string().min(1).max(200).optional().describe("Expense-category filter (EXACT match, e.g. 'CONTRACTUAL SERVICES')."),
2605
+ sortBy: z.enum(["amount", "payment_date", "vendor", "org1", "expense_category"]).optional().describe("Sort field. Pair with sortOrder."),
2606
+ sortOrder: z.enum(["asc", "desc"]).optional().describe("Sort direction (default desc when sortBy is set)."),
2607
+ limit: z.number().int().min(1).max(1000).default(25).describe("Rows per page, 1..1000, default 25."),
2608
+ offset: z.number().int().min(0).default(0).describe("0-based offset (snapped to a page×limit boundary; the served offset is disclosed). totalAvailable = the real match count, NOT a page length."),
2609
+ });
2610
+ // ─── Tableau Server Guest view CSV (curated view allowlist — SLED transparency) ─
2611
+ // Fetch a Guest-enabled Tableau Server WORKSHEET view's COMPLETE CSV export
2612
+ // (keyless) and page over it client-side. `view` is an enum (SSRF core).
2613
+ const TableauViewCsvInput = z.object({
2614
+ view: z
2615
+ .enum(tableau.TABLEAU_VIEWS.map((v) => v.key))
2616
+ .describe("The curated Tableau Server Guest view (SSRF allowlist enum). 'mt_contracts_awarded' = State of Montana (DOA) Contracts Awarded (~4,554 award records: $ Awarded, Award Date, Event Type IFB/RFP, Event# solicitation, Vendor Name, Agency)."),
2617
+ limit: z.number().int().min(1).max(1000).default(50).describe("Rows per page, 1..1000, default 50. The CSV is the complete view export; this pages over it client-side."),
2618
+ offset: z.number().int().min(0).default(0).describe("0-based offset; page with _meta.pagination.nextOffset. totalAvailable = the complete export row count (NOT a page length)."),
2619
+ });
2592
2620
  // ─── ArcGIS REST feature query (curated service allowlist — SLED bids/GIS) ─
2593
2621
  // Generic ArcGIS FeatureServer/MapServer layer query over a curated allowlist.
2594
2622
  // First payload: DC OCP PASS procurement layers (live solicitations/contracts/PO/
@@ -2596,7 +2624,7 @@ const BonfireSearchOpportunitiesInput = z.object({
2596
2624
  const ArcgisFeatureQueryInput = z.object({
2597
2625
  service: z
2598
2626
  .enum(arcgisFeature.ARCGIS_SERVICES.map((s) => s.key))
2599
- .describe("The curated ArcGIS layer (SSRF allowlist enum). DC OCP PASS: 'dc_pass_solicitations' (live solicitations ~25k), 'dc_pass_contracts', 'dc_pass_purchase_orders', 'dc_pass_payments'. Other US local govs: 'asheville_purchase_orders'/'asheville_po_summary' (Asheville NC), 'bellevue_vendor_payments'/'bellevue_awarded_contracts' (Bellevue WA), 'miamidade_purchase_orders_2025'/'miamidade_purchase_orders_2017' (Miami-Dade FL, current/2017), 'suffolk_county_ny_contracts_2018' (Suffolk County NY), 'matsu_borough_ak_checkbook' (Matanuska-Susitna Borough AK), 'lasvegas_checkbook' (Las Vegas NV ~373k), 'baltimore_checkbook' (Baltimore City MD ~367k), 'naperville_vendor_payments' (Naperville IL ~127k), 'worcester_ma_checkbook_fy25' (Worcester MA FY25), 'lasvegas_purchasing_contracts' (Las Vegas NV contract register), 'txdot_construction_projects' (Texas DOT, awarded construction company ~85k), 'akdot_construction_awards'/'akdot_aashtoware_proposals' (Alaska DOT&PF bid awards/proposals), 'iowadot_public_bid_awards' (Iowa DOT public bid), 'okdot_cirb_contract_status' (Oklahoma DOT CIRB contract status), 'topeka_checkbook_aggregate' (Topeka KS checkbook FY2015–2023 ~332k). 23 curated services (state DOT bid/award registers: TX/AK/IA/OK + municipal checkbooks/contracts)."),
2627
+ .describe("The curated ArcGIS layer (SSRF allowlist enum). DC OCP PASS: 'dc_pass_solicitations' (live solicitations ~25k), 'dc_pass_contracts', 'dc_pass_purchase_orders', 'dc_pass_payments'. Other US local govs: 'asheville_purchase_orders'/'asheville_po_summary' (Asheville NC), 'bellevue_vendor_payments'/'bellevue_awarded_contracts' (Bellevue WA), 'miamidade_purchase_orders_2025'/'miamidade_purchase_orders_2017' (Miami-Dade FL, current/2017), 'suffolk_county_ny_contracts_2018' (Suffolk County NY), 'matsu_borough_ak_checkbook' (Matanuska-Susitna Borough AK), 'lasvegas_checkbook' (Las Vegas NV ~373k), 'baltimore_checkbook' (Baltimore City MD ~367k), 'naperville_vendor_payments' (Naperville IL ~127k), 'worcester_ma_checkbook_fy25' (Worcester MA FY25), 'lasvegas_purchasing_contracts' (Las Vegas NV contract register), 'txdot_construction_projects' (Texas DOT, awarded construction company ~85k), 'akdot_construction_awards'/'akdot_aashtoware_proposals' (Alaska DOT&PF bid awards/proposals), 'iowadot_public_bid_awards' (Iowa DOT public bid), 'okdot_cirb_contract_status' (Oklahoma DOT CIRB contract status), 'topeka_checkbook_aggregate' (Topeka KS checkbook FY2015–2023 ~332k), 'nddot_flex_setaside_road'/'nddot_flex_partner_road'/'nddot_flex_setaside_bridge'/'nddot_flex_partner_bridge' (North Dakota DOT federal flex-funding awards to local public agencies — counties/townships/cities, NOT vendor contracts; a proxy because ND's checkbook/procurement portal is not keyless-reachable). 27 curated services (state DOT bid/award registers: TX/AK/IA/OK + ND DOT flex-funding awards + municipal checkbooks/contracts)."),
2600
2628
  where: z
2601
2629
  .string()
2602
2630
  .min(1)
@@ -3138,7 +3166,7 @@ const CensusBusinessPatternsInput = z.object({
3138
3166
  .string()
3139
3167
  .regex(/^\d{4}$/)
3140
3168
  .optional()
3141
- .describe("The CBP data year (default '2022', the latest confirmed vintage). Validated ^\\d{4}$ (it rides in the request path)."),
3169
+ .describe("The CBP data year (default '2023', the latest published vintage — CBP is released with a ~2-year lag). Validated ^\\d{4}$ (it rides in the request path)."),
3142
3170
  limit: z
3143
3171
  .number()
3144
3172
  .int()
@@ -5136,7 +5164,7 @@ export const TOOLS = [
5136
5164
  }),
5137
5165
  defineTool({
5138
5166
  name: "echo_facility_report",
5139
- description: "Fetch the EPA ECHO Detailed Facility Report (DFR) for ONE facility by its FRS RegistryID (keyless) — the per-facility compliance / enforcement / inspection / permit deep-dive for competitor or acquisition-target due diligence. Input `registryId` (all-digit FRS id, 9–12 digits, from echo_search_facilities rows). Returns { registryId, report:{…verbatim compliance/enforcement/permit detail…} } + single-record _meta (complete:true, no pagination). A bad/unknown RegistryID ⇒ not_found (never a fabricated report).",
5167
+ description: "Fetch the EPA ECHO Detailed Facility Report (DFR) for ONE facility by its FRS RegistryID (keyless) — the per-facility compliance / enforcement / inspection / permit deep-dive for competitor or acquisition-target due diligence. Input `registryId` (the RegistryID exactly as returned by echo_search_facilities rows — usually a 12-digit FRS id, but ECHO also returns state/program ids like 'DCR000509282' and short ids like '9434', all accepted; 1–20 letters/digits). Returns { registryId, report:{…verbatim compliance/enforcement/permit detail…} } + single-record _meta (complete:true, no pagination). A bad/unknown RegistryID ⇒ not_found (never a fabricated report).",
5140
5168
  inputSchema: EchoFacilityReportInput,
5141
5169
  handler: (input) => echo.facilityReport(input),
5142
5170
  }),
@@ -5231,12 +5259,12 @@ export const TOOLS = [
5231
5259
  }),
5232
5260
  // ━━━ Bonfire (Euna) — keyless per-org open-opportunity RSS (SLED bids) ━━━
5233
5261
  // SLED bid campaign. Thousands of US state/local govs on Bonfire expose a keyless
5234
- // RSS of open opportunities. Ships a curated 187-org live-verified seed directory
5262
+ // RSS of open opportunities. Ships a curated 186-org live-verified seed directory
5235
5263
  // (Bonfire's authoritative org API is auth-gated → out of bounds). Fixed-suffix
5236
5264
  // SSRF (.bonfirehub.com). RSS = the complete open set (totalAvailable honest).
5237
5265
  defineTool({
5238
5266
  name: "bonfire_list_organizations",
5239
- description: "List US governments on the Bonfire (Euna) eProcurement platform — the directory for bonfire_search_opportunities (keyless). Bonfire hosts thousands of US state/local governments' open-bid portals, each with a keyless RSS feed. Filter the curated seed by `state` (2-letter) / `query` (case-insensitive name substring); `limit`(1..200)/`offset`. Output: { organizations:[{ org, name, state }] }. Feed a result's `org` to bonfire_search_opportunities. ★HONESTY: this is a CURATED, live-verified SEED of 187 US orgs — Bonfire has NO keyless org-list API (its authoritative directory is auth-gated, out of bounds), and Euna markets up to ~900 US orgs, so the seed is PARTIAL (disclosed in _meta); probe `{slug}.bonfirehub.com/opportunities/rss` to extend. totalAvailable = the exact filtered seed count.",
5267
+ description: "List US governments on the Bonfire (Euna) eProcurement platform — the directory for bonfire_search_opportunities (keyless). Bonfire hosts thousands of US state/local governments' open-bid portals, each with a keyless RSS feed. Filter the curated seed by `state` (2-letter) / `query` (case-insensitive name substring); `limit`(1..200)/`offset`. Output: { organizations:[{ org, name, state }] }. Feed a result's `org` to bonfire_search_opportunities. ★HONESTY: this is a CURATED, live-verified SEED of 186 US orgs — Bonfire has NO keyless org-list API (its authoritative directory is auth-gated, out of bounds), and Euna markets up to ~900 US orgs, so the seed is PARTIAL (disclosed in _meta); probe `{slug}.bonfirehub.com/opportunities/rss` to extend. totalAvailable = the exact filtered seed count.",
5240
5268
  inputSchema: BonfireListOrganizationsInput,
5241
5269
  handler: (input) => bonfire.listOrganizations(input),
5242
5270
  }),
@@ -5256,6 +5284,26 @@ export const TOOLS = [
5256
5284
  inputSchema: ArcgisFeatureQueryInput,
5257
5285
  handler: (input) => arcgisFeature.featureQuery(input),
5258
5286
  }),
5287
+ // ─── Tableau Server Guest view CSV export (curated allowlist) — SLED transparency ─
5288
+ // Many US state/local govs publish contracts/vendor-payment/checkbook data on a
5289
+ // Guest-enabled Tableau Server; a worksheet view exports its full data as CSV at
5290
+ // {host}/t/{site}/views/{wb}/{view}.csv?:embed=y (keyless). First payload: Montana
5291
+ // Contracts Awarded — the ND-sibling in the dark-state closure campaign.
5292
+ defineTool({
5293
+ name: "tableau_view_csv",
5294
+ description: "Fetch a curated US-government **Tableau Server Guest** view's COMPLETE CSV export (keyless) and page over it — a SLED transparency source (many state/local govs publish contracts / vendor-payment / checkbook data on a Guest-enabled Tableau Server; a worksheet view exports as CSV at `{host}/t/{site}/views/{workbook}/{view}.csv?:embed=y`, no login/key/cookie). First payload: `mt_contracts_awarded` = **State of Montana (DOA) Contracts Awarded** (~4,554 award records: '$ Awarded', 'Award Date', 'Event Type' (Invitation For Bid / RFP), 'Event#' solicitation number, 'Vendor Name', 'Agency'). Inputs: `view` (the allowlist ENUM — SSRF core, never a free host), `limit`(1..1000)/`offset`. Returns { view, columns:[…], rows:[{col:value…}] } + honest _meta. HONESTY: the CSV is the COMPLETE view export (Tableau returns ALL summary rows — NO server pagination), so totalAvailable = the true row count (NEVER a page length); limit/offset page it client-side; a round-number total is flagged as a possible Tableau export cap. Values are TRIMMED strings (an empty field ⇒ null, never 0/\"\"); the content is preserved — amounts like \"$5,879,590.00\" are FORMATTED STRINGS, parse client-side. A 429/5xx/404/timeout THROWS; a gated/renamed view (200 sign-in HTML or an empty dashboard-container export) ⇒ schema_drift (a loud failure, NEVER a fake empty); a worksheet with a header but 0 data rows ⇒ honest empty. SSRF: fixed allowlist base + hostname assertion + redirect:error.",
5295
+ inputSchema: TableauViewCsvInput,
5296
+ handler: (input) => tableau.viewCsv(input),
5297
+ }),
5298
+ // ─── Socrata Open Expenditures checkbook (curated portal allowlist) — SLED ─
5299
+ // Row-level vendor payments via the keyless /api/checkbook_data.json app-proxy.
5300
+ // First portal: South Dakota — the LAST dark-state closure (presence → 100%).
5301
+ defineTool({
5302
+ name: "open_checkbook_search",
5303
+ description: "Row-level vendor-payment search over a curated US-government **Socrata Open Expenditures** checkbook portal (keyless) — a SLED spending source. Some govs run Socrata's 'Open Expenditures/Open Checkbook' product, whose public dashboard fronts a keyless app-proxy at `{host}/api/checkbook_data.json`. First portal: `sd` = **State of South Dakota Open Checkbook** (~740,980 vendor-payment rows, ~$8.41B, the ~3 most-recent fiscal years). Inputs: `portal` (allowlist ENUM — SSRF core), `year`/`vendor`/`org`/`expenseCategory` (EXACT-match filters), `sortBy`/`sortOrder`, `limit`(1..1000)/`offset`. Returns { portal, rows:[{vendor, amount, payment_date, org1, expense_category, description, fund, invoice, payment_id}] } + honest _meta. HONESTY: totalAvailable = the API's own `count` (the REAL filtered total — matches the product's totals.json, e.g. 740,980 unfiltered / 109,887 for org=TRANSPORTATION — NEVER a page length); `amount` = number|null (a real $0 is 0, an absent value is null, never a fabricated 0); an EXACT-match filter miss ⇒ honest count:0; a deep offset past the end ⇒ returned:0 with the real count preserved; a 429/5xx/timeout THROWS; a non-`{data:[],count}` body ⇒ schema_drift. ★Only the ~3 most-recent fiscal years are exposed (NOT full history — disclosed). ★The underlying Socrata SODA dataset is login-gated and is NEVER touched — only the public app-proxy the dashboard itself uses. SSRF: fixed allowlist host + assertion + redirect:error.",
5304
+ inputSchema: OpenCheckbookSearchInput,
5305
+ handler: (input) => openCheckbook.openCheckbookSearch(input),
5306
+ }),
5259
5307
  // ━━━ GovInfo (api.govinfo.gov) — the api.data.gov keyed trio's 3rd API (3) ━━━ ADR-0010
5260
5308
  // GPO-authoritative bulk publications (BILLS/PLAW/USCODE/CREC/CFR-FR editions/
5261
5309
  // BUDGET/GAOREPORTS) with PDF/XML/MODS downloads + provenance. 2nd consumer of the
@@ -5312,7 +5360,7 @@ export const TOOLS = [
5312
5360
  // a negative number / never 0). The 2D-array body is parsed by header name.
5313
5361
  defineTool({
5314
5362
  name: "census_business_patterns",
5315
- description: "Market sizing by NAICS × geography — establishments, employment, and annual payroll from the US Census County Business Patterns (CBP) API (api.census.gov/data/{year}/cbp). ★REQUIRES a free CENSUS_API_KEY: the Census Data API has NO keyless tier, so without the key this tool THROWS an honest config error (get one at https://api.census.gov/data/key_signup.html; call api_key_status to see every source's key requirement). Input: optional `naics` (2–6 digit NAICS-2017, e.g. '5415'; omit to aggregate all sectors), `geography` (us|state|county, default us; county REQUIRES `state`), `state` (2-digit FIPS, e.g. '06'), `year` (default '2022'), optional `limit` (client-side top-N; CBP has no server pagination). Returns { rows:[{ name, geoId, naicsCode, naicsLabel, establishments, employees, annualPayrollUsd, state }] } + honest _meta. HONESTY: establishments/employees are integer counts and annualPayrollUsd is annual US dollars (×1000 from the source's $1,000-unit PAYANN); large-negative suppression sentinels map to null — NEVER a negative number and NEVER 0 (a genuine 0 stays 0; note CBP primarily uses noise-infusion + suppression flags, surfaced as reported — see the tool's suppression note); geoId/naicsCode/state are STRINGS (leading zeros survive). CBP returns the COMPLETE geography set for the filter (no pagination) ⇒ totalAvailable = the row count, complete:true. A missing/invalid key ⇒ invalid_input (a 302 to the Missing-Key page); a header-only body ⇒ honest empty (returned:0); a 5xx ⇒ THROWS; a 200 non-JSON ⇒ schema_drift. The key rides ONLY in the &key= query param — never logged or echoed.",
5363
+ description: "Market sizing by NAICS × geography — establishments, employment, and annual payroll from the US Census County Business Patterns (CBP) API (api.census.gov/data/{year}/cbp). ★REQUIRES a free CENSUS_API_KEY: the Census Data API has NO keyless tier, so without the key this tool THROWS an honest config error (get one at https://api.census.gov/data/key_signup.html; call api_key_status to see every source's key requirement). Input: optional `naics` (2–6 digit NAICS-2017, e.g. '5415'; omit to aggregate all sectors), `geography` (us|state|county, default us; county REQUIRES `state`), `state` (2-digit FIPS, e.g. '06'), `year` (default '2023'), optional `limit` (client-side top-N; CBP has no server pagination). Returns { rows:[{ name, geoId, naicsCode, naicsLabel, establishments, employees, annualPayrollUsd, state }] } + honest _meta. HONESTY: establishments/employees are integer counts and annualPayrollUsd is annual US dollars (×1000 from the source's $1,000-unit PAYANN); large-negative suppression sentinels map to null — NEVER a negative number and NEVER 0 (a genuine 0 stays 0; note CBP primarily uses noise-infusion + suppression flags, surfaced as reported — see the tool's suppression note); geoId/naicsCode/state are STRINGS (leading zeros survive). CBP returns the COMPLETE geography set for the filter (no pagination) ⇒ totalAvailable = the row count, complete:true. A missing/invalid key ⇒ invalid_input (a 302 to the Missing-Key page); a header-only body ⇒ honest empty (returned:0); a 5xx ⇒ THROWS; a 200 non-JSON ⇒ schema_drift. The key rides ONLY in the &key= query param — never logged or echoed.",
5316
5364
  inputSchema: CensusBusinessPatternsInput,
5317
5365
  handler: (input) => censusEconomic.businessPatterns(input),
5318
5366
  }),
@@ -5625,6 +5673,7 @@ async function main() {
5625
5673
  name: t.name,
5626
5674
  description: t.description,
5627
5675
  inputSchema: zodToJsonSchema(t.inputSchema),
5676
+ annotations: toolAnnotations(t.name),
5628
5677
  })),
5629
5678
  };
5630
5679
  });
@@ -5801,6 +5850,48 @@ export async function runTool(name, args, sam) {
5801
5850
  }
5802
5851
  throw new Error(`Unknown tool: ${name}`);
5803
5852
  }
5853
+ // ─── MCP tool annotations ────────────────────────────────────────────────────
5854
+ // Every tool advertises a human-friendly `title` plus behaviour hints, per the MCP
5855
+ // spec and the Anthropic Connectors Directory requirement (title + readOnlyHint).
5856
+ // EVERY tool in this server is strictly READ-ONLY (queries public data; none mutate
5857
+ // upstream state) and OPEN-WORLD (calls external government/public APIs), so those
5858
+ // two hints are uniform. `title` is derived from the tool name via a source-prefix
5859
+ // map so e.g. `sam_search_opportunities` → "SAM.gov: Search Opportunities".
5860
+ const TOOL_SOURCE_LABELS = {
5861
+ sam: "SAM.gov", usas: "USAspending", edgar: "SEC EDGAR", fdic: "FDIC", cms: "CMS",
5862
+ treasury: "Treasury", regulations: "Regulations.gov", openfda: "openFDA",
5863
+ govinfo: "GovInfo", fema: "FEMA", far: "FAR/DFARS", ecfr: "eCFR", census: "Census",
5864
+ clinicaltrials: "ClinicalTrials.gov", bls: "BLS", socrata: "Socrata", opengov: "OpenGov",
5865
+ nsf: "NSF", nonprofit: "Nonprofit", nhtsa: "NHTSA", gsa: "GSA", grants: "Grants.gov",
5866
+ fred: "FRED", fac: "FAC", echo: "EPA ECHO", dol: "DOL", congress: "Congress.gov",
5867
+ ckan: "data.gov", bonfire: "Bonfire", arcgis: "ArcGIS", tableau: "Tableau", open: "Open Checkbook", sba: "SBA", ofac: "OFAC",
5868
+ nws: "NWS", nppes: "NPPES", nist: "NIST", nih: "NIH", lda: "Senate LDA", hts: "USITC HTS",
5869
+ bea: "BEA", cbp: "CBP", cpsc: "CPSC", nvd: "NVD", courtlistener: "CourtListener",
5870
+ fpds: "FPDS", gao: "GAO", epa: "EPA", nsn: "NSN",
5871
+ };
5872
+ const TOOL_ACRONYMS = new Set([
5873
+ "naics", "psc", "cfda", "npi", "cve", "csv", "id", "url", "rss", "api", "hts", "sic",
5874
+ "dmepos", "cbp", "sam", "fdic", "epa", "ofac", "far", "dfars", "irs", "usc", "cfr",
5875
+ ]);
5876
+ export function humanizeToolTitle(name) {
5877
+ const tokens = name.split("_");
5878
+ // `fed_register_*` is a two-token source label.
5879
+ let source = tokens[0] ?? "";
5880
+ let rest = tokens.slice(1);
5881
+ if (source === "fed" && tokens[1] === "register") {
5882
+ source = "fed_register";
5883
+ rest = tokens.slice(2);
5884
+ }
5885
+ const label = source === "fed_register" ? "Federal Register" : TOOL_SOURCE_LABELS[source];
5886
+ const words = (label ? rest : tokens)
5887
+ .map((w) => (TOOL_ACRONYMS.has(w) ? w.toUpperCase() : w.charAt(0).toUpperCase() + w.slice(1)))
5888
+ .join(" ");
5889
+ return label ? (words ? `${label}: ${words}` : label) : words;
5890
+ }
5891
+ /** Uniform MCP annotations for a tool: derived title + read-only / open-world hints. */
5892
+ export function toolAnnotations(name) {
5893
+ return { title: humanizeToolTitle(name), readOnlyHint: true, openWorldHint: true };
5894
+ }
5804
5895
  /**
5805
5896
  * Hand-rolled Zod → JSON Schema converter (subset we use).
5806
5897
  */