@mailwoman/mcp 9.2.0 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{cli.ts → lib/cli.ts} +71 -50
- package/{index.ts → lib/index.ts} +2 -2
- package/{layer-guards.ts → lib/layer-guards.ts} +23 -23
- package/{server.ts → lib/server.ts} +1 -1
- package/{tools.ts → lib/tools.ts} +3 -3
- package/out/cli.d.ts +1 -1
- package/out/cli.d.ts.map +1 -1
- package/out/cli.js +45 -36
- package/out/cli.js.map +1 -1
- package/out/index.d.ts +2 -2
- package/out/index.d.ts.map +1 -1
- package/out/index.js +2 -2
- package/out/index.js.map +1 -1
- package/out/layer-guards.d.ts +8 -8
- package/out/layer-guards.d.ts.map +1 -1
- package/out/layer-guards.js +19 -20
- package/out/layer-guards.js.map +1 -1
- package/out/server.d.ts +1 -1
- package/out/server.d.ts.map +1 -1
- package/out/server.js +1 -1
- package/out/server.js.map +1 -1
- package/out/tools.d.ts.map +1 -1
- package/out/tools.js +3 -3
- package/out/tools.js.map +1 -1
- package/package.json +33 -12
package/{cli.ts → lib/cli.ts}
RENAMED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*
|
|
34
34
|
* `mailwoman_filer_lookup` follows the SAME "requires the layer unconditionally" discipline as
|
|
35
35
|
* `mailwoman_bdc_filing_landscape` (`assertFilerDatabaseExists` + `openFilerDatabaseIfPresent`, mirroring
|
|
36
|
-
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (
|
|
36
|
+
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (criterion 4 makes
|
|
37
37
|
* it throw rather than answer unstamped), so a missing filer.db becomes one friendly thrown Error naming the layer.
|
|
38
38
|
*
|
|
39
39
|
* `mailwoman_filer_family` follows the IDENTICAL discipline, reusing the same two guards — `familyRollup`
|
|
@@ -48,27 +48,24 @@
|
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
|
-
import { existsSync } from "node:fs"
|
|
52
|
-
import { DatabaseSync } from "node:sqlite"
|
|
53
|
-
import { parseArgs } from "node:util"
|
|
54
|
-
|
|
55
51
|
import { filingLandscape, plausibilityCheck, type BDCDatabase } from "@mailwoman/bdc"
|
|
56
|
-
import {
|
|
52
|
+
import type { PipelineResult } from "@mailwoman/core"
|
|
53
|
+
import { pathExists } from "@mailwoman/core/fs/readers"
|
|
57
54
|
import { readLayerManifest, type LayerContractDatabase } from "@mailwoman/core/layers"
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
55
|
+
import type { Resolver } from "@mailwoman/core/resolver"
|
|
56
|
+
import { parseArguments } from "@mailwoman/core/scripting/arguments"
|
|
57
|
+
import { mailwomanDataRoot, wofExtractPaths } from "@mailwoman/core/utils"
|
|
58
|
+
import { familyRollup } from "@mailwoman/filer/family-rollup"
|
|
59
|
+
import { filerLookup } from "@mailwoman/filer/filer-lookup"
|
|
60
|
+
import { toFRN, type FRN } from "@mailwoman/filer/frn"
|
|
61
|
+
import { NeuralAddressClassifier, type ScriptRoutedClassifier } from "@mailwoman/neural"
|
|
60
62
|
import { getPOICategory } from "@mailwoman/poi-taxonomy"
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
66
|
-
|
|
67
|
-
createResolverBackend,
|
|
68
|
-
mailwomanDataRoot,
|
|
69
|
-
resolveCandidateDBPath,
|
|
70
|
-
wofShardPaths,
|
|
71
|
-
} from "mailwoman/resolver-backend"
|
|
63
|
+
import { emitOverpassQL } from "@mailwoman/poi-taxonomy/overpass"
|
|
64
|
+
import { createWOFResolver } from "@mailwoman/resolver"
|
|
65
|
+
import { DatabaseClient } from "@mailwoman/sqlite/client"
|
|
66
|
+
import { createRuntimePipeline } from "mailwoman"
|
|
67
|
+
import { geocodeAddress, RegionDatabaseProvider } from "mailwoman/geocode"
|
|
68
|
+
import { buildNoGazetteerMessage, createResolverBackend, resolveCandidateDBPath } from "mailwoman/resolver-backend"
|
|
72
69
|
|
|
73
70
|
import {
|
|
74
71
|
assertBDCDatabaseExists,
|
|
@@ -76,11 +73,11 @@ import {
|
|
|
76
73
|
openBDCDatabaseIfPresent,
|
|
77
74
|
openFilerDatabaseIfPresent,
|
|
78
75
|
openPlausibilityPOIDeps,
|
|
79
|
-
} from "
|
|
80
|
-
import { createMCPServer } from "
|
|
81
|
-
import type { MCPToolDeps } from "
|
|
76
|
+
} from "#layer-guards"
|
|
77
|
+
import { createMCPServer } from "#server"
|
|
78
|
+
import type { MCPToolDeps } from "#tools"
|
|
82
79
|
|
|
83
|
-
const { values } =
|
|
80
|
+
const { values } = parseArguments({
|
|
84
81
|
options: {
|
|
85
82
|
"poi-db": { type: "string" },
|
|
86
83
|
},
|
|
@@ -96,10 +93,16 @@ const poiDatabasePath = values["poi-db"]
|
|
|
96
93
|
/**
|
|
97
94
|
* The shared classifier + resolver, built exactly once on the first call that needs them (see the module header).
|
|
98
95
|
* `NeuralAddressClassifier.loadFromWeights` auto-resolves the bundled `en-US` weights; the resolver backend prefers a
|
|
99
|
-
* configured candidate gazetteer (`$MAILWOMAN_CANDIDATE_DB`) and otherwise falls back to the admin-only WOF
|
|
96
|
+
* configured candidate gazetteer (`$MAILWOMAN_CANDIDATE_DB`) and otherwise falls back to the admin-only WOF extracts
|
|
100
97
|
* already on the data root — same selection `nominatim`/`photon`'s CLIs make.
|
|
101
98
|
*/
|
|
102
|
-
let corePromise:
|
|
99
|
+
let corePromise:
|
|
100
|
+
| Promise<{
|
|
101
|
+
classifier: ScriptRoutedClassifier<NeuralAddressClassifier>
|
|
102
|
+
resolver: Resolver
|
|
103
|
+
databases: RegionDatabaseProvider
|
|
104
|
+
}>
|
|
105
|
+
| undefined
|
|
103
106
|
|
|
104
107
|
/**
|
|
105
108
|
* The four tools that need {@link loadCore} — every path through `getPlainPipeline`/`getPoiPipeline`/`resolveGeocode`.
|
|
@@ -112,15 +115,26 @@ const CORE_BACKED_TOOLS = "mailwoman_parse, mailwoman_geocode, mailwoman_poi_sea
|
|
|
112
115
|
const CORE_FREE_TOOLS =
|
|
113
116
|
"mailwoman_layer_manifest, mailwoman_bdc_filing_landscape, mailwoman_filer_lookup, mailwoman_filer_family"
|
|
114
117
|
|
|
115
|
-
function loadCore(): Promise<{
|
|
118
|
+
function loadCore(): Promise<{
|
|
119
|
+
classifier: ScriptRoutedClassifier
|
|
120
|
+
resolver: Resolver
|
|
121
|
+
databases: RegionDatabaseProvider
|
|
122
|
+
}> {
|
|
116
123
|
corePromise ??= (async () => {
|
|
117
124
|
const resolverMod = await import("@mailwoman/resolver-wof-sqlite")
|
|
118
|
-
const wofPaths =
|
|
119
|
-
|
|
125
|
+
const wofPaths: string[] = []
|
|
126
|
+
|
|
127
|
+
for (const extractPath of wofExtractPaths()) {
|
|
128
|
+
if (await pathExists(extractPath)) {
|
|
129
|
+
wofPaths.push(extractPath)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const candidateDB = await resolveCandidateDBPath()
|
|
120
134
|
|
|
121
135
|
// #1009 friendly-failure discipline, the MCP shape of it. `server.ts` turns a thrown Error into an
|
|
122
136
|
// `isError` tool result carrying `error.message`, so the message an agent reads IS whatever is thrown
|
|
123
|
-
// here — which made the raw internal `
|
|
137
|
+
// here — which made the raw internal `resolveExtracts: at least one extract is required` the first thing a
|
|
124
138
|
// stranger saw from `mailwoman_parse` on a fresh install (measured 2026-08-03 against a standalone
|
|
125
139
|
// `npm install @mailwoman/mcp`). Same preflight as `photon`/`nominatim`/`mailwoman serve`, and the same
|
|
126
140
|
// discovery: #1444 moved the `<data-root>/wof/candidate.db` convention fallback INTO
|
|
@@ -135,7 +149,7 @@ function loadCore(): Promise<{ classifier: NeuralAddressClassifier; resolver: Re
|
|
|
135
149
|
)
|
|
136
150
|
}
|
|
137
151
|
|
|
138
|
-
const backend = createResolverBackend(resolverMod, { wofPaths, candidateDB })
|
|
152
|
+
const backend = await createResolverBackend(resolverMod, { wofPaths, candidateDB })
|
|
139
153
|
const resolver = createWOFResolver(backend)
|
|
140
154
|
|
|
141
155
|
// Same discipline for the model weights. `@mailwoman/neural-weights-en-us` is a declared dependency of
|
|
@@ -143,10 +157,10 @@ function loadCore(): Promise<{ classifier: NeuralAddressClassifier; resolver: Re
|
|
|
143
157
|
// nothing and every core-backed tool answered with `resolveWeights`' raw not-found text. The guard keeps
|
|
144
158
|
// that text (it already names the exact fix command) and adds what an agent mid-conversation needs next:
|
|
145
159
|
// which tools are down and which are not.
|
|
146
|
-
let classifier: NeuralAddressClassifier
|
|
160
|
+
let classifier: ScriptRoutedClassifier<NeuralAddressClassifier>
|
|
147
161
|
|
|
148
162
|
try {
|
|
149
|
-
classifier = await NeuralAddressClassifier.
|
|
163
|
+
classifier = await NeuralAddressClassifier.loadRoutedFromWeights({ locale: "en-US" })
|
|
150
164
|
} catch (error) {
|
|
151
165
|
throw new Error(
|
|
152
166
|
`✗ ${error instanceof Error ? error.message : String(error)}\n\n` +
|
|
@@ -154,9 +168,9 @@ function loadCore(): Promise<{ classifier: NeuralAddressClassifier; resolver: Re
|
|
|
154
168
|
)
|
|
155
169
|
}
|
|
156
170
|
|
|
157
|
-
const
|
|
171
|
+
const databases = await RegionDatabaseProvider.create(resolverMod, mailwomanDataRoot())
|
|
158
172
|
|
|
159
|
-
return { classifier, resolver,
|
|
173
|
+
return { classifier, resolver, databases }
|
|
160
174
|
})()
|
|
161
175
|
|
|
162
176
|
return corePromise
|
|
@@ -207,9 +221,9 @@ async function getPoiPipeline(dbPath: string | undefined): Promise<Pipeline> {
|
|
|
207
221
|
* structurally assignable to `plausibility.ts`'s minimal `GeocodeLike` — no adapter needed.
|
|
208
222
|
*/
|
|
209
223
|
async function resolveGeocode(address: string) {
|
|
210
|
-
const { classifier, resolver,
|
|
224
|
+
const { classifier, resolver, databases } = await loadCore()
|
|
211
225
|
|
|
212
|
-
return geocodeAddress(address, { classifier, resolver,
|
|
226
|
+
return geocodeAddress(address, { classifier, resolver, databases: databases.for })
|
|
213
227
|
}
|
|
214
228
|
|
|
215
229
|
const deps: MCPToolDeps = {
|
|
@@ -247,15 +261,22 @@ const deps: MCPToolDeps = {
|
|
|
247
261
|
}
|
|
248
262
|
|
|
249
263
|
const { subject } = outcome.intent
|
|
250
|
-
const osmTag = subject.kind === "category" ? getPOICategory(subject.categoryID)?.osmTag : undefined
|
|
251
264
|
|
|
252
|
-
|
|
265
|
+
// One tag per category the subject reaches, and only when EVERY member carries one: a union emitted from the
|
|
266
|
+
// subset that happens to have an `osmTag` is a narrower query than the POI branch ran.
|
|
267
|
+
const osmTags =
|
|
268
|
+
subject.kind === "category"
|
|
269
|
+
? subject.categoryIDs.map((id) => getPOICategory(id)?.osmTag).filter((tag) => tag !== undefined)
|
|
270
|
+
: []
|
|
271
|
+
|
|
272
|
+
return emitOverpassQL(
|
|
273
|
+
outcome.intent,
|
|
274
|
+
subject.kind === "category" && osmTags.length === subject.categoryIDs.length ? { osmTags } : {}
|
|
275
|
+
)
|
|
253
276
|
},
|
|
254
277
|
|
|
255
278
|
async layerManifest(databasePath) {
|
|
256
|
-
using db = new DatabaseClient<LayerContractDatabase>({
|
|
257
|
-
database: new DatabaseSync(databasePath, { readOnly: true }),
|
|
258
|
-
})
|
|
279
|
+
using db = new DatabaseClient<LayerContractDatabase>(databasePath, { readOnly: true })
|
|
259
280
|
|
|
260
281
|
const manifest = await readLayerManifest(db)
|
|
261
282
|
|
|
@@ -275,15 +296,15 @@ const deps: MCPToolDeps = {
|
|
|
275
296
|
// Decision 6: `mailwoman_bdc_filing_landscape` requires bdc.db unconditionally (no optional-dep
|
|
276
297
|
// abstain shape exists for this tool), so a missing file becomes a friendly thrown Error naming the layer —
|
|
277
298
|
// never the raw `node:sqlite` "unable to open database file" message.
|
|
278
|
-
assertBDCDatabaseExists("mailwoman_bdc_filing_landscape", q.databasePath)
|
|
299
|
+
await assertBDCDatabaseExists("mailwoman_bdc_filing_landscape", q.databasePath)
|
|
279
300
|
|
|
280
|
-
using db = new DatabaseClient<BDCDatabase>(
|
|
301
|
+
using db = new DatabaseClient<BDCDatabase>(q.databasePath, { readOnly: true })
|
|
281
302
|
|
|
282
303
|
return filingLandscape(db, { geoids: q.geoids, h3Cells: q.h3Cells })
|
|
283
304
|
},
|
|
284
305
|
|
|
285
306
|
async plausibilityCheck(q) {
|
|
286
|
-
const bdcDB = openBDCDatabaseIfPresent(q.bdcDatabasePath)
|
|
307
|
+
const bdcDB = await openBDCDatabaseIfPresent(q.bdcDatabasePath)
|
|
287
308
|
const poi = await openPlausibilityPOIDeps(q.poiDatabasePath)
|
|
288
309
|
|
|
289
310
|
try {
|
|
@@ -304,12 +325,12 @@ const deps: MCPToolDeps = {
|
|
|
304
325
|
},
|
|
305
326
|
|
|
306
327
|
async filerLookup(q) {
|
|
307
|
-
// Decision 6/
|
|
328
|
+
// Decision 6 / criterion 4: filerLookup has no optional-dep abstain shape — it throws rather than
|
|
308
329
|
// answer unstamped — so filer.db is required unconditionally, same discipline as bdc.db is for
|
|
309
330
|
// mailwoman_bdc_filing_landscape.
|
|
310
|
-
assertFilerDatabaseExists("mailwoman_filer_lookup", q.databasePath)
|
|
331
|
+
await assertFilerDatabaseExists("mailwoman_filer_lookup", q.databasePath)
|
|
311
332
|
|
|
312
|
-
using db = openFilerDatabaseIfPresent(q.databasePath)!
|
|
333
|
+
using db = (await openFilerDatabaseIfPresent(q.databasePath))!
|
|
313
334
|
|
|
314
335
|
let frn: FRN | undefined
|
|
315
336
|
|
|
@@ -323,7 +344,7 @@ const deps: MCPToolDeps = {
|
|
|
323
344
|
frn = parsed
|
|
324
345
|
}
|
|
325
346
|
|
|
326
|
-
return filerLookup(db, {
|
|
347
|
+
return await filerLookup(db, {
|
|
327
348
|
frn,
|
|
328
349
|
form499ID: q.form499ID,
|
|
329
350
|
bdcProviderID: q.bdcProviderID,
|
|
@@ -334,9 +355,9 @@ const deps: MCPToolDeps = {
|
|
|
334
355
|
async filerFamily(q) {
|
|
335
356
|
// Same discipline as mailwoman_filer_lookup — familyRollup has no optional-dep abstain shape
|
|
336
357
|
// either, so filer.db is required unconditionally.
|
|
337
|
-
assertFilerDatabaseExists("mailwoman_filer_family", q.databasePath)
|
|
358
|
+
await assertFilerDatabaseExists("mailwoman_filer_family", q.databasePath)
|
|
338
359
|
|
|
339
|
-
using db = openFilerDatabaseIfPresent(q.databasePath)!
|
|
360
|
+
using db = (await openFilerDatabaseIfPresent(q.databasePath))!
|
|
340
361
|
|
|
341
362
|
return familyRollup(db, {
|
|
342
363
|
familyID: q.familyID,
|
|
@@ -19,27 +19,27 @@
|
|
|
19
19
|
* instead of the raw `node:sqlite` "unable to open database file" message.
|
|
20
20
|
* - `openFilerDatabaseIfPresent` / `assertFilerDatabaseExists` — the SAME pairing, for filer.db.
|
|
21
21
|
* `mailwoman_filer_lookup` requires filer.db unconditionally (mirrors `mailwoman_bdc_filing_landscape`'s own
|
|
22
|
-
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since
|
|
22
|
+
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since criterion
|
|
23
23
|
* 4 makes it throw rather than answer unstamped), so `cli.ts` pairs `assertFilerDatabaseExists` (the friendly
|
|
24
24
|
* throw) with `openFilerDatabaseIfPresent` (the actual open) the same way `bdcFilingLandscape`'s handler does.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import { existsSync } from "node:fs"
|
|
28
|
-
import { DatabaseSync } from "node:sqlite"
|
|
29
|
-
|
|
30
27
|
import type { BDCDatabase, PlausibilityDeps } from "@mailwoman/bdc"
|
|
31
|
-
import {
|
|
32
|
-
import type { LayerContractDatabase } from "@mailwoman/core/layers"
|
|
28
|
+
import { pathExists } from "@mailwoman/core/fs/readers"
|
|
33
29
|
import type { FilerDatabase } from "@mailwoman/filer"
|
|
30
|
+
import type { POIDatabase } from "@mailwoman/resolver-wof-sqlite/poi"
|
|
31
|
+
import { DatabaseClient } from "@mailwoman/sqlite/client"
|
|
34
32
|
|
|
35
33
|
/**
|
|
36
34
|
* Open a bdc.db, or return `undefined` when `databasePath` is unset or the file is missing — NEVER a raw sqlite throw.
|
|
37
35
|
* See the module header.
|
|
38
36
|
*/
|
|
39
|
-
export function openBDCDatabaseIfPresent(
|
|
40
|
-
|
|
37
|
+
export async function openBDCDatabaseIfPresent(
|
|
38
|
+
databasePath: string | undefined
|
|
39
|
+
): Promise<DatabaseClient<BDCDatabase> | undefined> {
|
|
40
|
+
if (!databasePath || !(await pathExists(databasePath))) return undefined
|
|
41
41
|
|
|
42
|
-
return new DatabaseClient<BDCDatabase>(
|
|
42
|
+
return new DatabaseClient<BDCDatabase>(databasePath, { readOnly: true })
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
@@ -53,14 +53,14 @@ export function openBDCDatabaseIfPresent(databasePath: string | undefined): Data
|
|
|
53
53
|
* (constructed with `{database}`, not `{databasePath}` — see `poi-lookup.ts`), so it never double-closes.
|
|
54
54
|
*/
|
|
55
55
|
export async function openPlausibilityPOIDeps(databasePath: string | undefined): Promise<PlausibilityDeps["poi"]> {
|
|
56
|
-
if (!databasePath || !
|
|
56
|
+
if (!databasePath || !(await pathExists(databasePath))) return undefined
|
|
57
57
|
|
|
58
|
-
const { POILookup } = await import("@mailwoman/resolver-wof-sqlite/poi
|
|
59
|
-
const database = new
|
|
58
|
+
const { POILookup } = await import("@mailwoman/resolver-wof-sqlite/poi")
|
|
59
|
+
const database = new DatabaseClient<POIDatabase>(databasePath, { readOnly: true })
|
|
60
60
|
|
|
61
61
|
return {
|
|
62
62
|
lookup: new POILookup({ database }),
|
|
63
|
-
contractDB:
|
|
63
|
+
contractDB: database,
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -69,8 +69,8 @@ export async function openPlausibilityPOIDeps(databasePath: string | undefined):
|
|
|
69
69
|
* (decision 6b). `toolName` is threaded through so the message matches whichever tool calls this (today: only
|
|
70
70
|
* `mailwoman_bdc_filing_landscape`).
|
|
71
71
|
*/
|
|
72
|
-
export function assertBDCDatabaseExists(toolName: string, databasePath: string): void {
|
|
73
|
-
if (!
|
|
72
|
+
export async function assertBDCDatabaseExists(toolName: string, databasePath: string): Promise<void> {
|
|
73
|
+
if (!(await pathExists(databasePath))) {
|
|
74
74
|
throw new Error(`${toolName}: bdc.db not found at "${databasePath}"`)
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -80,22 +80,22 @@ export function assertBDCDatabaseExists(toolName: string, databasePath: string):
|
|
|
80
80
|
* (mirroring {@link openBDCDatabaseIfPresent}). Used by `cli.ts`'s `mailwoman_filer_lookup` handler after
|
|
81
81
|
* {@link assertFilerDatabaseExists} has already confirmed the file is present.
|
|
82
82
|
*/
|
|
83
|
-
export function openFilerDatabaseIfPresent(
|
|
83
|
+
export async function openFilerDatabaseIfPresent(
|
|
84
84
|
databasePath: string | undefined
|
|
85
|
-
): DatabaseClient<FilerDatabase> | undefined {
|
|
86
|
-
if (!databasePath || !
|
|
85
|
+
): Promise<DatabaseClient<FilerDatabase> | undefined> {
|
|
86
|
+
if (!databasePath || !(await pathExists(databasePath))) return undefined
|
|
87
87
|
|
|
88
|
-
return new DatabaseClient<FilerDatabase>(
|
|
88
|
+
return new DatabaseClient<FilerDatabase>(databasePath, { readOnly: true })
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Throws a friendly Error naming the layer when `databasePath` doesn't exist — `mailwoman_filer_lookup`'s guard
|
|
93
|
-
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (
|
|
94
|
-
* throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
93
|
+
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (criterion 4
|
|
94
|
+
* makes it throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
95
95
|
* `mailwoman_bdc_filing_landscape`.
|
|
96
96
|
*/
|
|
97
|
-
export function assertFilerDatabaseExists(toolName: string, databasePath: string): void {
|
|
98
|
-
if (!
|
|
97
|
+
export async function assertFilerDatabaseExists(toolName: string, databasePath: string): Promise<void> {
|
|
98
|
+
if (!(await pathExists(databasePath))) {
|
|
99
99
|
throw new Error(`${toolName}: filer.db not found at "${databasePath}"`)
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
|
|
12
12
|
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"
|
|
13
13
|
|
|
14
|
-
import { buildToolTable, type MCPToolDeps } from "
|
|
14
|
+
import { buildToolTable, type MCPToolDeps } from "#tools"
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The advertised server version — keep in lockstep with `package.json`'s `version` (not read from it dynamically: a
|
|
@@ -105,7 +105,7 @@ const POISearchInputSchema = z.object({
|
|
|
105
105
|
poiDatabasePath: z
|
|
106
106
|
.string()
|
|
107
107
|
.optional()
|
|
108
|
-
.describe("Path to a specific poi.db
|
|
108
|
+
.describe("Path to a specific poi.db extract to search. Omit to use the server's configured default (if any)."),
|
|
109
109
|
})
|
|
110
110
|
|
|
111
111
|
const OverpassExportInputSchema = z.object({
|
|
@@ -119,7 +119,7 @@ const LayerManifestInputSchema = z.object({
|
|
|
119
119
|
databasePath: z
|
|
120
120
|
.string()
|
|
121
121
|
.min(1)
|
|
122
|
-
.describe("Path to a mailwoman spatial-layer database (poi.db, an address-points
|
|
122
|
+
.describe("Path to a mailwoman spatial-layer database (poi.db, an address-points extract, etc.)."),
|
|
123
123
|
})
|
|
124
124
|
|
|
125
125
|
const BDCFilingLandscapeInputSchema = z.object({
|
|
@@ -314,7 +314,7 @@ export function buildToolTable(deps: MCPToolDeps): MCPToolDef[] {
|
|
|
314
314
|
{
|
|
315
315
|
name: "mailwoman_layer_manifest",
|
|
316
316
|
description:
|
|
317
|
-
"Inspect a mailwoman spatial-layer database (poi.db, an address-points
|
|
317
|
+
"Inspect a mailwoman spatial-layer database (poi.db, an address-points extract, etc.): read its provenance " +
|
|
318
318
|
"and licensing manifest (source, vintage, build command, license) plus a coverage summary (how many H3 " +
|
|
319
319
|
"cells were surveyed, average completeness, total observed rows). Use this to check what a layer " +
|
|
320
320
|
"actually covers before relying on it.",
|
package/out/cli.d.ts
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*
|
|
34
34
|
* `mailwoman_filer_lookup` follows the SAME "requires the layer unconditionally" discipline as
|
|
35
35
|
* `mailwoman_bdc_filing_landscape` (`assertFilerDatabaseExists` + `openFilerDatabaseIfPresent`, mirroring
|
|
36
|
-
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (
|
|
36
|
+
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (criterion 4 makes
|
|
37
37
|
* it throw rather than answer unstamped), so a missing filer.db becomes one friendly thrown Error naming the layer.
|
|
38
38
|
*
|
|
39
39
|
* `mailwoman_filer_family` follows the IDENTICAL discipline, reusing the same two guards — `familyRollup`
|
package/out/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG"}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../lib/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG"}
|
package/out/cli.js
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*
|
|
34
34
|
* `mailwoman_filer_lookup` follows the SAME "requires the layer unconditionally" discipline as
|
|
35
35
|
* `mailwoman_bdc_filing_landscape` (`assertFilerDatabaseExists` + `openFilerDatabaseIfPresent`, mirroring
|
|
36
|
-
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (
|
|
36
|
+
* `assertBDCDatabaseExists` + the BDC open) — `filerLookup` itself has no optional-dep abstain shape (criterion 4 makes
|
|
37
37
|
* it throw rather than answer unstamped), so a missing filer.db becomes one friendly thrown Error naming the layer.
|
|
38
38
|
*
|
|
39
39
|
* `mailwoman_filer_family` follows the IDENTICAL discipline, reusing the same two guards — `familyRollup`
|
|
@@ -47,23 +47,25 @@
|
|
|
47
47
|
* mailwoman-mcp --poi-db poi.db # mailwoman_poi_search additionally executes against poi.db
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
|
-
import { existsSync } from "node:fs";
|
|
51
|
-
import { DatabaseSync } from "node:sqlite";
|
|
52
|
-
import { parseArgs } from "node:util";
|
|
53
50
|
import { filingLandscape, plausibilityCheck } from "@mailwoman/bdc";
|
|
54
|
-
import {
|
|
51
|
+
import { pathExists } from "@mailwoman/core/fs/readers";
|
|
55
52
|
import { readLayerManifest } from "@mailwoman/core/layers";
|
|
56
|
-
import {
|
|
53
|
+
import { parseArguments } from "@mailwoman/core/scripting/arguments";
|
|
54
|
+
import { mailwomanDataRoot, wofExtractPaths } from "@mailwoman/core/utils";
|
|
55
|
+
import { familyRollup } from "@mailwoman/filer/family-rollup";
|
|
56
|
+
import { filerLookup } from "@mailwoman/filer/filer-lookup";
|
|
57
|
+
import { toFRN } from "@mailwoman/filer/frn";
|
|
57
58
|
import { NeuralAddressClassifier } from "@mailwoman/neural";
|
|
58
59
|
import { getPOICategory } from "@mailwoman/poi-taxonomy";
|
|
60
|
+
import { emitOverpassQL } from "@mailwoman/poi-taxonomy/overpass";
|
|
59
61
|
import { createWOFResolver } from "@mailwoman/resolver";
|
|
62
|
+
import { DatabaseClient } from "@mailwoman/sqlite/client";
|
|
60
63
|
import { createRuntimePipeline } from "mailwoman";
|
|
61
|
-
import { geocodeAddress,
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
|
|
66
|
-
const { values } = parseArgs({
|
|
64
|
+
import { geocodeAddress, RegionDatabaseProvider } from "mailwoman/geocode";
|
|
65
|
+
import { buildNoGazetteerMessage, createResolverBackend, resolveCandidateDBPath } from "mailwoman/resolver-backend";
|
|
66
|
+
import { assertBDCDatabaseExists, assertFilerDatabaseExists, openBDCDatabaseIfPresent, openFilerDatabaseIfPresent, openPlausibilityPOIDeps, } from "#layer-guards";
|
|
67
|
+
import { createMCPServer } from "#server";
|
|
68
|
+
const { values } = parseArguments({
|
|
67
69
|
options: {
|
|
68
70
|
"poi-db": { type: "string" },
|
|
69
71
|
},
|
|
@@ -77,7 +79,7 @@ const poiDatabasePath = values["poi-db"];
|
|
|
77
79
|
/**
|
|
78
80
|
* The shared classifier + resolver, built exactly once on the first call that needs them (see the module header).
|
|
79
81
|
* `NeuralAddressClassifier.loadFromWeights` auto-resolves the bundled `en-US` weights; the resolver backend prefers a
|
|
80
|
-
* configured candidate gazetteer (`$MAILWOMAN_CANDIDATE_DB`) and otherwise falls back to the admin-only WOF
|
|
82
|
+
* configured candidate gazetteer (`$MAILWOMAN_CANDIDATE_DB`) and otherwise falls back to the admin-only WOF extracts
|
|
81
83
|
* already on the data root — same selection `nominatim`/`photon`'s CLIs make.
|
|
82
84
|
*/
|
|
83
85
|
let corePromise;
|
|
@@ -92,11 +94,16 @@ const CORE_FREE_TOOLS = "mailwoman_layer_manifest, mailwoman_bdc_filing_landscap
|
|
|
92
94
|
function loadCore() {
|
|
93
95
|
corePromise ??= (async () => {
|
|
94
96
|
const resolverMod = await import("@mailwoman/resolver-wof-sqlite");
|
|
95
|
-
const wofPaths =
|
|
96
|
-
const
|
|
97
|
+
const wofPaths = [];
|
|
98
|
+
for (const extractPath of wofExtractPaths()) {
|
|
99
|
+
if (await pathExists(extractPath)) {
|
|
100
|
+
wofPaths.push(extractPath);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const candidateDB = await resolveCandidateDBPath();
|
|
97
104
|
// #1009 friendly-failure discipline, the MCP shape of it. `server.ts` turns a thrown Error into an
|
|
98
105
|
// `isError` tool result carrying `error.message`, so the message an agent reads IS whatever is thrown
|
|
99
|
-
// here — which made the raw internal `
|
|
106
|
+
// here — which made the raw internal `resolveExtracts: at least one extract is required` the first thing a
|
|
100
107
|
// stranger saw from `mailwoman_parse` on a fresh install (measured 2026-08-03 against a standalone
|
|
101
108
|
// `npm install @mailwoman/mcp`). Same preflight as `photon`/`nominatim`/`mailwoman serve`, and the same
|
|
102
109
|
// discovery: #1444 moved the `<data-root>/wof/candidate.db` convention fallback INTO
|
|
@@ -108,7 +115,7 @@ function loadCore() {
|
|
|
108
115
|
docsPath: "/docs/developers/how-to/use-the-mcp-server",
|
|
109
116
|
})}\n\n Needs it: ${CORE_BACKED_TOOLS}\n Works without it: ${CORE_FREE_TOOLS}`);
|
|
110
117
|
}
|
|
111
|
-
const backend = createResolverBackend(resolverMod, { wofPaths, candidateDB });
|
|
118
|
+
const backend = await createResolverBackend(resolverMod, { wofPaths, candidateDB });
|
|
112
119
|
const resolver = createWOFResolver(backend);
|
|
113
120
|
// Same discipline for the model weights. `@mailwoman/neural-weights-en-us` is a declared dependency of
|
|
114
121
|
// this package as of 2026-08-03 — before that a standalone `npm install @mailwoman/mcp` resolved
|
|
@@ -117,14 +124,14 @@ function loadCore() {
|
|
|
117
124
|
// which tools are down and which are not.
|
|
118
125
|
let classifier;
|
|
119
126
|
try {
|
|
120
|
-
classifier = await NeuralAddressClassifier.
|
|
127
|
+
classifier = await NeuralAddressClassifier.loadRoutedFromWeights({ locale: "en-US" });
|
|
121
128
|
}
|
|
122
129
|
catch (error) {
|
|
123
130
|
throw new Error(`✗ ${error instanceof Error ? error.message : String(error)}\n\n` +
|
|
124
131
|
` Needs it: ${CORE_BACKED_TOOLS}\n Works without it: ${CORE_FREE_TOOLS}`);
|
|
125
132
|
}
|
|
126
|
-
const
|
|
127
|
-
return { classifier, resolver,
|
|
133
|
+
const databases = await RegionDatabaseProvider.create(resolverMod, mailwomanDataRoot());
|
|
134
|
+
return { classifier, resolver, databases };
|
|
128
135
|
})();
|
|
129
136
|
return corePromise;
|
|
130
137
|
}
|
|
@@ -163,8 +170,8 @@ async function getPoiPipeline(dbPath) {
|
|
|
163
170
|
* structurally assignable to `plausibility.ts`'s minimal `GeocodeLike` — no adapter needed.
|
|
164
171
|
*/
|
|
165
172
|
async function resolveGeocode(address) {
|
|
166
|
-
const { classifier, resolver,
|
|
167
|
-
return geocodeAddress(address, { classifier, resolver,
|
|
173
|
+
const { classifier, resolver, databases } = await loadCore();
|
|
174
|
+
return geocodeAddress(address, { classifier, resolver, databases: databases.for });
|
|
168
175
|
}
|
|
169
176
|
const deps = {
|
|
170
177
|
async parse(text, opts) {
|
|
@@ -191,13 +198,15 @@ const deps = {
|
|
|
191
198
|
throw new Error(`mailwoman_overpass_export: query is not POI-shaped (${outcome?.type ?? "no poi intent"}${reason})`);
|
|
192
199
|
}
|
|
193
200
|
const { subject } = outcome.intent;
|
|
194
|
-
|
|
195
|
-
|
|
201
|
+
// One tag per category the subject reaches, and only when EVERY member carries one: a union emitted from the
|
|
202
|
+
// subset that happens to have an `osmTag` is a narrower query than the POI branch ran.
|
|
203
|
+
const osmTags = subject.kind === "category"
|
|
204
|
+
? subject.categoryIDs.map((id) => getPOICategory(id)?.osmTag).filter((tag) => tag !== undefined)
|
|
205
|
+
: [];
|
|
206
|
+
return emitOverpassQL(outcome.intent, subject.kind === "category" && osmTags.length === subject.categoryIDs.length ? { osmTags } : {});
|
|
196
207
|
},
|
|
197
208
|
async layerManifest(databasePath) {
|
|
198
|
-
using db = new DatabaseClient({
|
|
199
|
-
database: new DatabaseSync(databasePath, { readOnly: true }),
|
|
200
|
-
});
|
|
209
|
+
using db = new DatabaseClient(databasePath, { readOnly: true });
|
|
201
210
|
const manifest = await readLayerManifest(db);
|
|
202
211
|
const coverage = await db
|
|
203
212
|
.selectFrom("layer_coverage")
|
|
@@ -213,12 +222,12 @@ const deps = {
|
|
|
213
222
|
// Decision 6: `mailwoman_bdc_filing_landscape` requires bdc.db unconditionally (no optional-dep
|
|
214
223
|
// abstain shape exists for this tool), so a missing file becomes a friendly thrown Error naming the layer —
|
|
215
224
|
// never the raw `node:sqlite` "unable to open database file" message.
|
|
216
|
-
assertBDCDatabaseExists("mailwoman_bdc_filing_landscape", q.databasePath);
|
|
217
|
-
using db = new DatabaseClient(
|
|
225
|
+
await assertBDCDatabaseExists("mailwoman_bdc_filing_landscape", q.databasePath);
|
|
226
|
+
using db = new DatabaseClient(q.databasePath, { readOnly: true });
|
|
218
227
|
return filingLandscape(db, { geoids: q.geoids, h3Cells: q.h3Cells });
|
|
219
228
|
},
|
|
220
229
|
async plausibilityCheck(q) {
|
|
221
|
-
const bdcDB = openBDCDatabaseIfPresent(q.bdcDatabasePath);
|
|
230
|
+
const bdcDB = await openBDCDatabaseIfPresent(q.bdcDatabasePath);
|
|
222
231
|
const poi = await openPlausibilityPOIDeps(q.poiDatabasePath);
|
|
223
232
|
try {
|
|
224
233
|
return await plausibilityCheck({
|
|
@@ -235,11 +244,11 @@ const deps = {
|
|
|
235
244
|
}
|
|
236
245
|
},
|
|
237
246
|
async filerLookup(q) {
|
|
238
|
-
// Decision 6/
|
|
247
|
+
// Decision 6 / criterion 4: filerLookup has no optional-dep abstain shape — it throws rather than
|
|
239
248
|
// answer unstamped — so filer.db is required unconditionally, same discipline as bdc.db is for
|
|
240
249
|
// mailwoman_bdc_filing_landscape.
|
|
241
|
-
assertFilerDatabaseExists("mailwoman_filer_lookup", q.databasePath);
|
|
242
|
-
using db = openFilerDatabaseIfPresent(q.databasePath);
|
|
250
|
+
await assertFilerDatabaseExists("mailwoman_filer_lookup", q.databasePath);
|
|
251
|
+
using db = (await openFilerDatabaseIfPresent(q.databasePath));
|
|
243
252
|
let frn;
|
|
244
253
|
if (q.frn !== undefined) {
|
|
245
254
|
const parsed = toFRN(q.frn);
|
|
@@ -248,7 +257,7 @@ const deps = {
|
|
|
248
257
|
}
|
|
249
258
|
frn = parsed;
|
|
250
259
|
}
|
|
251
|
-
return filerLookup(db, {
|
|
260
|
+
return await filerLookup(db, {
|
|
252
261
|
frn,
|
|
253
262
|
form499ID: q.form499ID,
|
|
254
263
|
bdcProviderID: q.bdcProviderID,
|
|
@@ -258,8 +267,8 @@ const deps = {
|
|
|
258
267
|
async filerFamily(q) {
|
|
259
268
|
// Same discipline as mailwoman_filer_lookup — familyRollup has no optional-dep abstain shape
|
|
260
269
|
// either, so filer.db is required unconditionally.
|
|
261
|
-
assertFilerDatabaseExists("mailwoman_filer_family", q.databasePath);
|
|
262
|
-
using db = openFilerDatabaseIfPresent(q.databasePath);
|
|
270
|
+
await assertFilerDatabaseExists("mailwoman_filer_family", q.databasePath);
|
|
271
|
+
using db = (await openFilerDatabaseIfPresent(q.databasePath));
|
|
263
272
|
return familyRollup(db, {
|
|
264
273
|
familyID: q.familyID,
|
|
265
274
|
nodeID: q.nodeID,
|
package/out/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../lib/cli.ts"],"names":[],"mappings":"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"}
|
package/out/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
* `@mailwoman/mcp` public surface — the tool table + server factory, for a caller embedding the MCP server
|
|
7
7
|
* directly (custom transport, alternate deps) instead of running `mailwoman-mcp` as a subprocess.
|
|
8
8
|
*/
|
|
9
|
-
export * from "
|
|
10
|
-
export * from "
|
|
9
|
+
export * from "#server";
|
|
10
|
+
export * from "#tools";
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/out/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA"}
|
package/out/index.js
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
* `@mailwoman/mcp` public surface — the tool table + server factory, for a caller embedding the MCP server
|
|
7
7
|
* directly (custom transport, alternate deps) instead of running `mailwoman-mcp` as a subprocess.
|
|
8
8
|
*/
|
|
9
|
-
export * from "
|
|
10
|
-
export * from "
|
|
9
|
+
export * from "#server";
|
|
10
|
+
export * from "#tools";
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/out/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA"}
|
package/out/layer-guards.d.ts
CHANGED
|
@@ -19,18 +19,18 @@
|
|
|
19
19
|
* instead of the raw `node:sqlite` "unable to open database file" message.
|
|
20
20
|
* - `openFilerDatabaseIfPresent` / `assertFilerDatabaseExists` — the SAME pairing, for filer.db.
|
|
21
21
|
* `mailwoman_filer_lookup` requires filer.db unconditionally (mirrors `mailwoman_bdc_filing_landscape`'s own
|
|
22
|
-
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since
|
|
22
|
+
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since criterion
|
|
23
23
|
* 4 makes it throw rather than answer unstamped), so `cli.ts` pairs `assertFilerDatabaseExists` (the friendly
|
|
24
24
|
* throw) with `openFilerDatabaseIfPresent` (the actual open) the same way `bdcFilingLandscape`'s handler does.
|
|
25
25
|
*/
|
|
26
26
|
import type { BDCDatabase, PlausibilityDeps } from "@mailwoman/bdc";
|
|
27
|
-
import { DatabaseClient } from "@mailwoman/core/kysley/client";
|
|
28
27
|
import type { FilerDatabase } from "@mailwoman/filer";
|
|
28
|
+
import { DatabaseClient } from "@mailwoman/sqlite/client";
|
|
29
29
|
/**
|
|
30
30
|
* Open a bdc.db, or return `undefined` when `databasePath` is unset or the file is missing — NEVER a raw sqlite throw.
|
|
31
31
|
* See the module header.
|
|
32
32
|
*/
|
|
33
|
-
export declare function openBDCDatabaseIfPresent(databasePath: string | undefined): DatabaseClient<BDCDatabase> | undefined
|
|
33
|
+
export declare function openBDCDatabaseIfPresent(databasePath: string | undefined): Promise<DatabaseClient<BDCDatabase> | undefined>;
|
|
34
34
|
/**
|
|
35
35
|
* Same graceful discipline as {@link openBDCDatabaseIfPresent}, for the poi.db side of `plausibilityCheck`'s deps —
|
|
36
36
|
* `undefined` here becomes the `{type:"abstain", reason:"requires_build_local_layer"}` entry `plausibilityCheck`
|
|
@@ -47,18 +47,18 @@ export declare function openPlausibilityPOIDeps(databasePath: string | undefined
|
|
|
47
47
|
* (decision 6b). `toolName` is threaded through so the message matches whichever tool calls this (today: only
|
|
48
48
|
* `mailwoman_bdc_filing_landscape`).
|
|
49
49
|
*/
|
|
50
|
-
export declare function assertBDCDatabaseExists(toolName: string, databasePath: string): void
|
|
50
|
+
export declare function assertBDCDatabaseExists(toolName: string, databasePath: string): Promise<void>;
|
|
51
51
|
/**
|
|
52
52
|
* Open a filer.db, or return `undefined` when `databasePath` is unset or the file is missing — NEVER a raw sqlite throw
|
|
53
53
|
* (mirroring {@link openBDCDatabaseIfPresent}). Used by `cli.ts`'s `mailwoman_filer_lookup` handler after
|
|
54
54
|
* {@link assertFilerDatabaseExists} has already confirmed the file is present.
|
|
55
55
|
*/
|
|
56
|
-
export declare function openFilerDatabaseIfPresent(databasePath: string | undefined): DatabaseClient<FilerDatabase> | undefined
|
|
56
|
+
export declare function openFilerDatabaseIfPresent(databasePath: string | undefined): Promise<DatabaseClient<FilerDatabase> | undefined>;
|
|
57
57
|
/**
|
|
58
58
|
* Throws a friendly Error naming the layer when `databasePath` doesn't exist — `mailwoman_filer_lookup`'s guard
|
|
59
|
-
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (
|
|
60
|
-
* throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
59
|
+
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (criterion 4
|
|
60
|
+
* makes it throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
61
61
|
* `mailwoman_bdc_filing_landscape`.
|
|
62
62
|
*/
|
|
63
|
-
export declare function assertFilerDatabaseExists(toolName: string, databasePath: string): void
|
|
63
|
+
export declare function assertFilerDatabaseExists(toolName: string, databasePath: string): Promise<void>;
|
|
64
64
|
//# sourceMappingURL=layer-guards.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-guards.d.ts","sourceRoot":"","sources":["../layer-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;
|
|
1
|
+
{"version":3,"file":"layer-guards.d.ts","sourceRoot":"","sources":["../lib/layer-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC7C,YAAY,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,CAIlD;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAUhH;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAInG;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC/C,YAAY,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC,CAIpD;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrG"}
|
package/out/layer-guards.js
CHANGED
|
@@ -19,21 +19,20 @@
|
|
|
19
19
|
* instead of the raw `node:sqlite` "unable to open database file" message.
|
|
20
20
|
* - `openFilerDatabaseIfPresent` / `assertFilerDatabaseExists` — the SAME pairing, for filer.db.
|
|
21
21
|
* `mailwoman_filer_lookup` requires filer.db unconditionally (mirrors `mailwoman_bdc_filing_landscape`'s own
|
|
22
|
-
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since
|
|
22
|
+
* "requires the layer" discipline — `filerLookup` itself has no optional-dep abstain shape either, since criterion
|
|
23
23
|
* 4 makes it throw rather than answer unstamped), so `cli.ts` pairs `assertFilerDatabaseExists` (the friendly
|
|
24
24
|
* throw) with `openFilerDatabaseIfPresent` (the actual open) the same way `bdcFilingLandscape`'s handler does.
|
|
25
25
|
*/
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { DatabaseClient } from "@mailwoman/core/kysley/client";
|
|
26
|
+
import { pathExists } from "@mailwoman/core/fs/readers";
|
|
27
|
+
import { DatabaseClient } from "@mailwoman/sqlite/client";
|
|
29
28
|
/**
|
|
30
29
|
* Open a bdc.db, or return `undefined` when `databasePath` is unset or the file is missing — NEVER a raw sqlite throw.
|
|
31
30
|
* See the module header.
|
|
32
31
|
*/
|
|
33
|
-
export function openBDCDatabaseIfPresent(databasePath) {
|
|
34
|
-
if (!databasePath || !
|
|
32
|
+
export async function openBDCDatabaseIfPresent(databasePath) {
|
|
33
|
+
if (!databasePath || !(await pathExists(databasePath)))
|
|
35
34
|
return undefined;
|
|
36
|
-
return new DatabaseClient(
|
|
35
|
+
return new DatabaseClient(databasePath, { readOnly: true });
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
38
|
* Same graceful discipline as {@link openBDCDatabaseIfPresent}, for the poi.db side of `plausibilityCheck`'s deps —
|
|
@@ -46,13 +45,13 @@ export function openBDCDatabaseIfPresent(databasePath) {
|
|
|
46
45
|
* (constructed with `{database}`, not `{databasePath}` — see `poi-lookup.ts`), so it never double-closes.
|
|
47
46
|
*/
|
|
48
47
|
export async function openPlausibilityPOIDeps(databasePath) {
|
|
49
|
-
if (!databasePath || !
|
|
48
|
+
if (!databasePath || !(await pathExists(databasePath)))
|
|
50
49
|
return undefined;
|
|
51
|
-
const { POILookup } = await import("@mailwoman/resolver-wof-sqlite/poi
|
|
52
|
-
const database = new
|
|
50
|
+
const { POILookup } = await import("@mailwoman/resolver-wof-sqlite/poi");
|
|
51
|
+
const database = new DatabaseClient(databasePath, { readOnly: true });
|
|
53
52
|
return {
|
|
54
53
|
lookup: new POILookup({ database }),
|
|
55
|
-
contractDB:
|
|
54
|
+
contractDB: database,
|
|
56
55
|
};
|
|
57
56
|
}
|
|
58
57
|
/**
|
|
@@ -60,8 +59,8 @@ export async function openPlausibilityPOIDeps(databasePath) {
|
|
|
60
59
|
* (decision 6b). `toolName` is threaded through so the message matches whichever tool calls this (today: only
|
|
61
60
|
* `mailwoman_bdc_filing_landscape`).
|
|
62
61
|
*/
|
|
63
|
-
export function assertBDCDatabaseExists(toolName, databasePath) {
|
|
64
|
-
if (!
|
|
62
|
+
export async function assertBDCDatabaseExists(toolName, databasePath) {
|
|
63
|
+
if (!(await pathExists(databasePath))) {
|
|
65
64
|
throw new Error(`${toolName}: bdc.db not found at "${databasePath}"`);
|
|
66
65
|
}
|
|
67
66
|
}
|
|
@@ -70,19 +69,19 @@ export function assertBDCDatabaseExists(toolName, databasePath) {
|
|
|
70
69
|
* (mirroring {@link openBDCDatabaseIfPresent}). Used by `cli.ts`'s `mailwoman_filer_lookup` handler after
|
|
71
70
|
* {@link assertFilerDatabaseExists} has already confirmed the file is present.
|
|
72
71
|
*/
|
|
73
|
-
export function openFilerDatabaseIfPresent(databasePath) {
|
|
74
|
-
if (!databasePath || !
|
|
72
|
+
export async function openFilerDatabaseIfPresent(databasePath) {
|
|
73
|
+
if (!databasePath || !(await pathExists(databasePath)))
|
|
75
74
|
return undefined;
|
|
76
|
-
return new DatabaseClient(
|
|
75
|
+
return new DatabaseClient(databasePath, { readOnly: true });
|
|
77
76
|
}
|
|
78
77
|
/**
|
|
79
78
|
* Throws a friendly Error naming the layer when `databasePath` doesn't exist — `mailwoman_filer_lookup`'s guard
|
|
80
|
-
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (
|
|
81
|
-
* throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
79
|
+
* (mirroring {@link assertBDCDatabaseExists}). `filerLookup` itself has no optional-dep abstain shape (criterion 4
|
|
80
|
+
* makes it throw rather than answer unstamped), so filer.db is required unconditionally, same as bdc.db is for
|
|
82
81
|
* `mailwoman_bdc_filing_landscape`.
|
|
83
82
|
*/
|
|
84
|
-
export function assertFilerDatabaseExists(toolName, databasePath) {
|
|
85
|
-
if (!
|
|
83
|
+
export async function assertFilerDatabaseExists(toolName, databasePath) {
|
|
84
|
+
if (!(await pathExists(databasePath))) {
|
|
86
85
|
throw new Error(`${toolName}: filer.db not found at "${databasePath}"`);
|
|
87
86
|
}
|
|
88
87
|
}
|
package/out/layer-guards.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-guards.js","sourceRoot":"","sources":["../layer-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;
|
|
1
|
+
{"version":3,"file":"layer-guards.js","sourceRoot":"","sources":["../lib/layer-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAGvD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC7C,YAAgC;IAEhC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAExE,OAAO,IAAI,cAAc,CAAc,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;AACzE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,YAAgC;IAC7E,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAExE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,oCAAoC,CAAC,CAAA;IACxE,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAc,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAElF,OAAO;QACN,MAAM,EAAE,IAAI,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;QACnC,UAAU,EAAE,QAAQ;KACpB,CAAA;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,QAAgB,EAAE,YAAoB;IACnF,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,0BAA0B,YAAY,GAAG,CAAC,CAAA;IACtE,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC/C,YAAgC;IAEhC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAExE,OAAO,IAAI,cAAc,CAAgB,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,QAAgB,EAAE,YAAoB;IACrF,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,4BAA4B,YAAY,GAAG,CAAC,CAAA;IACxE,CAAC;AACF,CAAC"}
|
package/out/server.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* `CallToolResult` envelope. `cli.ts` owns building the real `MCPToolDeps` and connecting a transport.
|
|
9
9
|
*/
|
|
10
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
-
import { type MCPToolDeps } from "
|
|
11
|
+
import { type MCPToolDeps } from "#tools";
|
|
12
12
|
/**
|
|
13
13
|
* Build an `McpServer` with every `tools.ts` tool registered. A handler's returned value is JSON-stringified into a
|
|
14
14
|
* single `text` content block — every tool here answers with structured data (parse trees, geocode results, search
|
package/out/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../lib/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAUzD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,CAsB5D"}
|
package/out/server.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* `CallToolResult` envelope. `cli.ts` owns building the real `MCPToolDeps` and connecting a transport.
|
|
9
9
|
*/
|
|
10
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
-
import { buildToolTable } from "
|
|
11
|
+
import { buildToolTable } from "#tools";
|
|
12
12
|
/**
|
|
13
13
|
* The advertised server version — keep in lockstep with `package.json`'s `version` (not read from it dynamically: a
|
|
14
14
|
* static string avoids `resolveJsonModule`/`composite` friction for one cosmetic field, the same tradeoff
|
package/out/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAoB,MAAM,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../lib/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAoB,MAAM,QAAQ,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,OAAO,CAAA;AAElC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAiB;IAChD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAA;IAEhF,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,YAAY,CAClB,IAAI,CAAC,IAAI,EACT,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,EACtE,KAAK,EAAE,IAAI,EAA2B,EAAE;YACvC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAEvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;YAC9E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAEtE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YACrE,CAAC;QACF,CAAC,CACD,CAAA;IACF,CAAC;IAED,OAAO,MAAM,CAAA;AACd,CAAC"}
|
package/out/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACnE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,SAAS,EAAE,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/E,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAClD,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACzD,kBAAkB,EAAE,CAAC,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5G,iBAAiB,EAAE,CAAC,CAAC,EAAE;QACtB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,OAAO,CAAC;YAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAA;QACxD,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,EAAE,MAAM,CAAA;QACtB,mBAAmB,EAAE,MAAM,CAAA;KAC3B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,WAAW,EAAE,CAAC,CAAC,EAAE;QAChB,YAAY,EAAE,MAAM,CAAA;QACpB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,IAAI,CAAC,EAAE,MAAM,CAAA;KACb,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,WAAW,EAAE,CAAC,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACjH;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IACvC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5D;AA+KD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,EAAE,CAwJ9D"}
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../lib/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACnE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,SAAS,EAAE,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/E,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAClD,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACzD,kBAAkB,EAAE,CAAC,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5G,iBAAiB,EAAE,CAAC,CAAC,EAAE;QACtB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,OAAO,CAAC;YAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAA;QACxD,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,EAAE,MAAM,CAAA;QACtB,mBAAmB,EAAE,MAAM,CAAA;KAC3B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,WAAW,EAAE,CAAC,CAAC,EAAE;QAChB,YAAY,EAAE,MAAM,CAAA;QACpB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,IAAI,CAAC,EAAE,MAAM,CAAA;KACb,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,WAAW,EAAE,CAAC,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACjH;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IACvC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5D;AA+KD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,EAAE,CAwJ9D"}
|
package/out/tools.js
CHANGED
|
@@ -54,7 +54,7 @@ const POISearchInputSchema = z.object({
|
|
|
54
54
|
poiDatabasePath: z
|
|
55
55
|
.string()
|
|
56
56
|
.optional()
|
|
57
|
-
.describe("Path to a specific poi.db
|
|
57
|
+
.describe("Path to a specific poi.db extract to search. Omit to use the server's configured default (if any)."),
|
|
58
58
|
});
|
|
59
59
|
const OverpassExportInputSchema = z.object({
|
|
60
60
|
query: z
|
|
@@ -66,7 +66,7 @@ const LayerManifestInputSchema = z.object({
|
|
|
66
66
|
databasePath: z
|
|
67
67
|
.string()
|
|
68
68
|
.min(1)
|
|
69
|
-
.describe("Path to a mailwoman spatial-layer database (poi.db, an address-points
|
|
69
|
+
.describe("Path to a mailwoman spatial-layer database (poi.db, an address-points extract, etc.)."),
|
|
70
70
|
});
|
|
71
71
|
const BDCFilingLandscapeInputSchema = z.object({
|
|
72
72
|
database_path: z
|
|
@@ -216,7 +216,7 @@ export function buildToolTable(deps) {
|
|
|
216
216
|
},
|
|
217
217
|
{
|
|
218
218
|
name: "mailwoman_layer_manifest",
|
|
219
|
-
description: "Inspect a mailwoman spatial-layer database (poi.db, an address-points
|
|
219
|
+
description: "Inspect a mailwoman spatial-layer database (poi.db, an address-points extract, etc.): read its provenance " +
|
|
220
220
|
"and licensing manifest (source, vintage, build command, license) plus a coverage summary (how many H3 " +
|
|
221
221
|
"cells were surveyed, average completeness, total observed rows). Use this to check what a layer " +
|
|
222
222
|
"actually covers before relying on it.",
|
package/out/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA6CvB,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,2EAA2E,CAAC;IAC7G,GAAG,EAAE,CAAC;SACJ,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACR,+HAA+H,CAC/H;CACF,CAAC,CAAA;AAEF,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;CAC5E,CAAC,CAAA;AAEF,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACR,wHAAwH,CACxH;IACF,eAAe,EAAE,CAAC;SAChB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../lib/tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailwoman/mcp",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
4
4
|
"description": "MCP server — mailwoman's spatial toolset for agents (parse, geocode, poi_search, overpass_export, layer_manifest).",
|
|
5
5
|
"license": "AGPL-3.0-only OR LicenseRef-Commercial",
|
|
6
6
|
"repository": {
|
|
@@ -28,18 +28,28 @@
|
|
|
28
28
|
"!test/**"
|
|
29
29
|
],
|
|
30
30
|
"type": "module",
|
|
31
|
+
"imports": {
|
|
32
|
+
"#*": {
|
|
33
|
+
"types": "./out/*.d.ts",
|
|
34
|
+
"node": "./out/*.js",
|
|
35
|
+
"default": "./out/*.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
31
38
|
"exports": {
|
|
32
39
|
"./package.json": "./package.json",
|
|
33
40
|
".": {
|
|
34
41
|
"types": "./out/index.d.ts",
|
|
42
|
+
"node": "./out/index.js",
|
|
35
43
|
"default": "./out/index.js"
|
|
36
44
|
},
|
|
37
45
|
"./layer-guards": {
|
|
38
46
|
"types": "./out/layer-guards.d.ts",
|
|
47
|
+
"node": "./out/layer-guards.js",
|
|
39
48
|
"default": "./out/layer-guards.js"
|
|
40
49
|
},
|
|
41
50
|
"./tools": {
|
|
42
51
|
"types": "./out/tools.d.ts",
|
|
52
|
+
"node": "./out/tools.js",
|
|
43
53
|
"default": "./out/tools.js"
|
|
44
54
|
}
|
|
45
55
|
},
|
|
@@ -49,33 +59,44 @@
|
|
|
49
59
|
"./package.json": "./package.json",
|
|
50
60
|
".": {
|
|
51
61
|
"types": "./out/index.d.ts",
|
|
62
|
+
"node": "./out/index.js",
|
|
52
63
|
"default": "./out/index.js"
|
|
53
64
|
},
|
|
54
65
|
"./layer-guards": {
|
|
55
66
|
"types": "./out/layer-guards.d.ts",
|
|
67
|
+
"node": "./out/layer-guards.js",
|
|
56
68
|
"default": "./out/layer-guards.js"
|
|
57
69
|
},
|
|
58
70
|
"./tools": {
|
|
59
71
|
"types": "./out/tools.d.ts",
|
|
72
|
+
"node": "./out/tools.js",
|
|
60
73
|
"default": "./out/tools.js"
|
|
61
74
|
}
|
|
75
|
+
},
|
|
76
|
+
"imports": {
|
|
77
|
+
"#*": {
|
|
78
|
+
"types": "./out/*.d.ts",
|
|
79
|
+
"node": "./out/*.js",
|
|
80
|
+
"default": "./out/*.js"
|
|
81
|
+
}
|
|
62
82
|
}
|
|
63
83
|
},
|
|
64
84
|
"dependencies": {
|
|
65
|
-
"@mailwoman/bdc": "9.
|
|
66
|
-
"@mailwoman/core": "9.
|
|
67
|
-
"@mailwoman/filer": "9.
|
|
68
|
-
"@mailwoman/neural": "9.
|
|
69
|
-
"@mailwoman/neural-weights-en-us": "9.
|
|
70
|
-
"@mailwoman/poi-taxonomy": "9.
|
|
71
|
-
"@mailwoman/resolver": "9.
|
|
72
|
-
"@mailwoman/resolver-wof-sqlite": "9.
|
|
85
|
+
"@mailwoman/bdc": "9.4.0",
|
|
86
|
+
"@mailwoman/core": "9.4.0",
|
|
87
|
+
"@mailwoman/filer": "9.4.0",
|
|
88
|
+
"@mailwoman/neural": "9.4.0",
|
|
89
|
+
"@mailwoman/neural-weights-en-us": "9.4.0",
|
|
90
|
+
"@mailwoman/poi-taxonomy": "9.4.0",
|
|
91
|
+
"@mailwoman/resolver": "9.4.0",
|
|
92
|
+
"@mailwoman/resolver-wof-sqlite": "9.4.0",
|
|
93
|
+
"@mailwoman/sqlite": "9.4.0",
|
|
73
94
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
74
|
-
"mailwoman": "9.
|
|
75
|
-
"zod": "^4.4
|
|
95
|
+
"mailwoman": "9.4.0",
|
|
96
|
+
"zod": "^4.5.4"
|
|
76
97
|
},
|
|
77
98
|
"peerDependencies": {
|
|
78
|
-
"@mailwoman/resolver-wof-sqlite": "9.
|
|
99
|
+
"@mailwoman/resolver-wof-sqlite": "9.4.0"
|
|
79
100
|
},
|
|
80
101
|
"peerDependenciesMeta": {
|
|
81
102
|
"@mailwoman/resolver-wof-sqlite": {
|