@cyanheads/openstreetmap-mcp-server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CLAUDE.md +393 -0
  2. package/Dockerfile +99 -0
  3. package/LICENSE +201 -0
  4. package/README.md +283 -0
  5. package/dist/config/server-config.d.ts +14 -0
  6. package/dist/config/server-config.d.ts.map +1 -0
  7. package/dist/config/server-config.js +47 -0
  8. package/dist/config/server-config.js.map +1 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +40 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/mcp-server/tools/definitions/openstreetmap-format.d.ts +18 -0
  14. package/dist/mcp-server/tools/definitions/openstreetmap-format.d.ts.map +1 -0
  15. package/dist/mcp-server/tools/definitions/openstreetmap-format.js +36 -0
  16. package/dist/mcp-server/tools/definitions/openstreetmap-format.js.map +1 -0
  17. package/dist/mcp-server/tools/definitions/openstreetmap-geocode.tool.d.ts +59 -0
  18. package/dist/mcp-server/tools/definitions/openstreetmap-geocode.tool.d.ts.map +1 -0
  19. package/dist/mcp-server/tools/definitions/openstreetmap-geocode.tool.js +203 -0
  20. package/dist/mcp-server/tools/definitions/openstreetmap-geocode.tool.js.map +1 -0
  21. package/dist/mcp-server/tools/definitions/openstreetmap-lookup.tool.d.ts +39 -0
  22. package/dist/mcp-server/tools/definitions/openstreetmap-lookup.tool.d.ts.map +1 -0
  23. package/dist/mcp-server/tools/definitions/openstreetmap-lookup.tool.js +136 -0
  24. package/dist/mcp-server/tools/definitions/openstreetmap-lookup.tool.js.map +1 -0
  25. package/dist/mcp-server/tools/definitions/openstreetmap-query-bbox.tool.d.ts +57 -0
  26. package/dist/mcp-server/tools/definitions/openstreetmap-query-bbox.tool.d.ts.map +1 -0
  27. package/dist/mcp-server/tools/definitions/openstreetmap-query-bbox.tool.js +170 -0
  28. package/dist/mcp-server/tools/definitions/openstreetmap-query-bbox.tool.js.map +1 -0
  29. package/dist/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.d.ts +56 -0
  30. package/dist/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.d.ts.map +1 -0
  31. package/dist/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.js +174 -0
  32. package/dist/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.js.map +1 -0
  33. package/dist/mcp-server/tools/definitions/openstreetmap-query-raw.tool.d.ts +38 -0
  34. package/dist/mcp-server/tools/definitions/openstreetmap-query-raw.tool.d.ts.map +1 -0
  35. package/dist/mcp-server/tools/definitions/openstreetmap-query-raw.tool.js +124 -0
  36. package/dist/mcp-server/tools/definitions/openstreetmap-query-raw.tool.js.map +1 -0
  37. package/dist/mcp-server/tools/definitions/openstreetmap-reverse.tool.d.ts +40 -0
  38. package/dist/mcp-server/tools/definitions/openstreetmap-reverse.tool.d.ts.map +1 -0
  39. package/dist/mcp-server/tools/definitions/openstreetmap-reverse.tool.js +129 -0
  40. package/dist/mcp-server/tools/definitions/openstreetmap-reverse.tool.js.map +1 -0
  41. package/dist/mcp-server/tools/definitions/openstreetmap-tag-input.d.ts +21 -0
  42. package/dist/mcp-server/tools/definitions/openstreetmap-tag-input.d.ts.map +1 -0
  43. package/dist/mcp-server/tools/definitions/openstreetmap-tag-input.js +22 -0
  44. package/dist/mcp-server/tools/definitions/openstreetmap-tag-input.js.map +1 -0
  45. package/dist/services/nominatim/nominatim-service.d.ts +24 -0
  46. package/dist/services/nominatim/nominatim-service.d.ts.map +1 -0
  47. package/dist/services/nominatim/nominatim-service.js +160 -0
  48. package/dist/services/nominatim/nominatim-service.js.map +1 -0
  49. package/dist/services/nominatim/types.d.ts +55 -0
  50. package/dist/services/nominatim/types.d.ts.map +1 -0
  51. package/dist/services/nominatim/types.js +6 -0
  52. package/dist/services/nominatim/types.js.map +1 -0
  53. package/dist/services/overpass/overpass-service.d.ts +25 -0
  54. package/dist/services/overpass/overpass-service.d.ts.map +1 -0
  55. package/dist/services/overpass/overpass-service.js +146 -0
  56. package/dist/services/overpass/overpass-service.js.map +1 -0
  57. package/dist/services/overpass/types.d.ts +59 -0
  58. package/dist/services/overpass/types.d.ts.map +1 -0
  59. package/dist/services/overpass/types.js +6 -0
  60. package/dist/services/overpass/types.js.map +1 -0
  61. package/package.json +91 -0
  62. package/server.json +153 -0
@@ -0,0 +1,170 @@
1
+ /**
2
+ * @fileoverview Overpass bounding box query tool — finds OSM features within a bbox.
3
+ * @module mcp-server/tools/definitions/openstreetmap-query-bbox.tool
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getOverpassService } from '../../../services/overpass/overpass-service.js';
8
+ import { resolveTagInput } from './openstreetmap-tag-input.js';
9
+ const ATTRIBUTION = 'Data © OpenStreetMap contributors, ODbL 1.0';
10
+ export const openstreetmapQueryBbox = tool('openstreetmap_query_bbox', {
11
+ title: 'Find OSM features within a bounding box',
12
+ description: 'Find OSM features within a rectangular geographic area (bounding box) via the Overpass API. ' +
13
+ 'Useful for area surveys where you want everything in a region, not proximity searches. ' +
14
+ 'Use amenity for common POI types (hospital, pharmacy, cafe, school, etc.) ' +
15
+ 'or tag_key + tag_value for other OSM categories (leisure=park, shop=supermarket, natural=peak). ' +
16
+ 'Exactly one of amenity or tag_key/tag_value must be provided. ' +
17
+ 'For proximity searches centered on a point, use openstreetmap_query_nearby instead.',
18
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
19
+ input: z.object({
20
+ south: z.number().min(-90).max(90).describe('Southern boundary latitude (minimum latitude).'),
21
+ west: z.number().min(-180).max(180).describe('Western boundary longitude (minimum longitude).'),
22
+ north: z.number().min(-90).max(90).describe('Northern boundary latitude (maximum latitude).'),
23
+ east: z.number().min(-180).max(180).describe('Eastern boundary longitude (maximum longitude).'),
24
+ amenity: z
25
+ .string()
26
+ .optional()
27
+ .describe('OSM amenity tag value shortcut (e.g., "cafe", "bench", "hospital"). Cannot be combined with tag_key/tag_value.'),
28
+ tag_key: z
29
+ .string()
30
+ .optional()
31
+ .describe('OSM tag key for non-amenity queries (e.g., "leisure", "shop", "natural"). Use with tag_value. Cannot be combined with amenity.'),
32
+ tag_value: z
33
+ .string()
34
+ .optional()
35
+ .describe('OSM tag value paired with tag_key (e.g., "park", "supermarket", "peak").'),
36
+ element_types: z
37
+ .array(z.enum(['node', 'way', 'relation']))
38
+ .default(['node', 'way'])
39
+ .describe('OSM element types to search. Ways cover most buildings and areas; nodes cover most standalone POIs. Add "relation" for complex structures.'),
40
+ limit: z
41
+ .number()
42
+ .int()
43
+ .min(1)
44
+ .max(500)
45
+ .default(20)
46
+ .describe('Maximum results to return. Applied after the Overpass query — if the area has more features, they are truncated.'),
47
+ timeout_seconds: z
48
+ .number()
49
+ .int()
50
+ .min(5)
51
+ .max(60)
52
+ .default(25)
53
+ .describe('Overpass query timeout in seconds. Increase for large bounding boxes or dense areas.'),
54
+ }),
55
+ output: z.object({
56
+ elements: z
57
+ .array(z
58
+ .object({
59
+ osm_type: z.enum(['node', 'way', 'relation']).describe('OSM element type.'),
60
+ osm_id: z
61
+ .number()
62
+ .describe('OSM element ID. Use with osm_type for openstreetmap_lookup.'),
63
+ lat: z
64
+ .number()
65
+ .optional()
66
+ .describe('Latitude (present for nodes and ways/relations with computed center).'),
67
+ lon: z
68
+ .number()
69
+ .optional()
70
+ .describe('Longitude (present for nodes and ways/relations with computed center).'),
71
+ name: z.string().optional().describe('Feature name from OSM tags.'),
72
+ tags: z
73
+ .record(z.string(), z.string())
74
+ .describe('All OSM tags for this feature. Values are always strings.'),
75
+ })
76
+ .describe('A single matching OSM feature.'))
77
+ .describe('Matching OSM features within the bounding box, up to the limit.'),
78
+ total_found: z
79
+ .number()
80
+ .describe('Total features returned by Overpass before limit truncation.'),
81
+ truncated: z
82
+ .boolean()
83
+ .describe('True if results were cut at the limit. Reduce bbox area or add more specific tags to narrow the result set.'),
84
+ data_timestamp: z.string().describe('OSM data freshness timestamp from the Overpass response.'),
85
+ attribution: z
86
+ .string()
87
+ .describe('Required data attribution: Data © OpenStreetMap contributors, ODbL 1.0.'),
88
+ }),
89
+ errors: [
90
+ {
91
+ reason: 'invalid_tag',
92
+ code: JsonRpcErrorCode.ValidationError,
93
+ when: 'Both amenity and tag_key/tag_value are provided, or neither is provided.',
94
+ recovery: 'Provide either amenity (e.g., "hospital") or tag_key + tag_value (e.g., tag_key="leisure", tag_value="park"), but not both and not neither.',
95
+ },
96
+ {
97
+ reason: 'query_timeout',
98
+ code: JsonRpcErrorCode.Timeout,
99
+ when: 'The Overpass query exceeded the timeout.',
100
+ retryable: true,
101
+ recovery: 'Reduce the bounding box area, add more specific tag filters, or increase timeout_seconds and retry.',
102
+ },
103
+ {
104
+ reason: 'rate_limited',
105
+ code: JsonRpcErrorCode.ServiceUnavailable,
106
+ when: 'Overpass returned HTTP 429 — all 4 concurrent query slots are occupied.',
107
+ retryable: true,
108
+ recovery: 'Wait a few seconds and retry. Reduce concurrent calls or switch to a private Overpass instance via OSM_OVERPASS_BASE_URL.',
109
+ },
110
+ ],
111
+ async handler(input, ctx) {
112
+ const resolved = resolveTagInput(input);
113
+ if ('error' in resolved) {
114
+ throw ctx.fail('invalid_tag', resolved.error === 'both'
115
+ ? 'Cannot combine amenity with tag_key/tag_value.'
116
+ : 'Provide either amenity or tag_key + tag_value.', { ...ctx.recoveryFor('invalid_tag') });
117
+ }
118
+ const { tagKey, tagValue } = resolved;
119
+ const service = getOverpassService();
120
+ const ql = service.buildBboxQuery({
121
+ south: input.south,
122
+ west: input.west,
123
+ north: input.north,
124
+ east: input.east,
125
+ tagKey,
126
+ tagValue,
127
+ elementTypes: input.element_types,
128
+ timeoutSeconds: input.timeout_seconds,
129
+ });
130
+ const response = await service.query(ql, ctx);
131
+ const allPois = service.normalizeElements(response.elements);
132
+ const limited = allPois.slice(0, input.limit);
133
+ const dataTimestamp = response.osm3s?.timestamp_osm_base ?? new Date().toISOString();
134
+ ctx.log.info('Overpass bbox results', {
135
+ total: allPois.length,
136
+ returned: limited.length,
137
+ });
138
+ return {
139
+ elements: limited,
140
+ total_found: allPois.length,
141
+ truncated: allPois.length > input.limit,
142
+ data_timestamp: dataTimestamp,
143
+ attribution: ATTRIBUTION,
144
+ };
145
+ },
146
+ format: (result) => {
147
+ const lines = [
148
+ `**${result.total_found} feature${result.total_found === 1 ? '' : 's'} found**${result.truncated ? ` (showing first ${result.elements.length} — results truncated)` : ''}`,
149
+ `**Data as of:** ${result.data_timestamp}`,
150
+ '',
151
+ ];
152
+ for (const el of result.elements) {
153
+ const nameStr = el.name ?? 'Unnamed';
154
+ lines.push(`## ${nameStr}`);
155
+ lines.push(`**OSM:** ${el.osm_type.charAt(0).toUpperCase()}${el.osm_id}`);
156
+ if (el.lat !== undefined && el.lon !== undefined) {
157
+ lines.push(`**Coordinates:** ${el.lat}, ${el.lon}`);
158
+ }
159
+ const tagEntries = Object.entries(el.tags)
160
+ .map(([k, v]) => `${k}=${v}`)
161
+ .join(', ');
162
+ if (tagEntries)
163
+ lines.push(`**Tags:** ${tagEntries}`);
164
+ lines.push('');
165
+ }
166
+ lines.push(`*${result.attribution}*`);
167
+ return [{ type: 'text', text: lines.join('\n') }];
168
+ },
169
+ });
170
+ //# sourceMappingURL=openstreetmap-query-bbox.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openstreetmap-query-bbox.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/openstreetmap-query-bbox.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Overpass nearby query tool — finds OSM features within a radius.
3
+ * @module mcp-server/tools/definitions/openstreetmap-query-nearby.tool
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const openstreetmapQueryNearby: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ lat: z.ZodNumber;
9
+ lon: z.ZodNumber;
10
+ radius_meters: z.ZodDefault<z.ZodNumber>;
11
+ amenity: z.ZodOptional<z.ZodString>;
12
+ tag_key: z.ZodOptional<z.ZodString>;
13
+ tag_value: z.ZodOptional<z.ZodString>;
14
+ element_types: z.ZodDefault<z.ZodArray<z.ZodEnum<{
15
+ node: "node";
16
+ way: "way";
17
+ relation: "relation";
18
+ }>>>;
19
+ limit: z.ZodDefault<z.ZodNumber>;
20
+ timeout_seconds: z.ZodDefault<z.ZodNumber>;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ elements: z.ZodArray<z.ZodObject<{
23
+ osm_type: z.ZodEnum<{
24
+ node: "node";
25
+ way: "way";
26
+ relation: "relation";
27
+ }>;
28
+ osm_id: z.ZodNumber;
29
+ lat: z.ZodOptional<z.ZodNumber>;
30
+ lon: z.ZodOptional<z.ZodNumber>;
31
+ name: z.ZodOptional<z.ZodString>;
32
+ tags: z.ZodRecord<z.ZodString, z.ZodString>;
33
+ }, z.core.$strip>>;
34
+ total_found: z.ZodNumber;
35
+ truncated: z.ZodBoolean;
36
+ data_timestamp: z.ZodString;
37
+ attribution: z.ZodString;
38
+ }, z.core.$strip>, readonly [{
39
+ readonly reason: "invalid_tag";
40
+ readonly code: JsonRpcErrorCode.ValidationError;
41
+ readonly when: "Both amenity and tag_key/tag_value are provided, or neither is provided.";
42
+ readonly recovery: "Provide either amenity (e.g., \"hospital\") or tag_key + tag_value (e.g., tag_key=\"leisure\", tag_value=\"park\"), but not both and not neither.";
43
+ }, {
44
+ readonly reason: "query_timeout";
45
+ readonly code: JsonRpcErrorCode.Timeout;
46
+ readonly when: "The Overpass query exceeded the timeout.";
47
+ readonly retryable: true;
48
+ readonly recovery: "Reduce radius_meters, add more specific tag filters, or increase timeout_seconds and retry.";
49
+ }, {
50
+ readonly reason: "rate_limited";
51
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
52
+ readonly when: "Overpass returned HTTP 429 — all 4 concurrent query slots are occupied.";
53
+ readonly retryable: true;
54
+ readonly recovery: "Wait a few seconds and retry. Reduce concurrent calls or switch to a private Overpass instance via OSM_OVERPASS_BASE_URL.";
55
+ }]>;
56
+ //# sourceMappingURL=openstreetmap-query-nearby.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openstreetmap-query-nearby.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAMjE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoMnC,CAAC"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * @fileoverview Overpass nearby query tool — finds OSM features within a radius.
3
+ * @module mcp-server/tools/definitions/openstreetmap-query-nearby.tool
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getOverpassService } from '../../../services/overpass/overpass-service.js';
8
+ import { resolveTagInput } from './openstreetmap-tag-input.js';
9
+ const ATTRIBUTION = 'Data © OpenStreetMap contributors, ODbL 1.0';
10
+ export const openstreetmapQueryNearby = tool('openstreetmap_query_nearby', {
11
+ title: 'Find OSM features near a point',
12
+ description: 'Find OSM features within a radius around a geographic point via the Overpass API. ' +
13
+ 'The primary tool for "what\'s near X?" spatial queries. ' +
14
+ 'Use amenity for common POI types (hospital, pharmacy, restaurant, cafe, school, atm, etc.) ' +
15
+ 'or tag_key + tag_value for other OSM categories (leisure=park, shop=supermarket, natural=peak). ' +
16
+ 'Exactly one of amenity or tag_key/tag_value must be provided. ' +
17
+ 'Results include all element types specified (nodes cover standalone POIs, ways cover buildings and areas). ' +
18
+ 'Note: results are not sorted by distance — the Overpass API returns them in OSM element ID order.',
19
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
20
+ input: z.object({
21
+ lat: z.number().min(-90).max(90).describe('Center latitude in WGS84 decimal degrees.'),
22
+ lon: z.number().min(-180).max(180).describe('Center longitude in WGS84 decimal degrees.'),
23
+ radius_meters: z
24
+ .number()
25
+ .positive()
26
+ .max(50000)
27
+ .default(1000)
28
+ .describe('Search radius in meters. Max 50,000m (50km). Keep under 5,000m for dense urban POI queries to avoid slow responses.'),
29
+ amenity: z
30
+ .string()
31
+ .optional()
32
+ .describe('OSM amenity tag value (e.g., "hospital", "pharmacy", "restaurant", "school", "atm"). Shortcut for tag_key="amenity". Cannot be combined with tag_key/tag_value.'),
33
+ tag_key: z
34
+ .string()
35
+ .optional()
36
+ .describe('OSM tag key for non-amenity queries (e.g., "leisure", "shop", "highway", "natural"). Use with tag_value. Cannot be combined with amenity.'),
37
+ tag_value: z
38
+ .string()
39
+ .optional()
40
+ .describe('OSM tag value paired with tag_key (e.g., "park", "supermarket", "primary", "peak").'),
41
+ element_types: z
42
+ .array(z.enum(['node', 'way', 'relation']))
43
+ .default(['node', 'way'])
44
+ .describe('OSM element types to search. Ways cover most buildings and areas; nodes cover most standalone POIs. Add "relation" for complex structures like large campuses.'),
45
+ limit: z
46
+ .number()
47
+ .int()
48
+ .min(1)
49
+ .max(500)
50
+ .default(20)
51
+ .describe('Maximum results to return. Applied after the Overpass query — if the area has more features, they are truncated.'),
52
+ timeout_seconds: z
53
+ .number()
54
+ .int()
55
+ .min(5)
56
+ .max(60)
57
+ .default(25)
58
+ .describe('Overpass query timeout in seconds. Increase for large radius or dense areas.'),
59
+ }),
60
+ output: z.object({
61
+ elements: z
62
+ .array(z
63
+ .object({
64
+ osm_type: z.enum(['node', 'way', 'relation']).describe('OSM element type.'),
65
+ osm_id: z
66
+ .number()
67
+ .describe('OSM element ID. Use with osm_type for openstreetmap_lookup.'),
68
+ lat: z
69
+ .number()
70
+ .optional()
71
+ .describe('Latitude (present for nodes and ways/relations with computed center).'),
72
+ lon: z
73
+ .number()
74
+ .optional()
75
+ .describe('Longitude (present for nodes and ways/relations with computed center).'),
76
+ name: z.string().optional().describe('Feature name from OSM tags.'),
77
+ tags: z
78
+ .record(z.string(), z.string())
79
+ .describe('All OSM tags for this feature. Values are always strings.'),
80
+ })
81
+ .describe('A single matching OSM feature.'))
82
+ .describe('Matching OSM features, up to the limit.'),
83
+ total_found: z
84
+ .number()
85
+ .describe('Total features returned by Overpass before limit truncation.'),
86
+ truncated: z
87
+ .boolean()
88
+ .describe('True if results were cut at the limit. Reduce radius or add more specific tags to narrow the result set.'),
89
+ data_timestamp: z.string().describe('OSM data freshness timestamp from the Overpass response.'),
90
+ attribution: z
91
+ .string()
92
+ .describe('Required data attribution: Data © OpenStreetMap contributors, ODbL 1.0.'),
93
+ }),
94
+ errors: [
95
+ {
96
+ reason: 'invalid_tag',
97
+ code: JsonRpcErrorCode.ValidationError,
98
+ when: 'Both amenity and tag_key/tag_value are provided, or neither is provided.',
99
+ recovery: 'Provide either amenity (e.g., "hospital") or tag_key + tag_value (e.g., tag_key="leisure", tag_value="park"), but not both and not neither.',
100
+ },
101
+ {
102
+ reason: 'query_timeout',
103
+ code: JsonRpcErrorCode.Timeout,
104
+ when: 'The Overpass query exceeded the timeout.',
105
+ retryable: true,
106
+ recovery: 'Reduce radius_meters, add more specific tag filters, or increase timeout_seconds and retry.',
107
+ },
108
+ {
109
+ reason: 'rate_limited',
110
+ code: JsonRpcErrorCode.ServiceUnavailable,
111
+ when: 'Overpass returned HTTP 429 — all 4 concurrent query slots are occupied.',
112
+ retryable: true,
113
+ recovery: 'Wait a few seconds and retry. Reduce concurrent calls or switch to a private Overpass instance via OSM_OVERPASS_BASE_URL.',
114
+ },
115
+ ],
116
+ async handler(input, ctx) {
117
+ const resolved = resolveTagInput(input);
118
+ if ('error' in resolved) {
119
+ throw ctx.fail('invalid_tag', resolved.error === 'both'
120
+ ? 'Cannot combine amenity with tag_key/tag_value.'
121
+ : 'Provide either amenity or tag_key + tag_value.', { ...ctx.recoveryFor('invalid_tag') });
122
+ }
123
+ const { tagKey, tagValue } = resolved;
124
+ const service = getOverpassService();
125
+ const ql = service.buildAroundQuery({
126
+ lat: input.lat,
127
+ lon: input.lon,
128
+ radiusMeters: input.radius_meters,
129
+ tagKey,
130
+ tagValue,
131
+ elementTypes: input.element_types,
132
+ timeoutSeconds: input.timeout_seconds,
133
+ });
134
+ const response = await service.query(ql, ctx);
135
+ const allPois = service.normalizeElements(response.elements);
136
+ const limited = allPois.slice(0, input.limit);
137
+ const dataTimestamp = response.osm3s?.timestamp_osm_base ?? new Date().toISOString();
138
+ ctx.log.info('Overpass nearby results', {
139
+ total: allPois.length,
140
+ returned: limited.length,
141
+ });
142
+ return {
143
+ elements: limited,
144
+ total_found: allPois.length,
145
+ truncated: allPois.length > input.limit,
146
+ data_timestamp: dataTimestamp,
147
+ attribution: ATTRIBUTION,
148
+ };
149
+ },
150
+ format: (result) => {
151
+ const lines = [
152
+ `**${result.total_found} feature${result.total_found === 1 ? '' : 's'} found**${result.truncated ? ` (showing first ${result.elements.length} — results truncated)` : ''}`,
153
+ `**Data as of:** ${result.data_timestamp}`,
154
+ '',
155
+ ];
156
+ for (const el of result.elements) {
157
+ const nameStr = el.name ?? 'Unnamed';
158
+ lines.push(`## ${nameStr}`);
159
+ lines.push(`**OSM:** ${el.osm_type.charAt(0).toUpperCase()}${el.osm_id}`);
160
+ if (el.lat !== undefined && el.lon !== undefined) {
161
+ lines.push(`**Coordinates:** ${el.lat}, ${el.lon}`);
162
+ }
163
+ const tagEntries = Object.entries(el.tags)
164
+ .map(([k, v]) => `${k}=${v}`)
165
+ .join(', ');
166
+ if (tagEntries)
167
+ lines.push(`**Tags:** ${tagEntries}`);
168
+ lines.push('');
169
+ }
170
+ lines.push(`*${result.attribution}*`);
171
+ return [{ type: 'text', text: lines.join('\n') }];
172
+ },
173
+ });
174
+ //# sourceMappingURL=openstreetmap-query-nearby.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openstreetmap-query-nearby.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/openstreetmap-query-nearby.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Raw Overpass QL query tool — escape hatch for advanced spatial queries.
3
+ * @module mcp-server/tools/definitions/openstreetmap-query-raw.tool
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const openstreetmapQueryRaw: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ query: z.ZodString;
9
+ timeout_seconds: z.ZodDefault<z.ZodNumber>;
10
+ }, z.core.$strip>, z.ZodObject<{
11
+ elements: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
12
+ total_elements: z.ZodNumber;
13
+ data_timestamp: z.ZodOptional<z.ZodString>;
14
+ attribution: z.ZodString;
15
+ }, z.core.$strip>, readonly [{
16
+ readonly reason: "query_error";
17
+ readonly code: JsonRpcErrorCode.ValidationError;
18
+ readonly when: "Overpass returned a 400 error — malformed query syntax.";
19
+ readonly recovery: "Check Overpass QL syntax. Validate the query at overpass-turbo.eu before using this tool.";
20
+ }, {
21
+ readonly reason: "query_timeout";
22
+ readonly code: JsonRpcErrorCode.Timeout;
23
+ readonly when: "The query exceeded its timeout (Overpass runtime error in response body).";
24
+ readonly retryable: true;
25
+ readonly recovery: "Add [timeout:N] to the query string with a higher value, or simplify the query (smaller bbox, fewer element types, more specific tags).";
26
+ }, {
27
+ readonly reason: "result_too_large";
28
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
29
+ readonly when: "Overpass runtime error: query ran out of memory — result set exceeds the server memory limit.";
30
+ readonly recovery: "Narrow the query scope: reduce the bbox or around radius, add more tag filters, limit element types, or add [maxsize:N] to the query.";
31
+ }, {
32
+ readonly reason: "rate_limited";
33
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
34
+ readonly when: "Overpass returned HTTP 429 — all 4 concurrent query slots are occupied.";
35
+ readonly retryable: true;
36
+ readonly recovery: "Wait a few seconds and retry. Switch to a private Overpass instance via OSM_OVERPASS_BASE_URL for higher concurrency.";
37
+ }]>;
38
+ //# sourceMappingURL=openstreetmap-query-raw.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openstreetmap-query-raw.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/openstreetmap-query-raw.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKjE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8IhC,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @fileoverview Raw Overpass QL query tool — escape hatch for advanced spatial queries.
3
+ * @module mcp-server/tools/definitions/openstreetmap-query-raw.tool
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getOverpassService } from '../../../services/overpass/overpass-service.js';
8
+ const ATTRIBUTION = 'Data © OpenStreetMap contributors, ODbL 1.0';
9
+ export const openstreetmapQueryRaw = tool('openstreetmap_query_raw', {
10
+ title: 'Execute a raw Overpass QL query',
11
+ description: 'Execute a raw Overpass QL query for advanced spatial queries that the convenience tools do not cover. ' +
12
+ 'Use for multi-type queries, union queries, relation membership, historical queries, or any operation ' +
13
+ 'requiring full Overpass QL expressiveness. ' +
14
+ 'The query must include [out:json]. ' +
15
+ 'Example: "[out:json][timeout:15];node[\\"natural\\"=\\"peak\\"](47.5,-122.5,47.7,-122.2);out body;" ' +
16
+ 'Validate complex queries at overpass-turbo.eu before use. ' +
17
+ 'For simple "what\'s near X?" or "what\'s in this area?" queries, use openstreetmap_query_nearby or openstreetmap_query_bbox instead.',
18
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
19
+ input: z.object({
20
+ query: z
21
+ .string()
22
+ .describe('Overpass QL query string. Must include [out:json]. The server sets the endpoint and User-Agent; do not include those. Example: "[out:json][timeout:15];node[\\"natural\\"=\\"peak\\"](47.5,-122.5,47.7,-122.2);out body;"'),
23
+ timeout_seconds: z
24
+ .number()
25
+ .int()
26
+ .min(5)
27
+ .max(180)
28
+ .default(30)
29
+ .describe('Query timeout in seconds. The [timeout:N] directive in the query string takes precedence if present. Max 180s.'),
30
+ }),
31
+ output: z.object({
32
+ elements: z
33
+ .array(z.record(z.string(), z.unknown()))
34
+ .describe('Raw Overpass API response elements. Structure varies by query type — nodes have lat/lon, ways have nodes[], relations have members[].'),
35
+ total_elements: z.number().describe('Number of elements returned.'),
36
+ data_timestamp: z
37
+ .string()
38
+ .optional()
39
+ .describe('OSM data freshness timestamp from the Overpass response. Absent if not included in the response.'),
40
+ attribution: z
41
+ .string()
42
+ .describe('Required data attribution: Data © OpenStreetMap contributors, ODbL 1.0.'),
43
+ }),
44
+ errors: [
45
+ {
46
+ reason: 'query_error',
47
+ code: JsonRpcErrorCode.ValidationError,
48
+ when: 'Overpass returned a 400 error — malformed query syntax.',
49
+ recovery: 'Check Overpass QL syntax. Validate the query at overpass-turbo.eu before using this tool.',
50
+ },
51
+ {
52
+ reason: 'query_timeout',
53
+ code: JsonRpcErrorCode.Timeout,
54
+ when: 'The query exceeded its timeout (Overpass runtime error in response body).',
55
+ retryable: true,
56
+ recovery: 'Add [timeout:N] to the query string with a higher value, or simplify the query (smaller bbox, fewer element types, more specific tags).',
57
+ },
58
+ {
59
+ reason: 'result_too_large',
60
+ code: JsonRpcErrorCode.ServiceUnavailable,
61
+ when: 'Overpass runtime error: query ran out of memory — result set exceeds the server memory limit.',
62
+ recovery: 'Narrow the query scope: reduce the bbox or around radius, add more tag filters, limit element types, or add [maxsize:N] to the query.',
63
+ },
64
+ {
65
+ reason: 'rate_limited',
66
+ code: JsonRpcErrorCode.ServiceUnavailable,
67
+ when: 'Overpass returned HTTP 429 — all 4 concurrent query slots are occupied.',
68
+ retryable: true,
69
+ recovery: 'Wait a few seconds and retry. Switch to a private Overpass instance via OSM_OVERPASS_BASE_URL for higher concurrency.',
70
+ },
71
+ ],
72
+ async handler(input, ctx) {
73
+ let ql = input.query.trim();
74
+ // Preflight: require [out:json] before calling the service.
75
+ // Without it Overpass returns XML, JSON.parse throws, and the error surfaces as InternalError.
76
+ if (!ql.includes('[out:json]')) {
77
+ throw ctx.fail('query_error', 'Query is missing [out:json]. Add [out:json] at the start of the settings block (e.g. "[out:json][timeout:30];...").');
78
+ }
79
+ // Inject timeout if the query doesn't already include one
80
+ if (!ql.includes('[timeout:')) {
81
+ ql = ql.replace('[out:json]', `[out:json][timeout:${input.timeout_seconds}]`);
82
+ }
83
+ ctx.log.info('Overpass raw query', { queryLength: ql.length });
84
+ const service = getOverpassService();
85
+ const response = await service.query(ql, ctx);
86
+ const dataTimestamp = response.osm3s?.timestamp_osm_base;
87
+ ctx.log.info('Overpass raw results', { count: response.elements.length });
88
+ return {
89
+ elements: response.elements,
90
+ total_elements: response.elements.length,
91
+ ...(dataTimestamp ? { data_timestamp: dataTimestamp } : {}),
92
+ attribution: ATTRIBUTION,
93
+ };
94
+ },
95
+ format: (result) => {
96
+ const lines = [
97
+ `**${result.total_elements} element${result.total_elements === 1 ? '' : 's'} returned**`,
98
+ ];
99
+ if (result.data_timestamp) {
100
+ lines.push(`**Data as of:** ${result.data_timestamp}`);
101
+ }
102
+ lines.push('');
103
+ for (const el of result.elements.slice(0, 50)) {
104
+ const type = String(el.type ?? 'unknown');
105
+ const id = String(el.id ?? '?');
106
+ const tags = el.tags;
107
+ const name = tags?.name;
108
+ lines.push(`**${type}** ${id}${name ? ` — ${name}` : ''}`);
109
+ if (tags && Object.keys(tags).length > 0) {
110
+ const tagStr = Object.entries(tags)
111
+ .map(([k, v]) => `${k}=${v}`)
112
+ .join(', ');
113
+ lines.push(` Tags: ${tagStr}`);
114
+ }
115
+ }
116
+ if (result.elements.length > 50) {
117
+ lines.push(`... and ${result.elements.length - 50} more elements`);
118
+ }
119
+ lines.push('');
120
+ lines.push(`*${result.attribution}*`);
121
+ return [{ type: 'text', text: lines.join('\n') }];
122
+ },
123
+ });
124
+ //# sourceMappingURL=openstreetmap-query-raw.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openstreetmap-query-raw.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/openstreetmap-query-raw.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Reverse geocoding tool — converts coordinates to nearest address or place.
3
+ * @module mcp-server/tools/definitions/openstreetmap-reverse.tool
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const openstreetmapReverse: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ lat: z.ZodNumber;
9
+ lon: z.ZodNumber;
10
+ zoom: z.ZodDefault<z.ZodNumber>;
11
+ layer: z.ZodOptional<z.ZodString>;
12
+ extratags: z.ZodDefault<z.ZodBoolean>;
13
+ language: z.ZodOptional<z.ZodString>;
14
+ }, z.core.$strip>, z.ZodObject<{
15
+ result: z.ZodObject<{
16
+ place_id: z.ZodNumber;
17
+ osm_type: z.ZodOptional<z.ZodEnum<{
18
+ node: "node";
19
+ way: "way";
20
+ relation: "relation";
21
+ }>>;
22
+ osm_id: z.ZodOptional<z.ZodNumber>;
23
+ lat: z.ZodString;
24
+ lon: z.ZodString;
25
+ display_name: z.ZodString;
26
+ name: z.ZodOptional<z.ZodString>;
27
+ category: z.ZodOptional<z.ZodString>;
28
+ type: z.ZodOptional<z.ZodString>;
29
+ address: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
30
+ boundingbox: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString, z.ZodString], null>>;
31
+ extratags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
32
+ }, z.core.$strip>;
33
+ attribution: z.ZodString;
34
+ }, z.core.$strip>, readonly [{
35
+ readonly reason: "no_coverage";
36
+ readonly code: JsonRpcErrorCode.NotFound;
37
+ readonly when: "Nominatim returns an error indicating no OSM data at the given coordinates (e.g., open ocean or unmapped territory).";
38
+ readonly recovery: "Verify the coordinates are correct. Try a lower zoom value to match at a coarser level (e.g., zoom=10 for city-level).";
39
+ }]>;
40
+ //# sourceMappingURL=openstreetmap-reverse.tool.d.ts.map