@ignfab/geocontext 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +349 -259
- package/dist/gpf/adminexpress.d.ts +17 -8
- package/dist/gpf/adminexpress.js +40 -17
- package/dist/gpf/adminexpress.js.map +1 -1
- package/dist/gpf/altitude.d.ts +21 -9
- package/dist/gpf/altitude.js +5 -5
- package/dist/gpf/altitude.js.map +1 -1
- package/dist/gpf/geocode.d.ts +25 -4
- package/dist/gpf/geocode.js +5 -5
- package/dist/gpf/geocode.js.map +1 -1
- package/dist/gpf/parcellaire-express.d.ts +19 -9
- package/dist/gpf/parcellaire-express.js +59 -26
- package/dist/gpf/parcellaire-express.js.map +1 -1
- package/dist/gpf/urbanisme.d.ts +24 -16
- package/dist/gpf/urbanisme.js +81 -33
- package/dist/gpf/urbanisme.js.map +1 -1
- package/dist/gpf/{wfs.js → wfs-schema-catalog.js} +1 -1
- package/dist/gpf/wfs-schema-catalog.js.map +1 -0
- package/dist/helpers/RateLimiter.d.ts +44 -0
- package/dist/helpers/RateLimiter.js +52 -0
- package/dist/helpers/RateLimiter.js.map +1 -0
- package/dist/helpers/distance.d.ts +2 -1
- package/dist/helpers/distance.js +2 -1
- package/dist/helpers/distance.js.map +1 -1
- package/dist/helpers/errors/toolError.d.ts +30 -0
- package/dist/helpers/errors/toolError.js +193 -0
- package/dist/helpers/errors/toolError.js.map +1 -0
- package/dist/helpers/errors/zodErrorMapFr.d.ts +20 -0
- package/dist/helpers/errors/zodErrorMapFr.js +191 -0
- package/dist/helpers/errors/zodErrorMapFr.js.map +1 -0
- package/dist/helpers/http.d.ts +67 -7
- package/dist/helpers/http.js +458 -84
- package/dist/helpers/http.js.map +1 -1
- package/dist/helpers/jsonSchema.d.ts +20 -2
- package/dist/helpers/jsonSchema.js +12 -0
- package/dist/helpers/jsonSchema.js.map +1 -1
- package/dist/helpers/schemas.d.ts +4 -4
- package/dist/helpers/wfs_engine/attributeFilter.d.ts +51 -0
- package/dist/helpers/wfs_engine/attributeFilter.js +258 -0
- package/dist/helpers/wfs_engine/attributeFilter.js.map +1 -0
- package/dist/helpers/wfs_engine/byId.d.ts +76 -0
- package/dist/helpers/wfs_engine/byId.js +106 -0
- package/dist/helpers/wfs_engine/byId.js.map +1 -0
- package/dist/helpers/wfs_engine/execution.d.ts +72 -0
- package/dist/helpers/wfs_engine/execution.js +95 -0
- package/dist/helpers/wfs_engine/execution.js.map +1 -0
- package/dist/helpers/wfs_engine/features.d.ts +64 -0
- package/dist/helpers/wfs_engine/features.js +138 -0
- package/dist/helpers/wfs_engine/features.js.map +1 -0
- package/dist/helpers/wfs_engine/geometry.d.ts +16 -0
- package/dist/helpers/wfs_engine/geometry.js +44 -0
- package/dist/helpers/wfs_engine/geometry.js.map +1 -0
- package/dist/helpers/wfs_engine/properties.d.ts +51 -0
- package/dist/helpers/wfs_engine/properties.js +128 -0
- package/dist/helpers/wfs_engine/properties.js.map +1 -0
- package/dist/helpers/wfs_engine/queryPreparation.d.ts +32 -0
- package/dist/helpers/wfs_engine/queryPreparation.js +149 -0
- package/dist/helpers/wfs_engine/queryPreparation.js.map +1 -0
- package/dist/helpers/wfs_engine/request.d.ts +94 -0
- package/dist/helpers/wfs_engine/request.js +197 -0
- package/dist/helpers/wfs_engine/request.js.map +1 -0
- package/dist/helpers/wfs_engine/response.d.ts +80 -0
- package/dist/helpers/wfs_engine/response.js +135 -0
- package/dist/helpers/wfs_engine/response.js.map +1 -0
- package/dist/helpers/wfs_engine/schema.d.ts +209 -0
- package/dist/helpers/{wfs_internal → wfs_engine}/schema.js +50 -10
- package/dist/helpers/wfs_engine/schema.js.map +1 -0
- package/dist/helpers/wfs_engine/spatialCql.d.ts +46 -0
- package/dist/helpers/wfs_engine/spatialCql.js +54 -0
- package/dist/helpers/wfs_engine/spatialCql.js.map +1 -0
- package/dist/helpers/wfs_engine/spatialFilter.d.ts +14 -0
- package/dist/helpers/wfs_engine/spatialFilter.js +131 -0
- package/dist/helpers/wfs_engine/spatialFilter.js.map +1 -0
- package/dist/index.js +65 -23
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +4 -1
- package/dist/logger.js.map +1 -1
- package/dist/tools/AdminexpressTool.d.ts +42 -33
- package/dist/tools/AdminexpressTool.js +19 -3
- package/dist/tools/AdminexpressTool.js.map +1 -1
- package/dist/tools/AltitudeTool.d.ts +35 -44
- package/dist/tools/AltitudeTool.js +19 -8
- package/dist/tools/AltitudeTool.js.map +1 -1
- package/dist/tools/AssietteSupTool.d.ts +51 -34
- package/dist/tools/AssietteSupTool.js +18 -2
- package/dist/tools/AssietteSupTool.js.map +1 -1
- package/dist/tools/BaseTool.d.ts +17 -0
- package/dist/tools/BaseTool.js +41 -0
- package/dist/tools/BaseTool.js.map +1 -0
- package/dist/tools/CadastreTool.d.ts +53 -33
- package/dist/tools/CadastreTool.js +18 -2
- package/dist/tools/CadastreTool.js.map +1 -1
- package/dist/tools/GeocodeTool.d.ts +53 -37
- package/dist/tools/GeocodeTool.js +17 -2
- package/dist/tools/GeocodeTool.js.map +1 -1
- package/dist/tools/GpfWfsDescribeTypeTool.d.ts +66 -94
- package/dist/tools/GpfWfsDescribeTypeTool.js +26 -15
- package/dist/tools/GpfWfsDescribeTypeTool.js.map +1 -1
- package/dist/tools/GpfWfsGetFeatureByIdTool.d.ts +89 -0
- package/dist/tools/GpfWfsGetFeatureByIdTool.js +99 -0
- package/dist/tools/GpfWfsGetFeatureByIdTool.js.map +1 -0
- package/dist/tools/GpfWfsGetFeaturesTool.d.ts +89 -123
- package/dist/tools/GpfWfsGetFeaturesTool.js +31 -144
- package/dist/tools/GpfWfsGetFeaturesTool.js.map +1 -1
- package/dist/tools/GpfWfsSearchTypesTool.d.ts +41 -32
- package/dist/tools/GpfWfsSearchTypesTool.js +18 -3
- package/dist/tools/GpfWfsSearchTypesTool.js.map +1 -1
- package/dist/tools/UrbanismeTool.d.ts +42 -33
- package/dist/tools/UrbanismeTool.js +18 -2
- package/dist/tools/UrbanismeTool.js.map +1 -1
- package/package.json +51 -24
- package/dist/gpf/wfs.js.map +0 -1
- package/dist/helpers/wfs.d.ts +0 -27
- package/dist/helpers/wfs.js +0 -55
- package/dist/helpers/wfs.js.map +0 -1
- package/dist/helpers/wfs_internal/compile.d.ts +0 -46
- package/dist/helpers/wfs_internal/compile.js +0 -595
- package/dist/helpers/wfs_internal/compile.js.map +0 -1
- package/dist/helpers/wfs_internal/request.d.ts +0 -38
- package/dist/helpers/wfs_internal/request.js +0 -92
- package/dist/helpers/wfs_internal/request.js.map +0 -1
- package/dist/helpers/wfs_internal/response.d.ts +0 -21
- package/dist/helpers/wfs_internal/response.js +0 -29
- package/dist/helpers/wfs_internal/response.js.map +0 -1
- package/dist/helpers/wfs_internal/schema.d.ts +0 -167
- package/dist/helpers/wfs_internal/schema.js.map +0 -1
- /package/dist/gpf/{wfs.d.ts → wfs-schema-catalog.d.ts} +0 -0
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import BaseTool from "./BaseTool.js";
|
|
2
|
+
import { type GpfWfsGetFeaturesInput } from "../helpers/wfs_engine/schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* MCP tool exposing structured WFS feature search.
|
|
5
|
+
*
|
|
6
|
+
* The tool remains responsible for MCP schema exposure and response formatting.
|
|
7
|
+
* WFS request preparation and execution live in the structured WFS engine.
|
|
8
|
+
*/
|
|
9
|
+
declare class GpfWfsGetFeaturesTool extends BaseTool<GpfWfsGetFeaturesInput> {
|
|
6
10
|
name: string;
|
|
7
11
|
title: string;
|
|
8
12
|
annotations: {
|
|
@@ -21,11 +25,11 @@ declare class GpfWfsGetFeaturesTool extends MCPTool<GpfWfsGetFeaturesInput> {
|
|
|
21
25
|
property: import("zod").ZodString;
|
|
22
26
|
direction: import("zod").ZodDefault<import("zod").ZodEnum<["asc", "desc"]>>;
|
|
23
27
|
}, "strict", import("zod").ZodTypeAny, {
|
|
24
|
-
property
|
|
25
|
-
direction
|
|
28
|
+
property: string;
|
|
29
|
+
direction: "asc" | "desc";
|
|
26
30
|
}, {
|
|
27
|
-
property
|
|
28
|
-
direction?: "asc" | "desc";
|
|
31
|
+
property: string;
|
|
32
|
+
direction?: "asc" | "desc" | undefined;
|
|
29
33
|
}>, "many">>;
|
|
30
34
|
where: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
31
35
|
property: import("zod").ZodString;
|
|
@@ -33,15 +37,15 @@ declare class GpfWfsGetFeaturesTool extends MCPTool<GpfWfsGetFeaturesInput> {
|
|
|
33
37
|
value: import("zod").ZodOptional<import("zod").ZodString>;
|
|
34
38
|
values: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
|
|
35
39
|
}, "strict", import("zod").ZodTypeAny, {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
property: string;
|
|
41
|
+
operator: "gte" | "gt" | "lte" | "lt" | "eq" | "ne" | "in" | "is_null";
|
|
42
|
+
values?: string[] | undefined;
|
|
43
|
+
value?: string | undefined;
|
|
40
44
|
}, {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
property: string;
|
|
46
|
+
operator: "gte" | "gt" | "lte" | "lt" | "eq" | "ne" | "in" | "is_null";
|
|
47
|
+
values?: string[] | undefined;
|
|
48
|
+
value?: string | undefined;
|
|
45
49
|
}>, "many">>;
|
|
46
50
|
spatial_operator: import("zod").ZodOptional<import("zod").ZodEnum<["bbox", "intersects_point", "dwithin_point", "intersects_feature"]>>;
|
|
47
51
|
bbox_west: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
@@ -56,70 +60,66 @@ declare class GpfWfsGetFeaturesTool extends MCPTool<GpfWfsGetFeaturesInput> {
|
|
|
56
60
|
intersects_feature_typename: import("zod").ZodOptional<import("zod").ZodString>;
|
|
57
61
|
intersects_feature_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
58
62
|
}, "strict", import("zod").ZodTypeAny, {
|
|
59
|
-
typename
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
select?: string[];
|
|
63
|
+
typename: string;
|
|
64
|
+
result_type: "request" | "results" | "hits";
|
|
65
|
+
limit: number;
|
|
66
|
+
select?: string[] | undefined;
|
|
63
67
|
order_by?: {
|
|
64
|
-
property
|
|
65
|
-
direction
|
|
66
|
-
}[];
|
|
68
|
+
property: string;
|
|
69
|
+
direction: "asc" | "desc";
|
|
70
|
+
}[] | undefined;
|
|
67
71
|
where?: {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}[];
|
|
73
|
-
spatial_operator?: "bbox" | "intersects_point" | "dwithin_point" | "intersects_feature";
|
|
74
|
-
bbox_west?: number;
|
|
75
|
-
bbox_south?: number;
|
|
76
|
-
bbox_east?: number;
|
|
77
|
-
bbox_north?: number;
|
|
78
|
-
intersects_lon?: number;
|
|
79
|
-
intersects_lat?: number;
|
|
80
|
-
dwithin_lon?: number;
|
|
81
|
-
dwithin_lat?: number;
|
|
82
|
-
dwithin_distance_m?: number;
|
|
83
|
-
intersects_feature_typename?: string;
|
|
84
|
-
intersects_feature_id?: string;
|
|
72
|
+
property: string;
|
|
73
|
+
operator: "gte" | "gt" | "lte" | "lt" | "eq" | "ne" | "in" | "is_null";
|
|
74
|
+
values?: string[] | undefined;
|
|
75
|
+
value?: string | undefined;
|
|
76
|
+
}[] | undefined;
|
|
77
|
+
spatial_operator?: "bbox" | "intersects_point" | "dwithin_point" | "intersects_feature" | undefined;
|
|
78
|
+
bbox_west?: number | undefined;
|
|
79
|
+
bbox_south?: number | undefined;
|
|
80
|
+
bbox_east?: number | undefined;
|
|
81
|
+
bbox_north?: number | undefined;
|
|
82
|
+
intersects_lon?: number | undefined;
|
|
83
|
+
intersects_lat?: number | undefined;
|
|
84
|
+
dwithin_lon?: number | undefined;
|
|
85
|
+
dwithin_lat?: number | undefined;
|
|
86
|
+
dwithin_distance_m?: number | undefined;
|
|
87
|
+
intersects_feature_typename?: string | undefined;
|
|
88
|
+
intersects_feature_id?: string | undefined;
|
|
85
89
|
}, {
|
|
86
|
-
typename
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
select?: string[];
|
|
90
|
+
typename: string;
|
|
91
|
+
result_type?: "request" | "results" | "hits" | undefined;
|
|
92
|
+
limit?: number | undefined;
|
|
93
|
+
select?: string[] | undefined;
|
|
90
94
|
order_by?: {
|
|
91
|
-
property
|
|
92
|
-
direction?: "asc" | "desc";
|
|
93
|
-
}[];
|
|
95
|
+
property: string;
|
|
96
|
+
direction?: "asc" | "desc" | undefined;
|
|
97
|
+
}[] | undefined;
|
|
94
98
|
where?: {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}[];
|
|
100
|
-
spatial_operator?: "bbox" | "intersects_point" | "dwithin_point" | "intersects_feature";
|
|
101
|
-
bbox_west?: number;
|
|
102
|
-
bbox_south?: number;
|
|
103
|
-
bbox_east?: number;
|
|
104
|
-
bbox_north?: number;
|
|
105
|
-
intersects_lon?: number;
|
|
106
|
-
intersects_lat?: number;
|
|
107
|
-
dwithin_lon?: number;
|
|
108
|
-
dwithin_lat?: number;
|
|
109
|
-
dwithin_distance_m?: number;
|
|
110
|
-
intersects_feature_typename?: string;
|
|
111
|
-
intersects_feature_id?: string;
|
|
99
|
+
property: string;
|
|
100
|
+
operator: "gte" | "gt" | "lte" | "lt" | "eq" | "ne" | "in" | "is_null";
|
|
101
|
+
values?: string[] | undefined;
|
|
102
|
+
value?: string | undefined;
|
|
103
|
+
}[] | undefined;
|
|
104
|
+
spatial_operator?: "bbox" | "intersects_point" | "dwithin_point" | "intersects_feature" | undefined;
|
|
105
|
+
bbox_west?: number | undefined;
|
|
106
|
+
bbox_south?: number | undefined;
|
|
107
|
+
bbox_east?: number | undefined;
|
|
108
|
+
bbox_north?: number | undefined;
|
|
109
|
+
intersects_lon?: number | undefined;
|
|
110
|
+
intersects_lat?: number | undefined;
|
|
111
|
+
dwithin_lon?: number | undefined;
|
|
112
|
+
dwithin_lat?: number | undefined;
|
|
113
|
+
dwithin_distance_m?: number | undefined;
|
|
114
|
+
intersects_feature_typename?: string | undefined;
|
|
115
|
+
intersects_feature_id?: string | undefined;
|
|
112
116
|
}>;
|
|
113
117
|
/**
|
|
114
118
|
* Exposes an input schema variant that stays compatible with most MCP integrations.
|
|
115
119
|
*
|
|
116
120
|
* @returns The published input schema exposed through the MCP tool definition.
|
|
117
121
|
*/
|
|
118
|
-
get inputSchema():
|
|
119
|
-
type: "object";
|
|
120
|
-
properties?: Record<string, object>;
|
|
121
|
-
required?: string[];
|
|
122
|
-
};
|
|
122
|
+
get inputSchema(): import("../helpers/jsonSchema.js").PublishedInputSchema;
|
|
123
123
|
/**
|
|
124
124
|
* Formats compact responses (`hits`, `request`) into `structuredContent`.
|
|
125
125
|
* Full result sets are still delegated to the framework default behavior.
|
|
@@ -133,8 +133,8 @@ declare class GpfWfsGetFeaturesTool extends MCPTool<GpfWfsGetFeaturesInput> {
|
|
|
133
133
|
text: string;
|
|
134
134
|
}[];
|
|
135
135
|
structuredContent: {
|
|
136
|
-
result_type
|
|
137
|
-
totalFeatures
|
|
136
|
+
result_type: "hits";
|
|
137
|
+
totalFeatures: number;
|
|
138
138
|
};
|
|
139
139
|
} | {
|
|
140
140
|
content: {
|
|
@@ -142,64 +142,30 @@ declare class GpfWfsGetFeaturesTool extends MCPTool<GpfWfsGetFeaturesInput> {
|
|
|
142
142
|
text: string;
|
|
143
143
|
}[];
|
|
144
144
|
structuredContent: {
|
|
145
|
-
|
|
146
|
-
result_type
|
|
147
|
-
method
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
get_url?: string;
|
|
145
|
+
url: string;
|
|
146
|
+
result_type: "request";
|
|
147
|
+
method: "POST";
|
|
148
|
+
query: Record<string, string>;
|
|
149
|
+
body: string;
|
|
150
|
+
get_url?: string | null | undefined;
|
|
151
151
|
};
|
|
152
152
|
};
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* @param typename Exact WFS typename to load from the embedded schema store.
|
|
157
|
-
* @returns The matching feature type description.
|
|
158
|
-
*/
|
|
159
|
-
protected getFeatureType(typename: string): Promise<Collection>;
|
|
160
|
-
/**
|
|
161
|
-
* Executes a compiled WFS request as POST and returns the JSON FeatureCollection.
|
|
162
|
-
*
|
|
163
|
-
* @param request Compiled request split into query-string parameters and POST body.
|
|
164
|
-
* @returns The parsed JSON response returned by the WFS endpoint.
|
|
165
|
-
*/
|
|
166
|
-
protected fetchFeatureCollection(request: CompiledRequest): Promise<any>;
|
|
167
|
-
/**
|
|
168
|
-
* Extracts a result count from a WFS response, preferring `numberMatched`.
|
|
169
|
-
* Explicitly rejects responses that do not provide a usable total.
|
|
170
|
-
*
|
|
171
|
-
* @param featureCollection Parsed WFS response object.
|
|
172
|
-
* @returns The total number of matching features.
|
|
173
|
-
*/
|
|
174
|
-
protected getMatchedFeatureCount(featureCollection: Record<string, unknown>): number;
|
|
175
|
-
/**
|
|
176
|
-
* Enriches transformed features with a complete `feature_ref`, reusable
|
|
177
|
-
* in particular by `intersects_feature`.
|
|
178
|
-
*
|
|
179
|
-
* @param featureCollection Raw WFS FeatureCollection response.
|
|
180
|
-
* @param typename Typename of the main queried layer.
|
|
181
|
-
* @returns The transformed FeatureCollection with fully populated feature references.
|
|
182
|
-
*/
|
|
183
|
-
protected attachFeatureRefs(featureCollection: Record<string, unknown>, typename: string): Record<string, unknown>;
|
|
184
|
-
/**
|
|
185
|
-
* Resolves the geometry of a reference feature when `intersects_feature` is used,
|
|
186
|
-
* then converts it to EWKT for CQL compilation.
|
|
154
|
+
* Orchestrates the MCP-facing execution flow.
|
|
187
155
|
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*/
|
|
191
|
-
protected resolveIntersectsFeatureGeometry(input: GpfWfsGetFeaturesInput): Promise<{
|
|
192
|
-
typename: string;
|
|
193
|
-
feature_id: string;
|
|
194
|
-
geometry_ewkt: string;
|
|
195
|
-
}>;
|
|
196
|
-
/**
|
|
197
|
-
* Orchestrates the full tool execution flow:
|
|
198
|
-
* catalog lookup -> compilation -> WFS request -> response post-processing.
|
|
156
|
+
* Request previews stay in the tool because they are a tool-specific output
|
|
157
|
+
* mode, while the WFS-side preparation and execution live in `features.ts`.
|
|
199
158
|
*
|
|
200
159
|
* @param input Normalized tool input.
|
|
201
160
|
* @returns Either a compiled request, a hit count, or a transformed FeatureCollection.
|
|
202
161
|
*/
|
|
203
|
-
execute(input: GpfWfsGetFeaturesInput): Promise<Record<string, unknown
|
|
162
|
+
execute(input: GpfWfsGetFeaturesInput): Promise<import("../helpers/wfs_engine/request.js").WfsRequestPayload | (Record<string, unknown> & {
|
|
163
|
+
features?: (Record<string, unknown> & {
|
|
164
|
+
feature_ref?: {
|
|
165
|
+
typename: string | null;
|
|
166
|
+
feature_id: string;
|
|
167
|
+
};
|
|
168
|
+
})[];
|
|
169
|
+
})>;
|
|
204
170
|
}
|
|
205
171
|
export default GpfWfsGetFeaturesTool;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { wfsClient } from "../gpf/wfs.js";
|
|
3
|
-
import { fetchJSONPost } from "../helpers/http.js";
|
|
4
|
-
import logger from "../logger.js";
|
|
1
|
+
import BaseTool from "./BaseTool.js";
|
|
5
2
|
import { READ_ONLY_OPEN_WORLD_TOOL_ANNOTATIONS } from "../helpers/toolAnnotations.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
|
|
3
|
+
import { executeGetFeatures, prepareGetFeaturesRequest, } from "../helpers/wfs_engine/features.js";
|
|
4
|
+
import { toWfsRequestPayload } from "../helpers/wfs_engine/request.js";
|
|
5
|
+
import { gpfWfsGetFeaturesHitsOutputSchema, gpfWfsGetFeaturesInputSchema, gpfWfsGetFeaturesPublishedInputSchema, gpfWfsGetFeaturesRequestOutputSchema, } from "../helpers/wfs_engine/schema.js";
|
|
6
|
+
import logger from "../logger.js";
|
|
7
|
+
/**
|
|
8
|
+
* MCP tool exposing structured WFS feature search.
|
|
9
|
+
*
|
|
10
|
+
* The tool remains responsible for MCP schema exposure and response formatting.
|
|
11
|
+
* WFS request preparation and execution live in the structured WFS engine.
|
|
12
|
+
*/
|
|
13
|
+
// --- Tool ---
|
|
14
|
+
class GpfWfsGetFeaturesTool extends BaseTool {
|
|
11
15
|
name = "gpf_wfs_get_features";
|
|
12
16
|
title = "Lecture d’objets WFS";
|
|
13
17
|
annotations = READ_ONLY_OPEN_WORLD_TOOL_ANNOTATIONS;
|
|
@@ -16,9 +20,15 @@ class GpfWfsGetFeaturesTool extends MCPTool {
|
|
|
16
20
|
"Utiliser `select` pour choisir les propriétés, `where` pour filtrer, `order_by` pour trier et `spatial_operator` avec ses paramètres dédiés pour le spatial. Avec `result_type=\"request\"`, la géométrie est automatiquement ajoutée aux propriétés sélectionnées pour garantir une requête cartographiable.",
|
|
17
21
|
"Exemple attributaire : `where=[{ property: \"code_insee\", operator: \"eq\", value: \"75056\" }]`.",
|
|
18
22
|
"Exemple bbox : `spatial_operator=\"bbox\"` avec `bbox_west`, `bbox_south`, `bbox_east`, `bbox_north` en `lon/lat`.",
|
|
23
|
+
"Exemple point dans géométrie : `spatial_operator=\"intersects_point\"` avec `intersects_lon` et `intersects_lat`.",
|
|
19
24
|
"Exemple distance : `spatial_operator=\"dwithin_point\"` avec `dwithin_lon`, `dwithin_lat`, `dwithin_distance_m`.",
|
|
20
25
|
"Exemple réutilisation : `spatial_operator=\"intersects_feature\"` avec `intersects_feature_typename` et `intersects_feature_id` issus d'une `feature_ref`.",
|
|
26
|
+
"⚠️ Quand `typename` et `intersects_feature_typename` sont identiques, utiliser `gpf_wfs_get_feature_by_id` pour récupérer exactement l'objet ciblé.",
|
|
27
|
+
"**OBLIGATOIRE : toujours appeler `gpf_wfs_describe_type` avant ce tool, sauf si `gpf_wfs_describe_type` a déjà été appelé pour ce même typename dans la conversation en cours.**",
|
|
28
|
+
"Les noms de propriétés **ne peuvent pas être devinés** : ils sont spécifiques à chaque typename et diffèrent systématiquement des conventions habituelles (ex : pas de nom_officiel, navigabilite sans accent, etc.). Toute tentative sans appel préalable à `gpf_wfs_describe_type` **provoquera une erreur.**",
|
|
21
29
|
].join("\n");
|
|
30
|
+
// `schema` remains the runtime validation source, while `inputSchema`
|
|
31
|
+
// publishes the MCP-facing variant expected by clients.
|
|
22
32
|
schema = gpfWfsGetFeaturesInputSchema;
|
|
23
33
|
/**
|
|
24
34
|
* Exposes an input schema variant that stays compatible with most MCP integrations.
|
|
@@ -42,9 +52,10 @@ class GpfWfsGetFeaturesTool extends MCPTool {
|
|
|
42
52
|
data.result_type === "hits" &&
|
|
43
53
|
"totalFeatures" in data &&
|
|
44
54
|
typeof data.totalFeatures === "number") {
|
|
55
|
+
const payload = gpfWfsGetFeaturesHitsOutputSchema.parse(data);
|
|
45
56
|
return {
|
|
46
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
47
|
-
structuredContent:
|
|
57
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
58
|
+
structuredContent: payload,
|
|
48
59
|
};
|
|
49
60
|
}
|
|
50
61
|
if (typeof data === "object" &&
|
|
@@ -59,147 +70,23 @@ class GpfWfsGetFeaturesTool extends MCPTool {
|
|
|
59
70
|
return super.createSuccessResponse(data);
|
|
60
71
|
}
|
|
61
72
|
/**
|
|
62
|
-
*
|
|
73
|
+
* Orchestrates the MCP-facing execution flow.
|
|
63
74
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*/
|
|
67
|
-
async getFeatureType(typename) {
|
|
68
|
-
return wfsClient.getFeatureType(typename);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Executes a compiled WFS request as POST and returns the JSON FeatureCollection.
|
|
72
|
-
*
|
|
73
|
-
* @param request Compiled request split into query-string parameters and POST body.
|
|
74
|
-
* @returns The parsed JSON response returned by the WFS endpoint.
|
|
75
|
-
*/
|
|
76
|
-
async fetchFeatureCollection(request) {
|
|
77
|
-
const url = `${request.url}?${new URLSearchParams(request.query).toString()}`;
|
|
78
|
-
return fetchJSONPost(url, request.body, {
|
|
79
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
80
|
-
"Accept": "application/json",
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Extracts a result count from a WFS response, preferring `numberMatched`.
|
|
85
|
-
* Explicitly rejects responses that do not provide a usable total.
|
|
86
|
-
*
|
|
87
|
-
* @param featureCollection Parsed WFS response object.
|
|
88
|
-
* @returns The total number of matching features.
|
|
89
|
-
*/
|
|
90
|
-
getMatchedFeatureCount(featureCollection) {
|
|
91
|
-
if (typeof featureCollection.numberMatched === "number") {
|
|
92
|
-
return featureCollection.numberMatched;
|
|
93
|
-
}
|
|
94
|
-
if (featureCollection.numberMatched === "unknown") {
|
|
95
|
-
throw new Error("Le service WFS a renvoyé un comptage indéterminé (numberMatched=\"unknown\").");
|
|
96
|
-
}
|
|
97
|
-
if (typeof featureCollection.totalFeatures === "number") {
|
|
98
|
-
return featureCollection.totalFeatures;
|
|
99
|
-
}
|
|
100
|
-
throw new Error("Le service WFS n'a pas retourné de comptage exploitable");
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Enriches transformed features with a complete `feature_ref`, reusable
|
|
104
|
-
* in particular by `intersects_feature`.
|
|
105
|
-
*
|
|
106
|
-
* @param featureCollection Raw WFS FeatureCollection response.
|
|
107
|
-
* @param typename Typename of the main queried layer.
|
|
108
|
-
* @returns The transformed FeatureCollection with fully populated feature references.
|
|
109
|
-
*/
|
|
110
|
-
attachFeatureRefs(featureCollection, typename) {
|
|
111
|
-
const transformed = transformFeatureCollectionResponse(featureCollection);
|
|
112
|
-
if (!Array.isArray(transformed.features)) {
|
|
113
|
-
return transformed;
|
|
114
|
-
}
|
|
115
|
-
transformed.features = transformed.features.map((feature) => {
|
|
116
|
-
if (typeof feature !== "object" || feature === null || !("feature_ref" in feature)) {
|
|
117
|
-
return feature;
|
|
118
|
-
}
|
|
119
|
-
const featureRef = feature.feature_ref;
|
|
120
|
-
if (typeof featureRef !== "object" || featureRef === null) {
|
|
121
|
-
return feature;
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
...feature,
|
|
125
|
-
feature_ref: {
|
|
126
|
-
...featureRef,
|
|
127
|
-
typename,
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
});
|
|
131
|
-
return transformed;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Resolves the geometry of a reference feature when `intersects_feature` is used,
|
|
135
|
-
* then converts it to EWKT for CQL compilation.
|
|
136
|
-
*
|
|
137
|
-
* @param input Normalized tool input.
|
|
138
|
-
* @returns The resolved reference geometry, or `undefined` when no reference feature is needed.
|
|
139
|
-
*/
|
|
140
|
-
async resolveIntersectsFeatureGeometry(input) {
|
|
141
|
-
const spatialFilter = getSpatialFilter(input);
|
|
142
|
-
if (!spatialFilter || spatialFilter.operator !== "intersects_feature") {
|
|
143
|
-
return undefined;
|
|
144
|
-
}
|
|
145
|
-
const referenceFeatureType = await this.getFeatureType(spatialFilter.typename);
|
|
146
|
-
const referenceGeometryProperty = getGeometryProperty(referenceFeatureType);
|
|
147
|
-
const request = buildReferenceGeometryRequest(spatialFilter.typename, spatialFilter.feature_id, referenceGeometryProperty.name);
|
|
148
|
-
const featureCollection = await this.fetchFeatureCollection(request);
|
|
149
|
-
const referenceFeature = Array.isArray(featureCollection?.features) ? featureCollection.features[0] : undefined;
|
|
150
|
-
if (!referenceFeature) {
|
|
151
|
-
throw new Error(`Le feature de référence '${spatialFilter.feature_id}' est introuvable dans '${spatialFilter.typename}'.`);
|
|
152
|
-
}
|
|
153
|
-
if (!referenceFeature?.geometry) {
|
|
154
|
-
throw new Error(`Le feature de référence '${spatialFilter.feature_id}' n'a pas de géométrie exploitable.`);
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
typename: spatialFilter.typename,
|
|
158
|
-
feature_id: spatialFilter.feature_id,
|
|
159
|
-
geometry_ewkt: geometryToEwkt(referenceFeature.geometry),
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Orchestrates the full tool execution flow:
|
|
164
|
-
* catalog lookup -> compilation -> WFS request -> response post-processing.
|
|
75
|
+
* Request previews stay in the tool because they are a tool-specific output
|
|
76
|
+
* mode, while the WFS-side preparation and execution live in `features.ts`.
|
|
165
77
|
*
|
|
166
78
|
* @param input Normalized tool input.
|
|
167
79
|
* @returns Either a compiled request, a hit count, or a transformed FeatureCollection.
|
|
168
80
|
*/
|
|
169
81
|
async execute(input) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const request = buildMainRequest(input, compiled);
|
|
82
|
+
logger.info(`[tool] execute ${this.name} ...`, {
|
|
83
|
+
input: input
|
|
84
|
+
});
|
|
174
85
|
if (input.result_type === "request") {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
method: request.method,
|
|
178
|
-
url: request.url,
|
|
179
|
-
query: request.query,
|
|
180
|
-
body: request.body,
|
|
181
|
-
get_url: request.get_url ?? null,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
let featureCollection;
|
|
185
|
-
try {
|
|
186
|
-
logger.info(`[gpf_wfs_get_features] POST ${request.url}?${new URLSearchParams(request.query).toString()}`);
|
|
187
|
-
featureCollection = await this.fetchFeatureCollection(request);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
191
|
-
if (message.includes(`Illegal property name: ${compiled.geometryProperty.name}`)) {
|
|
192
|
-
throw new Error(`Le champ géométrique '${compiled.geometryProperty.name}' issu du catalogue embarqué est rejeté par le WFS live pour '${input.typename}'. Le catalogue embarqué est probablement désynchronisé. Détail : ${message}`);
|
|
193
|
-
}
|
|
194
|
-
throw error;
|
|
195
|
-
}
|
|
196
|
-
if (input.result_type === "hits") {
|
|
197
|
-
return {
|
|
198
|
-
result_type: "hits",
|
|
199
|
-
totalFeatures: this.getMatchedFeatureCount(featureCollection),
|
|
200
|
-
};
|
|
86
|
+
const { request } = await prepareGetFeaturesRequest(input);
|
|
87
|
+
return toWfsRequestPayload(request);
|
|
201
88
|
}
|
|
202
|
-
return
|
|
89
|
+
return executeGetFeatures(input);
|
|
203
90
|
}
|
|
204
91
|
}
|
|
205
92
|
export default GpfWfsGetFeaturesTool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GpfWfsGetFeaturesTool.js","sourceRoot":"","sources":["../../src/tools/GpfWfsGetFeaturesTool.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"GpfWfsGetFeaturesTool.js","sourceRoot":"","sources":["../../src/tools/GpfWfsGetFeaturesTool.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,qCAAqC,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EACL,iCAAiC,EACjC,4BAA4B,EAE5B,qCAAqC,EACrC,oCAAoC,GACrC,MAAM,iCAAiC,CAAC;AACzC,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC;;;;;GAKG;AAEH,eAAe;AAEf,MAAM,qBAAsB,SAAQ,QAAgC;IAClE,IAAI,GAAG,sBAAsB,CAAC;IAC9B,KAAK,GAAG,sBAAsB,CAAC;IAC/B,WAAW,GAAG,qCAAqC,CAAC;IACpD,WAAW,GAAG;QACZ,8GAA8G;QAC9G,+SAA+S;QAC/S,oGAAoG;QACpG,oHAAoH;QACpH,mHAAmH;QACnH,kHAAkH;QAClH,4JAA4J;QAC5J,qJAAqJ;QACrJ,kLAAkL;QAClL,iTAAiT;KAClT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,sEAAsE;IACtE,wDAAwD;IACxD,MAAM,GAAG,4BAA4B,CAAC;IAEtC;;;;OAIG;IACH,IAAI,WAAW;QACb,OAAO,qCAAqC,CAAC;IAC/C,CAAC;IAED;;;;;;OAMG;IACO,qBAAqB,CAAC,IAAa;QAC3C,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,aAAa,IAAI,IAAI;YACrB,IAAI,CAAC,WAAW,KAAK,MAAM;YAC3B,eAAe,IAAI,IAAI;YACvB,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,EACtC,CAAC;YACD,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE9D,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnE,iBAAiB,EAAE,OAAO;aAC3B,CAAC;QACJ,CAAC;QAED,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,aAAa,IAAI,IAAI;YACrB,IAAI,CAAC,WAAW,KAAK,SAAS,EAC9B,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChE,iBAAiB,EAAE,oCAAoC,CAAC,KAAK,CAAC,IAAI,CAAC;aACpE,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,KAA6B;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,IAAI,MAAM,EAAE;YAC7C,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,yBAAyB,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;CACF;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool exposing keyword-based search over the embedded WFS type catalog.
|
|
3
|
+
*/
|
|
4
|
+
import BaseTool from "./BaseTool.js";
|
|
2
5
|
import { z } from "zod";
|
|
3
6
|
declare const gpfWfsSearchTypesInputSchema: z.ZodObject<{
|
|
4
7
|
query: z.ZodString;
|
|
5
8
|
max_results: z.ZodOptional<z.ZodNumber>;
|
|
6
9
|
}, "strict", z.ZodTypeAny, {
|
|
7
|
-
query
|
|
8
|
-
max_results?: number;
|
|
10
|
+
query: string;
|
|
11
|
+
max_results?: number | undefined;
|
|
9
12
|
}, {
|
|
10
|
-
query
|
|
11
|
-
max_results?: number;
|
|
13
|
+
query: string;
|
|
14
|
+
max_results?: number | undefined;
|
|
12
15
|
}>;
|
|
13
16
|
type GpfWfsSearchTypesInput = z.infer<typeof gpfWfsSearchTypesInputSchema>;
|
|
14
|
-
declare class GpfWfsSearchTypesTool extends
|
|
17
|
+
declare class GpfWfsSearchTypesTool extends BaseTool<GpfWfsSearchTypesInput> {
|
|
15
18
|
name: string;
|
|
16
19
|
title: string;
|
|
17
20
|
annotations: {
|
|
@@ -28,47 +31,53 @@ declare class GpfWfsSearchTypesTool extends MCPTool<GpfWfsSearchTypesInput> {
|
|
|
28
31
|
description: z.ZodString;
|
|
29
32
|
score: z.ZodOptional<z.ZodNumber>;
|
|
30
33
|
}, "strip", z.ZodTypeAny, {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
score?: number;
|
|
34
|
+
title: string;
|
|
35
|
+
description: string;
|
|
36
|
+
id: string;
|
|
37
|
+
score?: number | undefined;
|
|
35
38
|
}, {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
score?: number;
|
|
39
|
+
title: string;
|
|
40
|
+
description: string;
|
|
41
|
+
id: string;
|
|
42
|
+
score?: number | undefined;
|
|
40
43
|
}>, "many">;
|
|
41
44
|
}, "strip", z.ZodTypeAny, {
|
|
42
|
-
results
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
score?: number;
|
|
45
|
+
results: {
|
|
46
|
+
title: string;
|
|
47
|
+
description: string;
|
|
48
|
+
id: string;
|
|
49
|
+
score?: number | undefined;
|
|
47
50
|
}[];
|
|
48
51
|
}, {
|
|
49
|
-
results
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
score?: number;
|
|
52
|
+
results: {
|
|
53
|
+
title: string;
|
|
54
|
+
description: string;
|
|
55
|
+
id: string;
|
|
56
|
+
score?: number | undefined;
|
|
54
57
|
}[];
|
|
55
58
|
}>;
|
|
56
59
|
schema: z.ZodObject<{
|
|
57
60
|
query: z.ZodString;
|
|
58
61
|
max_results: z.ZodOptional<z.ZodNumber>;
|
|
59
62
|
}, "strict", z.ZodTypeAny, {
|
|
60
|
-
query
|
|
61
|
-
max_results?: number;
|
|
63
|
+
query: string;
|
|
64
|
+
max_results?: number | undefined;
|
|
62
65
|
}, {
|
|
63
|
-
query
|
|
64
|
-
max_results?: number;
|
|
66
|
+
query: string;
|
|
67
|
+
max_results?: number | undefined;
|
|
65
68
|
}>;
|
|
69
|
+
/**
|
|
70
|
+
* Searches the embedded WFS type catalog from a free-text query.
|
|
71
|
+
*
|
|
72
|
+
* @param input Normalized tool input.
|
|
73
|
+
* @returns The ordered search results, optionally enriched with relevance scores.
|
|
74
|
+
*/
|
|
66
75
|
execute(input: GpfWfsSearchTypesInput): Promise<{
|
|
67
76
|
results: {
|
|
68
|
-
score?:
|
|
69
|
-
id:
|
|
70
|
-
title:
|
|
71
|
-
description:
|
|
77
|
+
score?: any;
|
|
78
|
+
id: any;
|
|
79
|
+
title: any;
|
|
80
|
+
description: any;
|
|
72
81
|
}[];
|
|
73
82
|
}>;
|
|
74
83
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool exposing keyword-based search over the embedded WFS type catalog.
|
|
3
|
+
*/
|
|
4
|
+
import BaseTool from "./BaseTool.js";
|
|
2
5
|
import { z } from "zod";
|
|
3
6
|
import { READ_ONLY_OPEN_WORLD_TOOL_ANNOTATIONS } from "../helpers/toolAnnotations.js";
|
|
4
|
-
import { wfsClient } from "../gpf/wfs.js";
|
|
7
|
+
import { wfsClient } from "../gpf/wfs-schema-catalog.js";
|
|
8
|
+
import logger from "../logger.js";
|
|
9
|
+
// --- Schema ---
|
|
5
10
|
const gpfWfsSearchTypesInputSchema = z.object({
|
|
6
11
|
query: z
|
|
7
12
|
.string()
|
|
@@ -25,7 +30,8 @@ const gpfWfsSearchTypeResultSchema = z.object({
|
|
|
25
30
|
const gpfWfsSearchTypesOutputSchema = z.object({
|
|
26
31
|
results: z.array(gpfWfsSearchTypeResultSchema).describe("La liste ordonnée des types WFS trouvés."),
|
|
27
32
|
});
|
|
28
|
-
|
|
33
|
+
// --- Tool ---
|
|
34
|
+
class GpfWfsSearchTypesTool extends BaseTool {
|
|
29
35
|
name = "gpf_wfs_search_types";
|
|
30
36
|
title = "Recherche de types WFS";
|
|
31
37
|
annotations = READ_ONLY_OPEN_WORLD_TOOL_ANNOTATIONS;
|
|
@@ -38,7 +44,16 @@ class GpfWfsSearchTypesTool extends MCPTool {
|
|
|
38
44
|
].join("\n");
|
|
39
45
|
outputSchemaShape = gpfWfsSearchTypesOutputSchema;
|
|
40
46
|
schema = gpfWfsSearchTypesInputSchema;
|
|
47
|
+
/**
|
|
48
|
+
* Searches the embedded WFS type catalog from a free-text query.
|
|
49
|
+
*
|
|
50
|
+
* @param input Normalized tool input.
|
|
51
|
+
* @returns The ordered search results, optionally enriched with relevance scores.
|
|
52
|
+
*/
|
|
41
53
|
async execute(input) {
|
|
54
|
+
logger.info(`[tool] execute ${this.name} ...`, {
|
|
55
|
+
input: input
|
|
56
|
+
});
|
|
42
57
|
const maxResults = input.max_results || 10;
|
|
43
58
|
const featureTypes = await wfsClient.searchFeatureTypesWithScores(input.query, maxResults);
|
|
44
59
|
return {
|