teryt-mcp 0.1.1 → 0.1.3

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.
@@ -0,0 +1,21 @@
1
+ import * as _mcp_craftman_core from '@mcp-craftman/core';
2
+ import { RuntimeConfig } from '@mcp-craftman/node';
3
+
4
+ type DatasetCode = "TERC" | "SIMC" | "ULIC" | "WMRODZ";
5
+
6
+ type SourceFile = {
7
+ readonly dataset: DatasetCode;
8
+ readonly content: Uint8Array;
9
+ readonly sourceUrl: string;
10
+ readonly stateDate: string;
11
+ };
12
+ type TerytSource = {
13
+ readonly download: (dataset: DatasetCode) => Promise<SourceFile>;
14
+ };
15
+
16
+ type CreateAppOverrides = {
17
+ readonly syncSource?: TerytSource;
18
+ };
19
+ declare function createApp(config?: RuntimeConfig, overrides?: CreateAppOverrides): _mcp_craftman_core.McpApp;
20
+
21
+ export { createApp as c };
@@ -1,8 +1,11 @@
1
+ // src/version.ts
2
+ var terytMcpVersion = "0.1.3";
3
+
1
4
  // src/features/server-status/application/get-server-status.ts
2
5
  function getServerStatus(input) {
3
6
  return {
4
7
  serverName: "teryt-mcp",
5
- serverVersion: "0.1.0",
8
+ serverVersion: terytMcpVersion,
6
9
  frameworkVersion: input.frameworkVersion,
7
10
  transport: input.transport,
8
11
  dataDir: input.dataDir,
@@ -68,210 +71,6 @@ function createServerStatusTool(input) {
68
71
  import { createMcpApp } from "@mcp-craftman/core";
69
72
  import { loadRuntimeConfig } from "@mcp-craftman/node";
70
73
 
71
- // src/features/get-place/infrastructure/in-memory-place-details-repository.ts
72
- var fixturePlaces = [
73
- {
74
- id: "0009876",
75
- name: "Boles\u0142awiec",
76
- stateDate: "2026-01-01",
77
- unitId: "02-01-01-1"
78
- },
79
- {
80
- id: "0012345",
81
- name: "Stara Wie\u015B",
82
- stateDate: "2026-01-01",
83
- unitId: "02-01-02-2"
84
- }
85
- ];
86
- var InMemoryPlaceDetailsRepository = class {
87
- async getPlace(id) {
88
- return fixturePlaces.find((place) => place.id === id) ?? null;
89
- }
90
- };
91
-
92
- // src/features/get-street/infrastructure/in-memory-street-details-repository.ts
93
- var fixtureStreets = [
94
- {
95
- code: "0000123",
96
- id: "0009876-0000123",
97
- name: "Marsza\u0142kowska",
98
- placeId: "0009876",
99
- stateDate: "2026-01-01"
100
- },
101
- {
102
- code: "0000456",
103
- id: "0009876-0000456",
104
- name: "Rynek",
105
- placeId: "0009876",
106
- stateDate: "2026-01-01"
107
- }
108
- ];
109
- var InMemoryStreetDetailsRepository = class {
110
- async getStreet(id) {
111
- return fixtureStreets.find((street) => street.id === id || street.code === id) ?? null;
112
- }
113
- };
114
-
115
- // src/features/get-unit/infrastructure/in-memory-unit-details-repository.ts
116
- var fixtureStateDate = "2026-01-01";
117
- var fixtureUnits = [
118
- {
119
- id: "02",
120
- name: "DOLNO\u015AL\u0104SKIE",
121
- stateDate: fixtureStateDate,
122
- type: "wojew\xF3dztwo"
123
- },
124
- {
125
- id: "02-01-01-1",
126
- name: "Boles\u0142awiec",
127
- stateDate: fixtureStateDate,
128
- type: "gmina miejska"
129
- },
130
- {
131
- id: "02-01-02-2",
132
- name: "Boles\u0142awiec",
133
- stateDate: fixtureStateDate,
134
- type: "gmina wiejska"
135
- }
136
- ];
137
- var InMemoryUnitDetailsRepository = class {
138
- async getUnit(id) {
139
- return fixtureUnits.find((unit) => unit.id === id) ?? null;
140
- }
141
- };
142
-
143
- // src/features/resolve-address/infrastructure/in-memory-address-repository.ts
144
- var fixturePlace = {
145
- id: "0009876",
146
- name: "Boles\u0142awiec"
147
- };
148
- var fixtureStateDate2 = "2026-01-01";
149
- var fixtureUnit = {
150
- id: "02-01-01-1",
151
- name: "Boles\u0142awiec",
152
- type: "gmina miejska"
153
- };
154
- var fixtureAddresses = [
155
- {
156
- id: "0009876-0000123",
157
- place: fixturePlace,
158
- stateDate: fixtureStateDate2,
159
- street: {
160
- code: "0000123",
161
- id: "0009876-0000123",
162
- name: "Marsza\u0142kowska"
163
- },
164
- unit: fixtureUnit
165
- },
166
- {
167
- id: "0009876-0000456",
168
- place: fixturePlace,
169
- stateDate: fixtureStateDate2,
170
- street: {
171
- code: "0000456",
172
- id: "0009876-0000456",
173
- name: "Rynek"
174
- },
175
- unit: fixtureUnit
176
- }
177
- ];
178
- var InMemoryAddressRepository = class {
179
- async listAddresses() {
180
- return fixtureAddresses;
181
- }
182
- };
183
-
184
- // src/features/search-places/infrastructure/in-memory-place-repository.ts
185
- var fixtureStateDate3 = "2026-01-01";
186
- var fixturePlaces2 = [
187
- {
188
- id: "0009876",
189
- name: "Boles\u0142awiec",
190
- stateDate: fixtureStateDate3,
191
- unitId: "02-01-01-1"
192
- },
193
- {
194
- id: "0011111",
195
- name: "Krak\xF3w",
196
- stateDate: fixtureStateDate3,
197
- unitId: "12-61-01-1"
198
- },
199
- {
200
- id: "0012222",
201
- name: "Warszawa",
202
- stateDate: fixtureStateDate3,
203
- unitId: "14-65-01-1"
204
- },
205
- {
206
- id: "0012345",
207
- name: "Stara Wie\u015B",
208
- stateDate: fixtureStateDate3,
209
- unitId: "02-01-02-2"
210
- },
211
- {
212
- id: "0013333",
213
- name: "D\u0105browa",
214
- stateDate: fixtureStateDate3,
215
- unitId: "24-01-01-2"
216
- }
217
- ];
218
- var InMemoryPlaceRepository = class {
219
- async listPlaces() {
220
- return fixturePlaces2;
221
- }
222
- };
223
-
224
- // src/features/search-streets/infrastructure/in-memory-street-repository.ts
225
- var fixtureStreets2 = [
226
- {
227
- code: "0000123",
228
- id: "0009876-0000123",
229
- name: "Marsza\u0142kowska",
230
- placeId: "0009876",
231
- stateDate: "2026-01-01"
232
- },
233
- {
234
- code: "0000456",
235
- id: "0009876-0000456",
236
- name: "Rynek",
237
- placeId: "0009876",
238
- stateDate: "2026-01-01"
239
- }
240
- ];
241
- var InMemoryStreetRepository = class {
242
- async listStreets() {
243
- return fixtureStreets2;
244
- }
245
- };
246
-
247
- // src/features/search-units/infrastructure/in-memory-unit-repository.ts
248
- var fixtureStateDate4 = "2026-01-01";
249
- var fixtureUnits2 = [
250
- {
251
- id: "02",
252
- name: "DOLNO\u015AL\u0104SKIE",
253
- stateDate: fixtureStateDate4,
254
- type: "wojew\xF3dztwo"
255
- },
256
- {
257
- id: "02-01-01-1",
258
- name: "Boles\u0142awiec",
259
- stateDate: fixtureStateDate4,
260
- type: "gmina miejska"
261
- },
262
- {
263
- id: "02-01-02-2",
264
- name: "Boles\u0142awiec",
265
- stateDate: fixtureStateDate4,
266
- type: "gmina wiejska"
267
- }
268
- ];
269
- var InMemoryUnitRepository = class {
270
- async listUnits() {
271
- return fixtureUnits2;
272
- }
273
- };
274
-
275
74
  // src/features/source-status/infrastructure/eteryt-source-catalog.ts
276
75
  var SOURCE_URL = "https://eteryt.stat.gov.pl/eTeryt/";
277
76
  var EterytSourceCatalog = class {
@@ -817,7 +616,7 @@ function insertStreets(db, rows) {
817
616
  `${row.values.SYM ?? ""}-${row.values.SYM_UL ?? ""}`,
818
617
  row.values.SYM ?? "",
819
618
  row.values.SYM_UL ?? "",
820
- [row.values.CECHA, row.values.NAZWA_1, row.values.NAZWA_2].filter(Boolean).join(" "),
619
+ [row.values.NAZWA_1, row.values.NAZWA_2].filter(Boolean).join(" "),
821
620
  row.values.SYM ?? "",
822
621
  row.values.STAN_NA ?? ""
823
622
  ]);
@@ -834,7 +633,7 @@ function findImport(imports, dataset) {
834
633
  return imported;
835
634
  }
836
635
  function createUnitId2(values) {
837
- return [values.WOJ ?? "", values.POW ?? "", values.GMI ?? "", values.RODZ ?? values.RODZ_GMI ?? ""].join("-");
636
+ return [values.WOJ, values.POW, values.GMI, values.RODZ ?? values.RODZ_GMI].filter(Boolean).join("-");
838
637
  }
839
638
 
840
639
  // src/features/sync-database/infrastructure/sqlite-database-builder.ts
@@ -934,6 +733,176 @@ function rollback(db) {
934
733
  }
935
734
  }
936
735
 
736
+ // src/features/sync-database/infrastructure/sqlite-query.ts
737
+ import { readFile as readFile2 } from "fs/promises";
738
+ import { join as join5 } from "path";
739
+ import initSqlJs2 from "sql.js";
740
+ var sqlJs2;
741
+ async function withTerytDatabase(dataDir, callback) {
742
+ let content;
743
+ try {
744
+ content = await readFile2(join5(dataDir, "teryt.sqlite"));
745
+ } catch (error) {
746
+ if (isMissingFile2(error)) {
747
+ const db2 = await createEmptyDatabase();
748
+ try {
749
+ return callback(db2);
750
+ } finally {
751
+ db2.close();
752
+ }
753
+ }
754
+ throw error;
755
+ }
756
+ const SQL = await loadSqlJs2();
757
+ const db = new SQL.Database(content);
758
+ try {
759
+ return callback(db);
760
+ } finally {
761
+ db.close();
762
+ }
763
+ }
764
+ function queryOne(db, sql, params, map) {
765
+ return queryMany(db, sql, params, map)[0] ?? null;
766
+ }
767
+ function queryMany(db, sql, params, map) {
768
+ const statement = db.prepare(sql);
769
+ const rows = [];
770
+ try {
771
+ statement.bind([...params]);
772
+ while (statement.step()) {
773
+ rows.push(map(statement.getAsObject()));
774
+ }
775
+ } finally {
776
+ statement.free();
777
+ }
778
+ return rows;
779
+ }
780
+ async function createEmptyDatabase() {
781
+ const SQL = await loadSqlJs2();
782
+ const db = new SQL.Database();
783
+ db.run("CREATE TABLE places (id TEXT, name TEXT, stateDate TEXT, unitId TEXT)");
784
+ db.run("CREATE TABLE streets (SYM_UL TEXT, id TEXT, name TEXT, placeId TEXT, stateDate TEXT)");
785
+ db.run("CREATE TABLE units (id TEXT, name TEXT, stateDate TEXT, type TEXT)");
786
+ return db;
787
+ }
788
+ function loadSqlJs2() {
789
+ sqlJs2 ??= initSqlJs2();
790
+ return sqlJs2;
791
+ }
792
+ function isMissingFile2(error) {
793
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
794
+ }
795
+
796
+ // src/features/sync-database/infrastructure/sqlite-teryt-repository.ts
797
+ var SqliteTerytRepository = class {
798
+ constructor(dataDir) {
799
+ this.dataDir = dataDir;
800
+ }
801
+ dataDir;
802
+ async getPlace(id) {
803
+ return withTerytDatabase(this.dataDir, (db) => queryOne(db, "SELECT id, name, stateDate, unitId FROM places WHERE id = ?", [id], mapPlace));
804
+ }
805
+ async getStreet(id) {
806
+ return withTerytDatabase(
807
+ this.dataDir,
808
+ (db) => queryOne(
809
+ db,
810
+ "SELECT SYM_UL AS code, id, name, placeId, stateDate FROM streets WHERE id = ? OR SYM_UL = ?",
811
+ [id, id],
812
+ mapStreet
813
+ )
814
+ );
815
+ }
816
+ async getUnit(id) {
817
+ return withTerytDatabase(this.dataDir, (db) => queryOne(db, "SELECT id, name, stateDate, type FROM units WHERE id = ?", [id], mapUnit));
818
+ }
819
+ async listAddresses() {
820
+ return withTerytDatabase(
821
+ this.dataDir,
822
+ (db) => queryMany(
823
+ db,
824
+ `SELECT
825
+ streets.id AS id,
826
+ streets.stateDate AS stateDate,
827
+ streets.SYM_UL AS streetCode,
828
+ streets.name AS streetName,
829
+ places.id AS placeId,
830
+ places.name AS placeName,
831
+ units.id AS unitId,
832
+ units.name AS unitName,
833
+ units.type AS unitType
834
+ FROM streets
835
+ JOIN places ON places.id = streets.placeId
836
+ JOIN units ON units.id = places.unitId
837
+ ORDER BY places.name, streets.name, streets.id`,
838
+ [],
839
+ mapAddress
840
+ )
841
+ );
842
+ }
843
+ async listPlaces() {
844
+ return withTerytDatabase(this.dataDir, (db) => queryMany(db, "SELECT id, name, stateDate, unitId FROM places ORDER BY name, id", [], mapPlace));
845
+ }
846
+ async listStreets() {
847
+ return withTerytDatabase(
848
+ this.dataDir,
849
+ (db) => queryMany(db, "SELECT SYM_UL AS code, id, name, placeId, stateDate FROM streets ORDER BY name, id", [], mapStreet)
850
+ );
851
+ }
852
+ async listUnits() {
853
+ return withTerytDatabase(this.dataDir, (db) => queryMany(db, "SELECT id, name, stateDate, type FROM units ORDER BY name, id", [], mapUnit));
854
+ }
855
+ };
856
+ function mapPlace(row) {
857
+ return {
858
+ id: readText(row.id),
859
+ name: readText(row.name),
860
+ stateDate: readText(row.stateDate),
861
+ unitId: readText(row.unitId)
862
+ };
863
+ }
864
+ function mapStreet(row) {
865
+ return {
866
+ code: readText(row.code),
867
+ id: readText(row.id),
868
+ name: readText(row.name),
869
+ placeId: readText(row.placeId),
870
+ stateDate: readText(row.stateDate)
871
+ };
872
+ }
873
+ function mapUnit(row) {
874
+ return {
875
+ id: readText(row.id),
876
+ name: readText(row.name),
877
+ stateDate: readText(row.stateDate),
878
+ type: readText(row.type)
879
+ };
880
+ }
881
+ function mapAddress(row) {
882
+ const streetId = readText(row.id);
883
+ return {
884
+ id: streetId,
885
+ place: {
886
+ id: readText(row.placeId),
887
+ name: readText(row.placeName)
888
+ },
889
+ stateDate: readText(row.stateDate),
890
+ street: {
891
+ code: readText(row.streetCode),
892
+ id: streetId,
893
+ name: readText(row.streetName)
894
+ },
895
+ unit: {
896
+ id: readText(row.unitId),
897
+ name: readText(row.unitName),
898
+ type: readText(row.unitType)
899
+ }
900
+ };
901
+ }
902
+ function readText(value) {
903
+ return typeof value === "string" ? value : "";
904
+ }
905
+
937
906
  // src/mcp/registry.ts
938
907
  import { createCapabilityRegistry } from "@mcp-craftman/core";
939
908
 
@@ -1295,7 +1264,7 @@ function normalizeName(value) {
1295
1264
  }
1296
1265
 
1297
1266
  // src/features/resolve-address/mcp/resolve-address.tool.ts
1298
- import { defineTool as defineTool6, readOptionalNumberField, readRequiredStringField as readRequiredStringField4 } from "@mcp-craftman/core";
1267
+ import { defineTool as defineTool6, readQueryLimitInput } from "@mcp-craftman/core";
1299
1268
  function createResolveAddressTool(dependencies) {
1300
1269
  return defineTool6({
1301
1270
  inputSchema,
@@ -1308,7 +1277,7 @@ function createResolveAddressTool(dependencies) {
1308
1277
  readOnlyHint: true
1309
1278
  },
1310
1279
  handler: async (input) => ({
1311
- structuredContent: await resolveAddress(parseInput4(input), dependencies)
1280
+ structuredContent: await resolveAddress(readQueryLimitInput(input, "resolve_address"), dependencies)
1312
1281
  })
1313
1282
  });
1314
1283
  }
@@ -1420,14 +1389,6 @@ var outputSchema = {
1420
1389
  },
1421
1390
  required: ["addresses", "stateDate"]
1422
1391
  };
1423
- function parseInput4(input) {
1424
- const query = readRequiredStringField4(input, "query", "resolve_address");
1425
- const limit = readOptionalNumberField(input, "limit", "resolve_address");
1426
- return {
1427
- limit,
1428
- query
1429
- };
1430
- }
1431
1392
 
1432
1393
  // src/features/search-places/application/search-places.ts
1433
1394
  var DEFAULT_LIMIT2 = 20;
@@ -1502,7 +1463,7 @@ function normalizeName2(value) {
1502
1463
  }
1503
1464
 
1504
1465
  // src/features/search-places/mcp/search-places.tool.ts
1505
- import { defineTool as defineTool7, readOptionalNumberField as readOptionalNumberField2, readRequiredStringField as readRequiredStringField5 } from "@mcp-craftman/core";
1466
+ import { defineTool as defineTool7, readQueryLimitInput as readQueryLimitInput2 } from "@mcp-craftman/core";
1506
1467
  function createSearchPlacesTool(dependencies) {
1507
1468
  return defineTool7({
1508
1469
  name: "search_places",
@@ -1578,18 +1539,10 @@ function createSearchPlacesTool(dependencies) {
1578
1539
  readOnlyHint: true
1579
1540
  },
1580
1541
  handler: async (input) => ({
1581
- structuredContent: await searchPlaces(parseInput5(input), dependencies)
1542
+ structuredContent: await searchPlaces(readQueryLimitInput2(input, "search_places"), dependencies)
1582
1543
  })
1583
1544
  });
1584
1545
  }
1585
- function parseInput5(input) {
1586
- const query = readRequiredStringField5(input, "query", "search_places");
1587
- const limit = readOptionalNumberField2(input, "limit", "search_places");
1588
- return {
1589
- limit,
1590
- query
1591
- };
1592
- }
1593
1546
 
1594
1547
  // src/features/search-streets/application/search-streets.ts
1595
1548
  var DEFAULT_LIMIT3 = 20;
@@ -1664,7 +1617,7 @@ function normalizeName3(value) {
1664
1617
  }
1665
1618
 
1666
1619
  // src/features/search-streets/mcp/search-streets.tool.ts
1667
- import { defineTool as defineTool8, readOptionalNumberField as readOptionalNumberField3, readRequiredStringField as readRequiredStringField6 } from "@mcp-craftman/core";
1620
+ import { defineTool as defineTool8, readQueryLimitInput as readQueryLimitInput3 } from "@mcp-craftman/core";
1668
1621
  function createSearchStreetsTool(dependencies) {
1669
1622
  return defineTool8({
1670
1623
  inputSchema: inputSchema2,
@@ -1677,7 +1630,7 @@ function createSearchStreetsTool(dependencies) {
1677
1630
  readOnlyHint: true
1678
1631
  },
1679
1632
  handler: async (input) => ({
1680
- structuredContent: await searchStreets(parseInput6(input), dependencies)
1633
+ structuredContent: await searchStreets(readQueryLimitInput3(input, "search_streets"), dependencies)
1681
1634
  })
1682
1635
  });
1683
1636
  }
@@ -1749,14 +1702,6 @@ var outputSchema2 = {
1749
1702
  },
1750
1703
  required: ["stateDate", "streets"]
1751
1704
  };
1752
- function parseInput6(input) {
1753
- const query = readRequiredStringField6(input, "query", "search_streets");
1754
- const limit = readOptionalNumberField3(input, "limit", "search_streets");
1755
- return {
1756
- limit,
1757
- query
1758
- };
1759
- }
1760
1705
 
1761
1706
  // src/features/search-units/application/search-units.ts
1762
1707
  var DEFAULT_LIMIT4 = 20;
@@ -1831,7 +1776,7 @@ function normalizeName4(value) {
1831
1776
  }
1832
1777
 
1833
1778
  // src/features/search-units/mcp/search-units.tool.ts
1834
- import { defineTool as defineTool9, readOptionalNumberField as readOptionalNumberField4, readRequiredStringField as readRequiredStringField7 } from "@mcp-craftman/core";
1779
+ import { defineTool as defineTool9, readQueryLimitInput as readQueryLimitInput4 } from "@mcp-craftman/core";
1835
1780
  function createSearchUnitsTool(dependencies) {
1836
1781
  return defineTool9({
1837
1782
  name: "search_units",
@@ -1907,18 +1852,10 @@ function createSearchUnitsTool(dependencies) {
1907
1852
  readOnlyHint: true
1908
1853
  },
1909
1854
  handler: async (input) => ({
1910
- structuredContent: await searchUnits(parseInput7(input), dependencies)
1855
+ structuredContent: await searchUnits(readQueryLimitInput4(input, "search_units"), dependencies)
1911
1856
  })
1912
1857
  });
1913
1858
  }
1914
- function parseInput7(input) {
1915
- const query = readRequiredStringField7(input, "query", "search_units");
1916
- const limit = readOptionalNumberField4(input, "limit", "search_units");
1917
- return {
1918
- limit,
1919
- query
1920
- };
1921
- }
1922
1859
 
1923
1860
  // src/features/source-status/application/get-source-status.ts
1924
1861
  async function getSourceStatus(input) {
@@ -2346,20 +2283,21 @@ function createApp(config = loadRuntimeConfig(), overrides = {}) {
2346
2283
  const syncLockStore = new FileLockStore(config.dataDir);
2347
2284
  const syncManifestStore = new JsonSyncManifestStore(config.dataDir);
2348
2285
  const syncSource = overrides.syncSource ?? new EterytSource();
2286
+ const terytRepository = new SqliteTerytRepository(config.dataDir);
2349
2287
  return createMcpApp({
2350
2288
  name: "teryt-mcp",
2351
- version: "0.1.0",
2289
+ version: terytMcpVersion,
2352
2290
  registry: createRegistry({
2353
2291
  config,
2354
2292
  manifestStore,
2355
2293
  sourceCatalog,
2356
- addressRepository: new InMemoryAddressRepository(),
2357
- placeDetailsRepository: new InMemoryPlaceDetailsRepository(),
2358
- placeRepository: new InMemoryPlaceRepository(),
2359
- streetDetailsRepository: new InMemoryStreetDetailsRepository(),
2360
- streetRepository: new InMemoryStreetRepository(),
2361
- unitDetailsRepository: new InMemoryUnitDetailsRepository(),
2362
- unitRepository: new InMemoryUnitRepository(),
2294
+ addressRepository: terytRepository,
2295
+ placeDetailsRepository: terytRepository,
2296
+ placeRepository: terytRepository,
2297
+ streetDetailsRepository: terytRepository,
2298
+ streetRepository: terytRepository,
2299
+ unitDetailsRepository: terytRepository,
2300
+ unitRepository: terytRepository,
2363
2301
  sync: {
2364
2302
  databaseBuilder: new SqliteDatabaseBuilder(),
2365
2303
  fileStore: syncFileStore,
@@ -2372,16 +2310,35 @@ function createApp(config = loadRuntimeConfig(), overrides = {}) {
2372
2310
  });
2373
2311
  }
2374
2312
 
2375
- // src/server/serve.ts
2376
- import { loadRuntimeConfig as loadRuntimeConfig2, serveMcpApp } from "@mcp-craftman/node";
2377
- async function serve(config = loadRuntimeConfig2()) {
2378
- return serveMcpApp(createApp, {
2379
- config
2380
- });
2313
+ // src/runtime/config.ts
2314
+ import { homedir } from "os";
2315
+ import { resolve } from "path";
2316
+ import { loadRuntimeConfig as loadRuntimeConfig2 } from "@mcp-craftman/node";
2317
+ function loadTerytRuntimeConfig(env = process.env) {
2318
+ const config = loadRuntimeConfig2(env);
2319
+ return {
2320
+ ...config,
2321
+ dataDir: resolveTerytDataDir(env)
2322
+ };
2323
+ }
2324
+ function resolveTerytDataDir(env) {
2325
+ if (env.MCP_DATA_DIR) {
2326
+ return resolve(env.MCP_DATA_DIR);
2327
+ }
2328
+ if (env.XDG_CACHE_HOME) {
2329
+ return resolve(env.XDG_CACHE_HOME, "teryt-mcp");
2330
+ }
2331
+ if (process.platform === "darwin") {
2332
+ return resolve(homedir(), "Library", "Caches", "teryt-mcp");
2333
+ }
2334
+ if (process.platform === "win32" && env.LOCALAPPDATA) {
2335
+ return resolve(env.LOCALAPPDATA, "teryt-mcp");
2336
+ }
2337
+ return resolve(homedir(), ".cache", "teryt-mcp");
2381
2338
  }
2382
2339
 
2383
2340
  export {
2384
2341
  getServerStatus,
2385
2342
  createApp,
2386
- serve
2343
+ loadTerytRuntimeConfig
2387
2344
  };
@@ -0,0 +1,16 @@
1
+ import {
2
+ createApp,
3
+ loadTerytRuntimeConfig
4
+ } from "./chunk-LDGYCOB4.js";
5
+
6
+ // src/server/serve.ts
7
+ import { serveMcpApp } from "@mcp-craftman/node";
8
+ async function serve(config = loadTerytRuntimeConfig()) {
9
+ return serveMcpApp(createApp, {
10
+ config
11
+ });
12
+ }
13
+
14
+ export {
15
+ serve
16
+ };
package/dist/cli.d.ts CHANGED
@@ -1,23 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { RuntimeConfig, CliIo } from '@mcp-craftman/node';
3
- import * as _mcp_craftman_core from '@mcp-craftman/core';
4
-
5
- type DatasetCode = "TERC" | "SIMC" | "ULIC" | "WMRODZ";
6
-
7
- type SourceFile = {
8
- readonly dataset: DatasetCode;
9
- readonly content: Uint8Array;
10
- readonly sourceUrl: string;
11
- readonly stateDate: string;
12
- };
13
- type TerytSource = {
14
- readonly download: (dataset: DatasetCode) => Promise<SourceFile>;
15
- };
16
-
17
- type CreateAppOverrides = {
18
- readonly syncSource?: TerytSource;
19
- };
20
- declare function createApp(config?: RuntimeConfig, overrides?: CreateAppOverrides): _mcp_craftman_core.McpApp;
2
+ import { CliIo } from '@mcp-craftman/node';
3
+ import { c as createApp } from './app-DumxnZvs.js';
4
+ import '@mcp-craftman/core';
21
5
 
22
6
  type TerytCliIo = CliIo & {
23
7
  readonly appFactory?: typeof createApp;
package/dist/cli.js CHANGED
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ serve
4
+ } from "./chunk-R2QUAOGP.js";
2
5
  import {
3
6
  createApp,
4
7
  getServerStatus,
5
- serve
6
- } from "./chunk-GSWKF6BK.js";
8
+ loadTerytRuntimeConfig
9
+ } from "./chunk-LDGYCOB4.js";
7
10
 
8
11
  // src/cli.ts
9
12
  import {
10
13
  createDefaultCliIo,
11
14
  isCliEntrypoint,
12
- loadRuntimeConfig,
13
15
  writeCliToolStructuredContent,
14
16
  writeJson
15
17
  } from "@mcp-craftman/node";
@@ -17,11 +19,11 @@ import { mcpCraftmanCoreVersion } from "@mcp-craftman/core";
17
19
  async function runCli(argv = process.argv.slice(2), io = defaultIo()) {
18
20
  const [command, ...args] = argv;
19
21
  if (command === "serve") {
20
- await serve(loadRuntimeConfig(io.env));
22
+ await serve(loadTerytRuntimeConfig(io.env));
21
23
  return;
22
24
  }
23
25
  if (command === "status") {
24
- const config = loadRuntimeConfig(io.env);
26
+ const config = loadTerytRuntimeConfig(io.env);
25
27
  writeJson(
26
28
  io.stdout,
27
29
  getServerStatus({
@@ -47,7 +49,10 @@ async function runCli(argv = process.argv.slice(2), io = defaultIo()) {
47
49
  throw new Error(`Unknown command: ${command ?? "<missing>"}`);
48
50
  }
49
51
  async function writeCliToolResult(stream, toolName, input, io) {
50
- await writeCliToolStructuredContent(stream, io.appFactory ?? createApp, toolName, input, io.env);
52
+ await writeCliToolStructuredContent(stream, io.appFactory ?? createApp, toolName, input, {
53
+ ...io.env,
54
+ MCP_DATA_DIR: loadTerytRuntimeConfig(io.env).dataDir
55
+ });
51
56
  }
52
57
  function defaultIo() {
53
58
  return createDefaultCliIo();
package/dist/main.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  serve
3
- } from "./chunk-GSWKF6BK.js";
3
+ } from "./chunk-R2QUAOGP.js";
4
+ import "./chunk-LDGYCOB4.js";
4
5
 
5
6
  // src/main.ts
6
7
  await serve();
@@ -0,0 +1,15 @@
1
+ import { c as createApp } from './app-DumxnZvs.js';
2
+ import '@mcp-craftman/core';
3
+ import '@mcp-craftman/node';
4
+
5
+ type PostinstallIo = {
6
+ readonly env: NodeJS.ProcessEnv;
7
+ readonly stderr: NodeJS.WritableStream;
8
+ };
9
+ type PostinstallOptions = {
10
+ readonly appFactory?: typeof createApp;
11
+ readonly io?: PostinstallIo;
12
+ };
13
+ declare function runPostinstallSync(options?: PostinstallOptions): Promise<void>;
14
+
15
+ export { runPostinstallSync };
@@ -0,0 +1,42 @@
1
+ import {
2
+ createApp,
3
+ loadTerytRuntimeConfig
4
+ } from "./chunk-LDGYCOB4.js";
5
+
6
+ // src/postinstall.ts
7
+ import { callTool } from "@mcp-craftman/core";
8
+ import { isCliEntrypoint } from "@mcp-craftman/node";
9
+ var skipValues = /* @__PURE__ */ new Set(["1", "true", "yes"]);
10
+ async function runPostinstallSync(options = {}) {
11
+ const io = options.io ?? {
12
+ env: process.env,
13
+ stderr: process.stderr
14
+ };
15
+ if (skipValues.has((io.env.TERYT_MCP_SKIP_POSTINSTALL_SYNC ?? "").toLowerCase())) {
16
+ io.stderr.write("teryt-mcp postinstall: skipping initial sync.\n");
17
+ return;
18
+ }
19
+ const config = loadTerytRuntimeConfig(io.env);
20
+ const appFactory = options.appFactory ?? createApp;
21
+ const result = await callTool(appFactory(config), "sync_database", {
22
+ mode: "missing"
23
+ });
24
+ const status = readStatus(result.structuredContent);
25
+ io.stderr.write(`teryt-mcp postinstall: initial sync ${status} in ${config.dataDir}.
26
+ `);
27
+ }
28
+ function readStatus(content) {
29
+ if (typeof content === "object" && content !== null && "status" in content && typeof content.status === "string") {
30
+ return content.status;
31
+ }
32
+ return "completed";
33
+ }
34
+ if (isCliEntrypoint("postinstall.js")) {
35
+ runPostinstallSync().catch((error) => {
36
+ process.stderr.write(`teryt-mcp postinstall: initial sync failed: ${error instanceof Error ? error.message : String(error)}
37
+ `);
38
+ });
39
+ }
40
+ export {
41
+ runPostinstallSync
42
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teryt-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "description": "MCP server for the official Polish TERYT registry.",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  "access": "public"
16
16
  },
17
17
  "dependencies": {
18
- "@mcp-craftman/core": "^0.1.2",
18
+ "@mcp-craftman/core": "^0.1.3",
19
19
  "@mcp-craftman/node": "^0.1.2",
20
20
  "fflate": "^0.8.3",
21
21
  "sql.js": "^1.14.1"
@@ -38,7 +38,8 @@
38
38
  "node": ">=20.19.0"
39
39
  },
40
40
  "scripts": {
41
- "build": "tsup src/main.ts src/cli.ts --format esm --dts --clean",
41
+ "build": "tsup src/main.ts src/cli.ts src/postinstall.ts --format esm --dts --clean",
42
+ "postinstall": "node dist/postinstall.js",
42
43
  "quality": "mcp-craftman quality",
43
44
  "test": "vitest run"
44
45
  }