@pipeworx/mcp-gov-auctions 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/server.json +1 -1
- package/src/index.ts +38 -9
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Government Auctions MCP — physical-asset auctions (surplus, seized, forfeited,
|
|
4
4
|
|
|
5
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
5
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1342+ live data sources.
|
|
6
6
|
|
|
7
7
|
## Tools
|
|
8
8
|
|
|
@@ -23,7 +23,7 @@ Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
|
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Or connect to the full Pipeworx gateway for access to all
|
|
26
|
+
Or connect to the full Pipeworx gateway for access to all 1342+ data sources:
|
|
27
27
|
|
|
28
28
|
```json
|
|
29
29
|
{
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.pipeworx-io/gov-auctions",
|
|
4
4
|
"title": "Gov Auctions",
|
|
5
5
|
"description": "Government Auctions MCP — physical-asset auctions (surplus, seized, forfeited,",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.1",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/gov-auctions",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-gov-auctions",
|
package/src/index.ts
CHANGED
|
@@ -191,17 +191,46 @@ function shapeLot(r: LotRow) {
|
|
|
191
191
|
// Shared filter builder for the active-lot list tools.
|
|
192
192
|
function activeLotFilters(args: Record<string, unknown>): string[] {
|
|
193
193
|
const parts = ['status=eq.active'];
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
// Accept the common param aliases agents reach for (query/q/search/keywords)
|
|
195
|
+
// — previously anything but `keyword` was silently ignored, returning the
|
|
196
|
+
// whole unfiltered pool as if it had matched.
|
|
197
|
+
parts.push(...titleKeywordParts(args));
|
|
198
|
+
const state = String(args.state ?? args.location_state ?? '').trim();
|
|
197
199
|
if (state) parts.push(`location_state=eq.${encodeURIComponent(state.toUpperCase())}`);
|
|
198
|
-
const assetType = String(args.asset_type ?? '').trim();
|
|
200
|
+
const assetType = normalizeAssetType(String(args.asset_type ?? args.category ?? args.type ?? '').trim());
|
|
199
201
|
if (assetType) parts.push(`asset_type=eq.${encodeURIComponent(assetType)}`);
|
|
200
|
-
const source = String(args.source ?? '').trim();
|
|
202
|
+
const source = String(args.source ?? '').trim().toLowerCase();
|
|
201
203
|
if (source) parts.push(`source=eq.${encodeURIComponent(source)}`);
|
|
202
204
|
return parts;
|
|
203
205
|
}
|
|
204
206
|
|
|
207
|
+
// Keyword → PostgREST title filters, shared by all keyword tools. Accepts the
|
|
208
|
+
// param aliases agents use (query/q/search/keywords), and tokenizes multi-word
|
|
209
|
+
// keywords into AND-ed substring matches so word order/adjacency don't matter.
|
|
210
|
+
function titleKeywordParts(args: Record<string, unknown>): string[] {
|
|
211
|
+
const keyword = String(args.keyword ?? args.query ?? args.q ?? args.search ?? args.keywords ?? '').trim();
|
|
212
|
+
if (!keyword) return [];
|
|
213
|
+
return keyword
|
|
214
|
+
.split(/\s+/)
|
|
215
|
+
.filter((t) => t.length >= 2)
|
|
216
|
+
.slice(0, 6)
|
|
217
|
+
.map((tok) => `title=ilike.*${encodeURIComponent(tok)}*`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Map plural/synonym asset categories agents pass to the enum values.
|
|
221
|
+
function normalizeAssetType(raw: string): string {
|
|
222
|
+
if (!raw) return '';
|
|
223
|
+
const t = raw.toLowerCase();
|
|
224
|
+
const map: Record<string, string> = {
|
|
225
|
+
vehicles: 'vehicle', car: 'vehicle', cars: 'vehicle', truck: 'vehicle', trucks: 'vehicle', auto: 'vehicle',
|
|
226
|
+
equipment: 'equipment', machinery: 'equipment', heavy: 'equipment',
|
|
227
|
+
realestate: 'realestate', 'real estate': 'realestate', property: 'realestate', land: 'realestate',
|
|
228
|
+
electronics: 'electronics', electronic: 'electronics', computers: 'electronics',
|
|
229
|
+
};
|
|
230
|
+
if ((ASSET_TYPES as readonly string[]).includes(t)) return t;
|
|
231
|
+
return map[t] ?? '';
|
|
232
|
+
}
|
|
233
|
+
|
|
205
234
|
async function search(cfg: SupabaseConfig, args: Record<string, unknown>) {
|
|
206
235
|
const parts = activeLotFilters(args);
|
|
207
236
|
if (args.max_price !== undefined && String(args.max_price).trim() !== '') {
|
|
@@ -260,11 +289,11 @@ async function lotDetails(cfg: SupabaseConfig, args: Record<string, unknown>) {
|
|
|
260
289
|
|
|
261
290
|
async function soldComps(cfg: SupabaseConfig, args: Record<string, unknown>) {
|
|
262
291
|
const parts = ['status=eq.closed', 'final_price=not.is.null'];
|
|
263
|
-
const keyword = String(args.keyword ?? '').trim();
|
|
264
|
-
|
|
265
|
-
const assetType = String(args.asset_type ?? '').trim();
|
|
292
|
+
const keyword = String(args.keyword ?? args.query ?? args.q ?? args.search ?? args.keywords ?? '').trim();
|
|
293
|
+
parts.push(...titleKeywordParts(args));
|
|
294
|
+
const assetType = normalizeAssetType(String(args.asset_type ?? args.category ?? args.type ?? '').trim());
|
|
266
295
|
if (assetType) parts.push(`asset_type=eq.${encodeURIComponent(assetType)}`);
|
|
267
|
-
const state = String(args.state ?? '').trim();
|
|
296
|
+
const state = String(args.state ?? args.location_state ?? '').trim();
|
|
268
297
|
if (state) parts.push(`location_state=eq.${encodeURIComponent(state.toUpperCase())}`);
|
|
269
298
|
|
|
270
299
|
// Pull final prices for stats (cap to keep it bounded) + a few recent examples.
|