@assetlab/mcp-server 1.28.0 → 2.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.
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/tools-write.js +84 -27
- package/dist/tools-write.js.map +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +50 -20
- package/dist/tools.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/dist/worker.js +2 -1
- package/dist/worker.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -13,12 +13,13 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
13
13
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
14
|
import { AssetLabClient, loadConfig } from './client.js';
|
|
15
15
|
import { registerTools, SERVER_INSTRUCTIONS } from './tools.js';
|
|
16
|
+
import { VERSION } from './version.js';
|
|
16
17
|
async function main() {
|
|
17
18
|
const config = loadConfig();
|
|
18
19
|
const client = new AssetLabClient(config);
|
|
19
20
|
const server = new McpServer({
|
|
20
21
|
name: 'assetlab',
|
|
21
|
-
version:
|
|
22
|
+
version: VERSION,
|
|
22
23
|
}, {
|
|
23
24
|
instructions: SERVER_INSTRUCTIONS,
|
|
24
25
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;IAEzC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE,mBAAmB;KAClC,CACF,CAAA;IAED,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE7B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAA;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
package/dist/tools-write.js
CHANGED
|
@@ -128,6 +128,7 @@ export function registerWriteTools(server, client) {
|
|
|
128
128
|
location_ids: ASSOCIATION_ARRAY_SCHEMA('Locations this work order covers — use instead of location_id when there is more than one. Sending location_id alone replaces this with that single id.'),
|
|
129
129
|
asset_ids: ASSOCIATION_ARRAY_SCHEMA('Assets this work order covers — use instead of asset_id when there is more than one.'),
|
|
130
130
|
system_ids: ASSOCIATION_ARRAY_SCHEMA('Systems this work order covers — resolve via list_systems. Systems have no singular field; this array is the only way to associate them.'),
|
|
131
|
+
infrastructure_asset_ids: ASSOCIATION_ARRAY_SCHEMA('Infrastructure features this work order covers — resolve via list_infrastructure_assets. Use this when one job covers several features (a round of hydrant flushing); the whole selection is one work order with one completion and one cost, split across the features. Mutually exclusive with asset/location/system targets.'),
|
|
131
132
|
start_date: z.string().optional().describe('Start date (ISO 8601)'),
|
|
132
133
|
due_date: z.string().optional().describe('Due date (ISO 8601)'),
|
|
133
134
|
estimated_time: z.number().min(0).optional().describe('Estimated time in hours'),
|
|
@@ -142,7 +143,7 @@ export function registerWriteTools(server, client) {
|
|
|
142
143
|
.string()
|
|
143
144
|
.max(2000)
|
|
144
145
|
.optional()
|
|
145
|
-
.describe('Image
|
|
146
|
+
.describe('Image storage path (upload via create_upload_url with bucket "attachments", then set this to the returned path)'),
|
|
146
147
|
meter_reading: z
|
|
147
148
|
.number()
|
|
148
149
|
.min(0)
|
|
@@ -187,6 +188,7 @@ export function registerWriteTools(server, client) {
|
|
|
187
188
|
location_ids: ASSOCIATION_ARRAY_SCHEMA('Locations this work order covers — use instead of location_id when there is more than one. Sending location_id alone replaces this with that single id.'),
|
|
188
189
|
asset_ids: ASSOCIATION_ARRAY_SCHEMA('Assets this work order covers — use instead of asset_id when there is more than one.'),
|
|
189
190
|
system_ids: ASSOCIATION_ARRAY_SCHEMA('Systems this work order covers — resolve via list_systems. Systems have no singular field; this array is the only way to associate them.'),
|
|
191
|
+
infrastructure_asset_ids: ASSOCIATION_ARRAY_SCHEMA('Infrastructure features this work order covers — resolve via list_infrastructure_assets. Use this when one job covers several features (a round of hydrant flushing); the whole selection is one work order with one completion and one cost, split across the features. Mutually exclusive with asset/location/system targets.'),
|
|
190
192
|
start_date: z.string().optional().describe('Start date (ISO 8601)'),
|
|
191
193
|
due_date: z.string().optional().describe('Due date (ISO 8601)'),
|
|
192
194
|
estimated_time: z.number().min(0).optional().describe('Estimated time in hours'),
|
|
@@ -201,7 +203,7 @@ export function registerWriteTools(server, client) {
|
|
|
201
203
|
.string()
|
|
202
204
|
.max(2000)
|
|
203
205
|
.optional()
|
|
204
|
-
.describe('Image
|
|
206
|
+
.describe('Image storage path (upload via create_upload_url with bucket "attachments", then set this to the returned path)'),
|
|
205
207
|
meter_reading: z
|
|
206
208
|
.number()
|
|
207
209
|
.min(0)
|
|
@@ -924,6 +926,7 @@ export function registerWriteTools(server, client) {
|
|
|
924
926
|
asset_ids: ASSOCIATION_ARRAY_SCHEMA('Assets this schedule covers — use instead of asset_id when there is more than one.'),
|
|
925
927
|
system_ids: ASSOCIATION_ARRAY_SCHEMA('Systems this schedule covers. Systems have no singular field; this array is the only way to associate them.'),
|
|
926
928
|
location_ids: ASSOCIATION_ARRAY_SCHEMA('Locations this schedule covers — use instead of location_id when there is more than one. Sending location_id alone replaces this with that single id.'),
|
|
929
|
+
infrastructure_asset_ids: ASSOCIATION_ARRAY_SCHEMA('Infrastructure features this schedule covers — resolve via list_infrastructure_assets. One schedule over several features generates one work order per cycle covering all of them. Mutually exclusive with asset/location/system targets.'),
|
|
927
930
|
tasks: z
|
|
928
931
|
.array(z.object({
|
|
929
932
|
id: z.string().describe('Unique task ID (use a random string)'),
|
|
@@ -999,6 +1002,7 @@ export function registerWriteTools(server, client) {
|
|
|
999
1002
|
asset_ids: ASSOCIATION_ARRAY_SCHEMA('Assets this schedule covers — use instead of asset_id when there is more than one.'),
|
|
1000
1003
|
system_ids: ASSOCIATION_ARRAY_SCHEMA('Systems this schedule covers. Systems have no singular field; this array is the only way to associate them.'),
|
|
1001
1004
|
location_ids: ASSOCIATION_ARRAY_SCHEMA('Locations this schedule covers — use instead of location_id when there is more than one. Sending location_id alone replaces this with that single id.'),
|
|
1005
|
+
infrastructure_asset_ids: ASSOCIATION_ARRAY_SCHEMA('Infrastructure features this schedule covers — resolve via list_infrastructure_assets. One schedule over several features generates one work order per cycle covering all of them. Mutually exclusive with asset/location/system targets.'),
|
|
1002
1006
|
tasks: z
|
|
1003
1007
|
.array(z.object({
|
|
1004
1008
|
id: z.string().describe('Unique task ID'),
|
|
@@ -1918,6 +1922,56 @@ export function registerWriteTools(server, client) {
|
|
|
1918
1922
|
}
|
|
1919
1923
|
});
|
|
1920
1924
|
// ============================================================
|
|
1925
|
+
// 16b. Work Order Schedules (scope: work_order_schedules)
|
|
1926
|
+
// ============================================================
|
|
1927
|
+
server.tool('create_work_order_schedule', "Schedule a work order for a technician on a date (one entry of a day plan). stop_order gives the position in the technician's day; leave it unset for an unordered calendar entry. Requires work_order_schedules:write scope.", {
|
|
1928
|
+
work_order_id: z.string().uuid().describe('Work order ID (required)'),
|
|
1929
|
+
technician_id: z.string().min(1).describe('Technician Clerk user ID (required)'),
|
|
1930
|
+
scheduled_date: z.string().describe('Date (YYYY-MM-DD, required)'),
|
|
1931
|
+
scheduled_start_time: z.string().optional().describe('Start time (HH:MM)'),
|
|
1932
|
+
scheduled_end_time: z.string().optional().describe('End time (HH:MM)'),
|
|
1933
|
+
duration_minutes: z.number().int().optional().describe('Planned duration in minutes'),
|
|
1934
|
+
stop_order: z.number().int().optional().describe('1-based stop position in the day plan'),
|
|
1935
|
+
travel_time_minutes: z.number().int().optional().describe('Travel time from previous stop'),
|
|
1936
|
+
scheduling_notes: z.string().optional().describe('Scheduling notes'),
|
|
1937
|
+
}, async (params) => {
|
|
1938
|
+
try {
|
|
1939
|
+
const result = await client.create('work-order-schedules', buildBody(params));
|
|
1940
|
+
return formatResult(result);
|
|
1941
|
+
}
|
|
1942
|
+
catch (err) {
|
|
1943
|
+
return formatError(err);
|
|
1944
|
+
}
|
|
1945
|
+
});
|
|
1946
|
+
server.tool('update_work_order_schedule', 'Update a work order schedule entry by ID (date, times, stop_order, notes). work_order_id is immutable. Requires work_order_schedules:write scope.', {
|
|
1947
|
+
id: z.string().uuid().describe('Work order schedule ID'),
|
|
1948
|
+
technician_id: z.string().min(1).optional().describe('Technician Clerk user ID'),
|
|
1949
|
+
scheduled_date: z.string().optional().describe('Date (YYYY-MM-DD)'),
|
|
1950
|
+
scheduled_start_time: z.string().optional().describe('Start time (HH:MM)'),
|
|
1951
|
+
scheduled_end_time: z.string().optional().describe('End time (HH:MM)'),
|
|
1952
|
+
duration_minutes: z.number().int().optional().describe('Planned duration in minutes'),
|
|
1953
|
+
stop_order: z.number().int().optional().describe('1-based stop position in the day plan'),
|
|
1954
|
+
travel_time_minutes: z.number().int().optional().describe('Travel time from previous stop'),
|
|
1955
|
+
scheduling_notes: z.string().optional().describe('Scheduling notes'),
|
|
1956
|
+
}, async ({ id, ...rest }) => {
|
|
1957
|
+
try {
|
|
1958
|
+
const result = await client.update('work-order-schedules', id, buildBody(rest));
|
|
1959
|
+
return formatResult(result);
|
|
1960
|
+
}
|
|
1961
|
+
catch (err) {
|
|
1962
|
+
return formatError(err);
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1965
|
+
server.tool('delete_work_order_schedule', "Delete a work order schedule entry by ID (removes the stop from the technician's day). Requires work_order_schedules:write scope.", { id: z.string().uuid().describe('Work order schedule ID') }, async ({ id }) => {
|
|
1966
|
+
try {
|
|
1967
|
+
const result = await client.remove('work-order-schedules', id);
|
|
1968
|
+
return formatResult(result);
|
|
1969
|
+
}
|
|
1970
|
+
catch (err) {
|
|
1971
|
+
return formatError(err);
|
|
1972
|
+
}
|
|
1973
|
+
});
|
|
1974
|
+
// ============================================================
|
|
1921
1975
|
// 17. Project Comments (scope: project_comments)
|
|
1922
1976
|
// ============================================================
|
|
1923
1977
|
server.tool('create_project_comment', 'Create a new comment on a project. Requires project_comments:write scope.', {
|
|
@@ -2315,9 +2369,10 @@ export function registerWriteTools(server, client) {
|
|
|
2315
2369
|
user_id: z.string().min(1).describe('User ID (required)'),
|
|
2316
2370
|
start_time: z.string().describe('Start time (ISO 8601 datetime, required)'),
|
|
2317
2371
|
end_time: z.string().optional().describe('End time (ISO 8601 datetime)'),
|
|
2318
|
-
|
|
2372
|
+
duration_minutes: z.number().min(0).optional().describe('Duration worked, in minutes'),
|
|
2319
2373
|
description: z.string().optional().describe('Description'),
|
|
2320
|
-
|
|
2374
|
+
user_name: z.string().max(200).optional().describe('Display name of the user'),
|
|
2375
|
+
is_billable: z.boolean().optional().describe('Whether the time is billable'),
|
|
2321
2376
|
}, async (params) => {
|
|
2322
2377
|
try {
|
|
2323
2378
|
const result = await client.create('project-time-entries', buildBody(params));
|
|
@@ -2334,9 +2389,10 @@ export function registerWriteTools(server, client) {
|
|
|
2334
2389
|
user_id: z.string().optional().describe('User ID'),
|
|
2335
2390
|
start_time: z.string().optional().describe('Start time (ISO 8601 datetime)'),
|
|
2336
2391
|
end_time: z.string().optional().describe('End time (ISO 8601 datetime)'),
|
|
2337
|
-
|
|
2392
|
+
duration_minutes: z.number().min(0).optional().describe('Duration worked, in minutes'),
|
|
2338
2393
|
description: z.string().optional().describe('Description'),
|
|
2339
|
-
|
|
2394
|
+
user_name: z.string().max(200).optional().describe('Display name of the user'),
|
|
2395
|
+
is_billable: z.boolean().optional().describe('Whether the time is billable'),
|
|
2340
2396
|
}, async ({ id, ...rest }) => {
|
|
2341
2397
|
try {
|
|
2342
2398
|
const result = await client.update('project-time-entries', id, buildBody(rest));
|
|
@@ -3149,7 +3205,7 @@ export function registerWriteTools(server, client) {
|
|
|
3149
3205
|
// ============================================================
|
|
3150
3206
|
// Upload URLs
|
|
3151
3207
|
// ============================================================
|
|
3152
|
-
server.tool('create_upload_url', 'Generate a signed upload URL for uploading a file to AssetLab storage. Returns a signed_url to PUT the file to,
|
|
3208
|
+
server.tool('create_upload_url', 'Generate a signed upload URL for uploading a file to AssetLab storage. Returns a signed_url to PUT the file to, and the storage path to store on the record. IMPORTANT — When a user wants to upload a file, always clarify the target. File upload paths: (1) Asset IMAGE: bucket "asset-images" → update_asset with image_url. (2) Asset DOCUMENT (O&M, warranty, spec): bucket "documents" → create_asset_document. (3) Work order IMAGE: bucket "attachments" → update_work_order with image_url. (4) Work order/request/PM ATTACHMENT: bucket "attachments" → create_attachment with the parent ID. (5) Project DOCUMENT: bucket "project-documents" → create_project_document. (6) Contract DOCUMENT: bucket "contract-documents" → create_contract_document. Always ask the user which type they mean if ambiguous. Requires upload_urls:write scope.', {
|
|
3153
3209
|
bucket: z
|
|
3154
3210
|
.enum([
|
|
3155
3211
|
'documents',
|
|
@@ -3169,7 +3225,7 @@ export function registerWriteTools(server, client) {
|
|
|
3169
3225
|
return formatError(err);
|
|
3170
3226
|
}
|
|
3171
3227
|
});
|
|
3172
|
-
server.tool('upload_file', 'Upload a file to AssetLab storage by sending its bytes inline (base64). The AssetLab backend performs the storage upload server-side — use this tool when the client cannot PUT directly to Supabase Storage (e.g. Claude integrations whose outbound network blocks arbitrary supabase.co hosts). Returns { path,
|
|
3228
|
+
server.tool('upload_file', 'Upload a file to AssetLab storage by sending its bytes inline (base64). The AssetLab backend performs the storage upload server-side — use this tool when the client cannot PUT directly to Supabase Storage (e.g. Claude integrations whose outbound network blocks arbitrary supabase.co hosts). Returns { path, bucket, file_size, content_type }. After uploading, pass path to the appropriate record tool (update_asset image_url, create_asset_document file_path, update_work_order image_url, create_attachment file_path, create_project_document file_path, create_contract_document file_path). Server limit is ~10 MB decoded; MCP arg ceiling effectively caps file size around 700 KB–1 MB. For larger files, use create_upload_url instead. Requires upload_urls:write scope.', {
|
|
3173
3229
|
bucket: z
|
|
3174
3230
|
.enum([
|
|
3175
3231
|
'documents',
|
|
@@ -4577,44 +4633,45 @@ export function registerWriteTools(server, client) {
|
|
|
4577
4633
|
}
|
|
4578
4634
|
});
|
|
4579
4635
|
// ============================================================
|
|
4580
|
-
// Infrastructure
|
|
4636
|
+
// Infrastructure Feature Classes (scope: infrastructure_feature_classes)
|
|
4581
4637
|
// ============================================================
|
|
4582
4638
|
const INFRA_ASSET_CLASS_CATEGORIES = [
|
|
4583
|
-
'
|
|
4584
|
-
'sewer',
|
|
4639
|
+
'transportation',
|
|
4585
4640
|
'water',
|
|
4586
|
-
'
|
|
4641
|
+
'wastewater',
|
|
4642
|
+
'stormwater',
|
|
4643
|
+
'structures',
|
|
4587
4644
|
'electrical',
|
|
4588
4645
|
'telecom',
|
|
4589
|
-
'
|
|
4590
|
-
'
|
|
4646
|
+
'gas',
|
|
4647
|
+
'roadside',
|
|
4591
4648
|
'other',
|
|
4592
4649
|
];
|
|
4593
|
-
const
|
|
4650
|
+
const featureClassCode = z
|
|
4594
4651
|
.string()
|
|
4595
4652
|
.regex(/^[a-z][a-z0-9_]{0,49}$/)
|
|
4596
4653
|
.describe('Asset class code (lowercase snake_case, 1-50 chars)');
|
|
4597
|
-
server.tool('
|
|
4598
|
-
code:
|
|
4654
|
+
server.tool('create_infrastructure_feature_class', 'Create a tenant-defined infrastructure feature class. Builtin classes are managed by AssetLab and cannot be created via API (is_builtin is always forced to false). Requires infrastructure_feature_classes:write scope.', {
|
|
4655
|
+
code: featureClassCode,
|
|
4599
4656
|
name: z.string().max(200).describe('Display name (required)'),
|
|
4600
4657
|
category: z
|
|
4601
4658
|
.enum(INFRA_ASSET_CLASS_CATEGORIES)
|
|
4602
|
-
.describe('Category (
|
|
4659
|
+
.describe('Category — municipal service family (transportation, water, wastewater, stormwater, structures, electrical, telecom, gas, roadside, other)'),
|
|
4603
4660
|
description: z.string().optional().describe('Description'),
|
|
4604
4661
|
icon: z.string().max(50).optional().describe('Icon name'),
|
|
4605
4662
|
color: z.string().max(20).optional().describe('Display color (CSS color or hex)'),
|
|
4606
4663
|
sort_order: z.number().int().optional().describe('Sort order'),
|
|
4607
4664
|
}, async (params) => {
|
|
4608
4665
|
try {
|
|
4609
|
-
const result = await client.create('infrastructure-
|
|
4666
|
+
const result = await client.create('infrastructure-feature-classes', buildBody(params));
|
|
4610
4667
|
return formatResult(result);
|
|
4611
4668
|
}
|
|
4612
4669
|
catch (err) {
|
|
4613
4670
|
return formatError(err);
|
|
4614
4671
|
}
|
|
4615
4672
|
});
|
|
4616
|
-
server.tool('
|
|
4617
|
-
code:
|
|
4673
|
+
server.tool('update_infrastructure_feature_class', 'Update a tenant-defined infrastructure feature class (addressed by code). The `code`, `category`, and `is_builtin` fields are immutable; attempts to change them on a builtin class return 409. Requires infrastructure_feature_classes:write scope.', {
|
|
4674
|
+
code: featureClassCode,
|
|
4618
4675
|
name: z.string().max(200).optional().describe('Display name'),
|
|
4619
4676
|
description: z.string().optional().describe('Description'),
|
|
4620
4677
|
icon: z.string().max(50).optional().describe('Icon name'),
|
|
@@ -4622,16 +4679,16 @@ export function registerWriteTools(server, client) {
|
|
|
4622
4679
|
sort_order: z.number().int().optional().describe('Sort order'),
|
|
4623
4680
|
}, async ({ code, ...rest }) => {
|
|
4624
4681
|
try {
|
|
4625
|
-
const result = await client.update('infrastructure-
|
|
4682
|
+
const result = await client.update('infrastructure-feature-classes', code, buildBody(rest));
|
|
4626
4683
|
return formatResult(result);
|
|
4627
4684
|
}
|
|
4628
4685
|
catch (err) {
|
|
4629
4686
|
return formatError(err);
|
|
4630
4687
|
}
|
|
4631
4688
|
});
|
|
4632
|
-
server.tool('
|
|
4689
|
+
server.tool('delete_infrastructure_feature_class', 'Delete a tenant-defined infrastructure feature class by code. Builtin classes cannot be deleted. Classes referenced by any infrastructure network are protected by FK and cannot be deleted until those networks are reassigned. Requires infrastructure_feature_classes:write scope.', { code: featureClassCode }, async ({ code }) => {
|
|
4633
4690
|
try {
|
|
4634
|
-
const result = await client.remove('infrastructure-
|
|
4691
|
+
const result = await client.remove('infrastructure-feature-classes', code);
|
|
4635
4692
|
return formatResult(result);
|
|
4636
4693
|
}
|
|
4637
4694
|
catch (err) {
|
|
@@ -4641,9 +4698,9 @@ export function registerWriteTools(server, client) {
|
|
|
4641
4698
|
// ============================================================
|
|
4642
4699
|
// Infrastructure Networks (scope: infrastructure_networks)
|
|
4643
4700
|
// ============================================================
|
|
4644
|
-
server.tool('create_infrastructure_network', 'Create an infrastructure network — a named grouping of features bound to one
|
|
4701
|
+
server.tool('create_infrastructure_network', 'Create an infrastructure network — a named grouping of features bound to one feature class. Requires infrastructure_networks:write scope.', {
|
|
4645
4702
|
name: z.string().max(200).describe('Network name (required)'),
|
|
4646
|
-
|
|
4703
|
+
feature_class: featureClassCode.describe('Asset class code (must exist; resolve via list_infrastructure_feature_classes)'),
|
|
4647
4704
|
description: z.string().optional().describe('Description'),
|
|
4648
4705
|
color_scheme: z.string().max(50).optional().describe('Display color scheme'),
|
|
4649
4706
|
metadata: z.record(z.unknown()).optional().describe('Free-form JSON metadata'),
|
|
@@ -4659,7 +4716,7 @@ export function registerWriteTools(server, client) {
|
|
|
4659
4716
|
server.tool('update_infrastructure_network', 'Update an existing infrastructure network by ID. Requires infrastructure_networks:write scope.', {
|
|
4660
4717
|
id: z.string().uuid().describe('Infrastructure network ID'),
|
|
4661
4718
|
name: z.string().max(200).optional().describe('Network name'),
|
|
4662
|
-
|
|
4719
|
+
feature_class: featureClassCode.optional().describe('Asset class code'),
|
|
4663
4720
|
description: z.string().optional().describe('Description'),
|
|
4664
4721
|
color_scheme: z.string().max(50).optional().describe('Display color scheme'),
|
|
4665
4722
|
metadata: z.record(z.unknown()).optional().describe('Free-form JSON metadata'),
|