@burdenoff/mcp-libs 2026.627.4 → 2026.627.5
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/modules/mybodyshield/index.cjs +1834 -0
- package/dist/modules/mybodyshield/index.cjs.map +1 -0
- package/dist/modules/mybodyshield/index.d.cts +8 -0
- package/dist/modules/mybodyshield/index.d.ts +8 -0
- package/dist/modules/mybodyshield/index.js +1773 -0
- package/dist/modules/mybodyshield/index.js.map +1 -0
- package/dist/modules/semanticfed/index.cjs +1846 -0
- package/dist/modules/semanticfed/index.cjs.map +1 -0
- package/dist/modules/semanticfed/index.d.cts +8 -0
- package/dist/modules/semanticfed/index.d.ts +8 -0
- package/dist/modules/semanticfed/index.js +1785 -0
- package/dist/modules/semanticfed/index.js.map +1 -0
- package/dist/modules/technospam/index.cjs +1962 -0
- package/dist/modules/technospam/index.cjs.map +1 -0
- package/dist/modules/technospam/index.d.cts +8 -0
- package/dist/modules/technospam/index.d.ts +8 -0
- package/dist/modules/technospam/index.js +1901 -0
- package/dist/modules/technospam/index.js.map +1 -0
- package/dist/modules/theculturepost/index.cjs +1587 -0
- package/dist/modules/theculturepost/index.cjs.map +1 -0
- package/dist/modules/theculturepost/index.d.cts +8 -0
- package/dist/modules/theculturepost/index.d.ts +8 -0
- package/dist/modules/theculturepost/index.js +1526 -0
- package/dist/modules/theculturepost/index.js.map +1 -0
- package/dist/modules/theglobalfuel/index.cjs +1678 -0
- package/dist/modules/theglobalfuel/index.cjs.map +1 -0
- package/dist/modules/theglobalfuel/index.d.cts +8 -0
- package/dist/modules/theglobalfuel/index.d.ts +8 -0
- package/dist/modules/theglobalfuel/index.js +1617 -0
- package/dist/modules/theglobalfuel/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1617 @@
|
|
|
1
|
+
import { mcpToolName, errorResult, jsonResult, mcpResourceUri, mcpPromptName } from '../../chunk-H2OYWLOA.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// src/modules/theglobalfuel/operations.ts
|
|
5
|
+
var ASSET_FIELDS = `
|
|
6
|
+
id name code commodity kind status capacityPerDay capacityUnit
|
|
7
|
+
workingInterestPct operatorLeadId location latitude longitude
|
|
8
|
+
commissionedAt decommissionedAt tags workspaceId createdAt updatedAt
|
|
9
|
+
`;
|
|
10
|
+
var PRODUCTION_FIELDS = `
|
|
11
|
+
id assetId periodStart periodEnd volume unit grade downtimeHours notes
|
|
12
|
+
workspaceId createdAt updatedAt
|
|
13
|
+
`;
|
|
14
|
+
var RESERVE_FIELDS = `
|
|
15
|
+
id assetId category recoverable recoveryFactor unit methodology asOfDate
|
|
16
|
+
notes workspaceId createdAt updatedAt
|
|
17
|
+
`;
|
|
18
|
+
var CONTRACT_FIELDS = `
|
|
19
|
+
id reference counterparty side commodity status contractedVolume
|
|
20
|
+
deliveredVolume unit pricePerUnit currency priceIndex pricingBasis
|
|
21
|
+
deliveryLocation startDate endDate signedAt notes tags workspaceId
|
|
22
|
+
createdAt updatedAt
|
|
23
|
+
`;
|
|
24
|
+
var SHIPMENT_FIELDS = `
|
|
25
|
+
id contractId reference status mode volume unit origin destination carrier
|
|
26
|
+
scheduledAt departedAt deliveredAt notes document { id } workspaceId
|
|
27
|
+
createdAt updatedAt
|
|
28
|
+
`;
|
|
29
|
+
var INVENTORY_FIELDS = `
|
|
30
|
+
id lotCode commodity status quantity unit grade unitValue currency
|
|
31
|
+
location assetId producedAt notes workspaceId createdAt updatedAt
|
|
32
|
+
`;
|
|
33
|
+
var EMISSION_FIELDS = `
|
|
34
|
+
id assetId scope co2eTonnes periodStart periodEnd source methodology
|
|
35
|
+
verified verifiedAt notes workspaceId createdAt updatedAt
|
|
36
|
+
`;
|
|
37
|
+
var COMPLIANCE_FIELDS = `
|
|
38
|
+
id title category status authority certNumber assetId ownerId issuedAt
|
|
39
|
+
expiresAt notes tags evidence { id } workspaceId createdAt updatedAt
|
|
40
|
+
`;
|
|
41
|
+
var PAGE_INFO_FIELDS = `
|
|
42
|
+
pageInfo { cursor hasMore }
|
|
43
|
+
`;
|
|
44
|
+
var GET_ASSET = `
|
|
45
|
+
query TheglobalfuelGetAsset($id: ID!) {
|
|
46
|
+
theAsset(id: $id) {
|
|
47
|
+
${ASSET_FIELDS}
|
|
48
|
+
productionRecords { id periodStart periodEnd volume unit }
|
|
49
|
+
reserveEstimates { id category recoverable unit asOfDate }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
var LIST_ASSETS = `
|
|
54
|
+
query TheglobalfuelListAssets(
|
|
55
|
+
$commodity: TheCommodityType
|
|
56
|
+
$kind: TheAssetKind
|
|
57
|
+
$status: TheAssetStatus
|
|
58
|
+
$pagination: PaginationInput
|
|
59
|
+
) {
|
|
60
|
+
theListAssets(
|
|
61
|
+
commodity: $commodity
|
|
62
|
+
kind: $kind
|
|
63
|
+
status: $status
|
|
64
|
+
pagination: $pagination
|
|
65
|
+
) {
|
|
66
|
+
items { ${ASSET_FIELDS} }
|
|
67
|
+
${PAGE_INFO_FIELDS}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
var CREATE_ASSET = `
|
|
72
|
+
mutation TheglobalfuelCreateAsset($input: TheCreateAssetInput!) {
|
|
73
|
+
theCreateAsset(input: $input) {
|
|
74
|
+
${ASSET_FIELDS}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
var UPDATE_ASSET = `
|
|
79
|
+
mutation TheglobalfuelUpdateAsset($id: ID!, $input: TheUpdateAssetInput!) {
|
|
80
|
+
theUpdateAsset(id: $id, input: $input) {
|
|
81
|
+
${ASSET_FIELDS}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
var TRANSITION_ASSET = `
|
|
86
|
+
mutation TheglobalfuelTransitionAsset($id: ID!, $status: TheAssetStatus!) {
|
|
87
|
+
theTransitionAsset(id: $id, status: $status) {
|
|
88
|
+
${ASSET_FIELDS}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
92
|
+
var RETIRE_ASSET = `
|
|
93
|
+
mutation TheglobalfuelRetireAsset($id: ID!) {
|
|
94
|
+
theRetireAsset(id: $id)
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
var LIST_PRODUCTION_RECORDS = `
|
|
98
|
+
query TheglobalfuelListProductionRecords($assetId: ID, $pagination: PaginationInput) {
|
|
99
|
+
theListProductionRecords(assetId: $assetId, pagination: $pagination) {
|
|
100
|
+
items { ${PRODUCTION_FIELDS} }
|
|
101
|
+
${PAGE_INFO_FIELDS}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
var RECORD_PRODUCTION = `
|
|
106
|
+
mutation TheglobalfuelRecordProduction($input: TheRecordProductionInput!) {
|
|
107
|
+
theRecordProduction(input: $input) {
|
|
108
|
+
${PRODUCTION_FIELDS}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
var LIST_RESERVE_ESTIMATES = `
|
|
113
|
+
query TheglobalfuelListReserveEstimates($assetId: ID, $category: TheReserveCategory) {
|
|
114
|
+
theListReserveEstimates(assetId: $assetId, category: $category) {
|
|
115
|
+
${RESERVE_FIELDS}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
var CREATE_RESERVE_ESTIMATE = `
|
|
120
|
+
mutation TheglobalfuelCreateReserveEstimate($input: TheCreateReserveEstimateInput!) {
|
|
121
|
+
theCreateReserveEstimate(input: $input) {
|
|
122
|
+
${RESERVE_FIELDS}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
var GET_CONTRACT = `
|
|
127
|
+
query TheglobalfuelGetContract($id: ID!) {
|
|
128
|
+
theContract(id: $id) {
|
|
129
|
+
${CONTRACT_FIELDS}
|
|
130
|
+
shipments { id reference status volume unit }
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
134
|
+
var LIST_CONTRACTS = `
|
|
135
|
+
query TheglobalfuelListContracts(
|
|
136
|
+
$commodity: TheCommodityType
|
|
137
|
+
$side: TheContractSide
|
|
138
|
+
$status: TheContractStatus
|
|
139
|
+
$pagination: PaginationInput
|
|
140
|
+
) {
|
|
141
|
+
theListContracts(
|
|
142
|
+
commodity: $commodity
|
|
143
|
+
side: $side
|
|
144
|
+
status: $status
|
|
145
|
+
pagination: $pagination
|
|
146
|
+
) {
|
|
147
|
+
items { ${CONTRACT_FIELDS} }
|
|
148
|
+
${PAGE_INFO_FIELDS}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
var CREATE_CONTRACT = `
|
|
153
|
+
mutation TheglobalfuelCreateContract($input: TheCreateOfftakeContractInput!) {
|
|
154
|
+
theCreateContract(input: $input) {
|
|
155
|
+
${CONTRACT_FIELDS}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`;
|
|
159
|
+
var UPDATE_CONTRACT = `
|
|
160
|
+
mutation TheglobalfuelUpdateContract($id: ID!, $input: TheUpdateOfftakeContractInput!) {
|
|
161
|
+
theUpdateContract(id: $id, input: $input) {
|
|
162
|
+
${CONTRACT_FIELDS}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
`;
|
|
166
|
+
var TRANSITION_CONTRACT = `
|
|
167
|
+
mutation TheglobalfuelTransitionContract($id: ID!, $status: TheContractStatus!) {
|
|
168
|
+
theTransitionContract(id: $id, status: $status) {
|
|
169
|
+
${CONTRACT_FIELDS}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
`;
|
|
173
|
+
var LIST_SHIPMENTS = `
|
|
174
|
+
query TheglobalfuelListShipments($contractId: ID, $status: TheShipmentStatus) {
|
|
175
|
+
theListShipments(contractId: $contractId, status: $status) {
|
|
176
|
+
${SHIPMENT_FIELDS}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
var SCHEDULE_SHIPMENT = `
|
|
181
|
+
mutation TheglobalfuelScheduleShipment($input: TheCreateShipmentInput!) {
|
|
182
|
+
theScheduleShipment(input: $input) {
|
|
183
|
+
${SHIPMENT_FIELDS}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
`;
|
|
187
|
+
var DELIVER_SHIPMENT = `
|
|
188
|
+
mutation TheglobalfuelDeliverShipment($id: ID!) {
|
|
189
|
+
theDeliverShipment(id: $id) {
|
|
190
|
+
${SHIPMENT_FIELDS}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
var LIST_INVENTORY_LOTS = `
|
|
195
|
+
query TheglobalfuelListInventoryLots(
|
|
196
|
+
$commodity: TheCommodityType
|
|
197
|
+
$status: TheInventoryStatus
|
|
198
|
+
$pagination: PaginationInput
|
|
199
|
+
) {
|
|
200
|
+
theListInventoryLots(commodity: $commodity, status: $status, pagination: $pagination) {
|
|
201
|
+
items { ${INVENTORY_FIELDS} }
|
|
202
|
+
${PAGE_INFO_FIELDS}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
`;
|
|
206
|
+
var CREATE_INVENTORY_LOT = `
|
|
207
|
+
mutation TheglobalfuelCreateInventoryLot($input: TheCreateInventoryLotInput!) {
|
|
208
|
+
theCreateInventoryLot(input: $input) {
|
|
209
|
+
${INVENTORY_FIELDS}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
`;
|
|
213
|
+
var SET_INVENTORY_LOT_STATUS = `
|
|
214
|
+
mutation TheglobalfuelSetInventoryLotStatus($id: ID!, $status: TheInventoryStatus!) {
|
|
215
|
+
theSetInventoryLotStatus(id: $id, status: $status) {
|
|
216
|
+
${INVENTORY_FIELDS}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
`;
|
|
220
|
+
var LIST_EMISSION_RECORDS = `
|
|
221
|
+
query TheglobalfuelListEmissionRecords(
|
|
222
|
+
$assetId: ID
|
|
223
|
+
$scope: TheEmissionScope
|
|
224
|
+
$pagination: PaginationInput
|
|
225
|
+
) {
|
|
226
|
+
theListEmissionRecords(assetId: $assetId, scope: $scope, pagination: $pagination) {
|
|
227
|
+
items { ${EMISSION_FIELDS} }
|
|
228
|
+
${PAGE_INFO_FIELDS}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
`;
|
|
232
|
+
var RECORD_EMISSION = `
|
|
233
|
+
mutation TheglobalfuelRecordEmission($input: TheRecordEmissionInput!) {
|
|
234
|
+
theRecordEmission(input: $input) {
|
|
235
|
+
${EMISSION_FIELDS}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
`;
|
|
239
|
+
var VERIFY_EMISSION = `
|
|
240
|
+
mutation TheglobalfuelVerifyEmission($id: ID!) {
|
|
241
|
+
theVerifyEmission(id: $id) {
|
|
242
|
+
${EMISSION_FIELDS}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
`;
|
|
246
|
+
var GET_COMPLIANCE_CERT = `
|
|
247
|
+
query TheglobalfuelGetComplianceCert($id: ID!) {
|
|
248
|
+
theComplianceCert(id: $id) {
|
|
249
|
+
${COMPLIANCE_FIELDS}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
var LIST_COMPLIANCE_CERTS = `
|
|
254
|
+
query TheglobalfuelListComplianceCerts(
|
|
255
|
+
$assetId: ID
|
|
256
|
+
$category: TheComplianceCategory
|
|
257
|
+
$status: TheComplianceStatus
|
|
258
|
+
) {
|
|
259
|
+
theListComplianceCerts(assetId: $assetId, category: $category, status: $status) {
|
|
260
|
+
${COMPLIANCE_FIELDS}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
`;
|
|
264
|
+
var CREATE_COMPLIANCE_CERT = `
|
|
265
|
+
mutation TheglobalfuelCreateComplianceCert($input: TheCreateComplianceCertInput!) {
|
|
266
|
+
theCreateComplianceCert(input: $input) {
|
|
267
|
+
${COMPLIANCE_FIELDS}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
`;
|
|
271
|
+
var TRANSITION_COMPLIANCE_CERT = `
|
|
272
|
+
mutation TheglobalfuelTransitionComplianceCert($id: ID!, $status: TheComplianceStatus!) {
|
|
273
|
+
theTransitionComplianceCert(id: $id, status: $status) {
|
|
274
|
+
${COMPLIANCE_FIELDS}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
`;
|
|
278
|
+
var HEALTH = `
|
|
279
|
+
query TheglobalfuelHealth {
|
|
280
|
+
theHealth
|
|
281
|
+
}
|
|
282
|
+
`;
|
|
283
|
+
var CommodityTypeEnum = z.enum([
|
|
284
|
+
"BAUXITE",
|
|
285
|
+
"BIOFUEL",
|
|
286
|
+
"COAL",
|
|
287
|
+
"COPPER",
|
|
288
|
+
"CRUDE_OIL",
|
|
289
|
+
"ELECTRICITY",
|
|
290
|
+
"GOLD",
|
|
291
|
+
"HYDROGEN",
|
|
292
|
+
"IRON_ORE",
|
|
293
|
+
"LITHIUM",
|
|
294
|
+
"LNG",
|
|
295
|
+
"NATURAL_GAS",
|
|
296
|
+
"RARE_EARTH"
|
|
297
|
+
]).describe("Energy / mineral / commodity resource type");
|
|
298
|
+
var AssetKindEnum = z.enum([
|
|
299
|
+
"GAS_FIELD",
|
|
300
|
+
"MINE",
|
|
301
|
+
"OIL_FIELD",
|
|
302
|
+
"PIPELINE",
|
|
303
|
+
"POWER_PLANT",
|
|
304
|
+
"PROCESSING_PLANT",
|
|
305
|
+
"QUARRY",
|
|
306
|
+
"REFINERY",
|
|
307
|
+
"SOLAR_FARM",
|
|
308
|
+
"STORAGE_TERMINAL",
|
|
309
|
+
"WELL",
|
|
310
|
+
"WIND_FARM"
|
|
311
|
+
]).describe("Physical kind of a resource asset");
|
|
312
|
+
var AssetStatusEnum = z.enum([
|
|
313
|
+
"APPRAISAL",
|
|
314
|
+
"DECOMMISSIONING",
|
|
315
|
+
"DEVELOPMENT",
|
|
316
|
+
"EXPLORATION",
|
|
317
|
+
"PRODUCING",
|
|
318
|
+
"RETIRED",
|
|
319
|
+
"SUSPENDED"
|
|
320
|
+
]).describe("Lifecycle status of a resource asset");
|
|
321
|
+
var UnitEnum = z.enum(["BARRELS", "CUBIC_METERS", "GJ", "KILOGRAMS", "MCF", "MWH", "TONNES"]).describe("Unit of measure for volume / capacity / quantity");
|
|
322
|
+
var ReserveCategoryEnum = z.enum(["CONTINGENT", "POSSIBLE", "PROBABLE", "PROSPECTIVE", "PROVED"]).describe("Reserve-estimate confidence category");
|
|
323
|
+
var ContractSideEnum = z.enum(["BUY", "SELL"]).describe("Whether the offtake contract is a BUY or SELL position");
|
|
324
|
+
var ContractStatusEnum = z.enum(["ACTIVE", "COMPLETED", "DRAFT", "NEGOTIATION", "SIGNED", "SUSPENDED", "TERMINATED"]).describe("Lifecycle status of an offtake contract");
|
|
325
|
+
var PricingBasisEnum = z.enum(["FIXED", "FORMULA", "INDEX_LINKED", "SPOT"]).describe("Pricing basis for an offtake contract");
|
|
326
|
+
var ShipmentStatusEnum = z.enum(["CANCELLED", "DELIVERED", "IN_TRANSIT", "LOADING", "SCHEDULED"]).describe("Lifecycle status of a commodity shipment");
|
|
327
|
+
var TransportModeEnum = z.enum(["GRID", "PIPELINE", "RAIL", "TANKER", "TRUCK", "VESSEL_BULK"]).describe("Transport mode for a shipment");
|
|
328
|
+
var InventoryStatusEnum = z.enum(["AVAILABLE", "CONSUMED", "IN_TRANSIT", "RESERVED", "WRITTEN_OFF"]).describe("Lifecycle status of an inventory lot");
|
|
329
|
+
var EmissionScopeEnum = z.enum(["SCOPE_1", "SCOPE_2", "SCOPE_3"]).describe("GHG Protocol emission scope");
|
|
330
|
+
var ComplianceCategoryEnum = z.enum([
|
|
331
|
+
"CARBON_CREDIT",
|
|
332
|
+
"CHAIN_OF_CUSTODY",
|
|
333
|
+
"EMISSIONS_REPORT",
|
|
334
|
+
"ENVIRONMENTAL_PERMIT",
|
|
335
|
+
"EXPORT_LICENSE",
|
|
336
|
+
"EXTRACTION_LICENSE",
|
|
337
|
+
"SAFETY_AUDIT"
|
|
338
|
+
]).describe("Category of a compliance certification");
|
|
339
|
+
var ComplianceStatusEnum = z.enum(["APPROVED", "EXPIRED", "PENDING", "REJECTED", "REVOKED", "SUBMITTED"]).describe("Lifecycle status of a compliance certification");
|
|
340
|
+
var DateTimeString = z.string().describe("ISO-8601 DateTime, e.g. 2026-06-27T00:00:00Z");
|
|
341
|
+
|
|
342
|
+
// src/modules/theglobalfuel/tools/assets.ts
|
|
343
|
+
function registerAssetTools(server, ctx, track) {
|
|
344
|
+
server.registerTool(
|
|
345
|
+
track(mcpToolName(ctx.productName, "assets_get")),
|
|
346
|
+
{
|
|
347
|
+
title: "Get Asset",
|
|
348
|
+
description: "Fetch a single resource asset by ID, including its recent production records and reserve estimates.",
|
|
349
|
+
inputSchema: { id: z.string().describe("Asset ID") }
|
|
350
|
+
},
|
|
351
|
+
async ({ id }) => {
|
|
352
|
+
try {
|
|
353
|
+
const data = await ctx.gql.workspace.request(GET_ASSET, { id });
|
|
354
|
+
if (!data.theAsset) return errorResult(`Asset ${id} not found`);
|
|
355
|
+
return jsonResult(data.theAsset);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
ctx.logger.error("theglobalfuel assets_get failed", { error: String(error) });
|
|
358
|
+
return errorResult(
|
|
359
|
+
`Failed to get asset: ${error instanceof Error ? error.message : String(error)}`
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
server.registerTool(
|
|
365
|
+
track(mcpToolName(ctx.productName, "assets_list")),
|
|
366
|
+
{
|
|
367
|
+
title: "List Assets",
|
|
368
|
+
description: "List resource assets in the bound workspace with optional commodity/kind/status filters and pagination. Returns a connection ({ items, pageInfo }).",
|
|
369
|
+
inputSchema: {
|
|
370
|
+
commodity: CommodityTypeEnum.optional().describe("Filter by commodity type"),
|
|
371
|
+
kind: AssetKindEnum.optional().describe("Filter by asset kind"),
|
|
372
|
+
status: AssetStatusEnum.optional().describe("Filter by lifecycle status"),
|
|
373
|
+
limit: z.number().int().optional().describe("Page size (default 50)"),
|
|
374
|
+
offset: z.number().int().optional().describe("Pagination offset (default 0)")
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
async ({ commodity, kind, status, limit, offset }) => {
|
|
378
|
+
try {
|
|
379
|
+
const data = await ctx.gql.workspace.request(LIST_ASSETS, {
|
|
380
|
+
commodity,
|
|
381
|
+
kind,
|
|
382
|
+
status,
|
|
383
|
+
pagination: { limit: limit ?? 50, offset: offset ?? 0 }
|
|
384
|
+
});
|
|
385
|
+
return jsonResult(data.theListAssets);
|
|
386
|
+
} catch (error) {
|
|
387
|
+
ctx.logger.error("theglobalfuel assets_list failed", { error: String(error) });
|
|
388
|
+
return errorResult(
|
|
389
|
+
`Failed to list assets: ${error instanceof Error ? error.message : String(error)}`
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
server.registerTool(
|
|
395
|
+
track(mcpToolName(ctx.productName, "assets_create")),
|
|
396
|
+
{
|
|
397
|
+
title: "Create Asset",
|
|
398
|
+
description: "Register a new resource asset (well, mine, field, plant, etc.). `name` and `commodity` are required; `kind` defaults to WELL and `status` to EXPLORATION.",
|
|
399
|
+
inputSchema: {
|
|
400
|
+
name: z.string().min(1).describe("Asset display name"),
|
|
401
|
+
commodity: CommodityTypeEnum.describe("Commodity produced by the asset"),
|
|
402
|
+
kind: AssetKindEnum.optional().describe("Asset kind (default WELL)"),
|
|
403
|
+
code: z.string().optional().describe("Operator asset code / short identifier"),
|
|
404
|
+
capacityPerDay: z.number().optional().describe("Nameplate capacity per day"),
|
|
405
|
+
capacityUnit: UnitEnum.optional().describe("Unit for capacityPerDay (default BARRELS)"),
|
|
406
|
+
workingInterestPct: z.number().optional().describe("Working interest percentage held (0\u2013100)"),
|
|
407
|
+
operatorLeadId: z.string().optional().describe("User ID of the operator lead"),
|
|
408
|
+
location: z.string().optional().describe("Free-text location / basin name"),
|
|
409
|
+
latitude: z.number().optional().describe("Latitude (decimal degrees)"),
|
|
410
|
+
longitude: z.number().optional().describe("Longitude (decimal degrees)"),
|
|
411
|
+
commissionedAt: DateTimeString.optional().describe("Commissioning date"),
|
|
412
|
+
status: AssetStatusEnum.optional().describe(
|
|
413
|
+
"Initial lifecycle status (default EXPLORATION)"
|
|
414
|
+
),
|
|
415
|
+
tags: z.array(z.string()).optional().describe("Free-form tags")
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
async ({
|
|
419
|
+
name,
|
|
420
|
+
commodity,
|
|
421
|
+
kind,
|
|
422
|
+
code,
|
|
423
|
+
capacityPerDay,
|
|
424
|
+
capacityUnit,
|
|
425
|
+
workingInterestPct,
|
|
426
|
+
operatorLeadId,
|
|
427
|
+
location,
|
|
428
|
+
latitude,
|
|
429
|
+
longitude,
|
|
430
|
+
commissionedAt,
|
|
431
|
+
status,
|
|
432
|
+
tags
|
|
433
|
+
}) => {
|
|
434
|
+
try {
|
|
435
|
+
const input = { name, commodity };
|
|
436
|
+
if (kind !== void 0) input.kind = kind;
|
|
437
|
+
if (code !== void 0) input.code = code;
|
|
438
|
+
if (capacityPerDay !== void 0) input.capacityPerDay = capacityPerDay;
|
|
439
|
+
if (capacityUnit !== void 0) input.capacityUnit = capacityUnit;
|
|
440
|
+
if (workingInterestPct !== void 0) input.workingInterestPct = workingInterestPct;
|
|
441
|
+
if (operatorLeadId !== void 0) input.operatorLeadId = operatorLeadId;
|
|
442
|
+
if (location !== void 0) input.location = location;
|
|
443
|
+
if (latitude !== void 0) input.latitude = latitude;
|
|
444
|
+
if (longitude !== void 0) input.longitude = longitude;
|
|
445
|
+
if (commissionedAt !== void 0) input.commissionedAt = commissionedAt;
|
|
446
|
+
if (status !== void 0) input.status = status;
|
|
447
|
+
if (tags !== void 0) input.tags = tags;
|
|
448
|
+
const data = await ctx.gql.workspace.request(CREATE_ASSET, { input });
|
|
449
|
+
return jsonResult(data.theCreateAsset);
|
|
450
|
+
} catch (error) {
|
|
451
|
+
ctx.logger.error("theglobalfuel assets_create failed", { error: String(error) });
|
|
452
|
+
return errorResult(
|
|
453
|
+
`Failed to create asset: ${error instanceof Error ? error.message : String(error)}`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
);
|
|
458
|
+
server.registerTool(
|
|
459
|
+
track(mcpToolName(ctx.productName, "assets_update")),
|
|
460
|
+
{
|
|
461
|
+
title: "Update Asset",
|
|
462
|
+
description: "Update a resource asset. At least one mutable field must be provided. Use `assets_transition` / `assets_retire` for lifecycle changes.",
|
|
463
|
+
inputSchema: {
|
|
464
|
+
id: z.string().describe("Asset ID"),
|
|
465
|
+
name: z.string().optional().describe("Updated name"),
|
|
466
|
+
commodity: CommodityTypeEnum.optional().describe("Updated commodity"),
|
|
467
|
+
kind: AssetKindEnum.optional().describe("Updated asset kind"),
|
|
468
|
+
code: z.string().optional().describe("Updated asset code"),
|
|
469
|
+
capacityPerDay: z.number().optional().describe("Updated capacity per day"),
|
|
470
|
+
capacityUnit: UnitEnum.optional().describe("Updated capacity unit"),
|
|
471
|
+
workingInterestPct: z.number().optional().describe("Updated working interest percentage"),
|
|
472
|
+
operatorLeadId: z.string().optional().describe("Updated operator lead user ID"),
|
|
473
|
+
location: z.string().optional().describe("Updated location"),
|
|
474
|
+
latitude: z.number().optional().describe("Updated latitude"),
|
|
475
|
+
longitude: z.number().optional().describe("Updated longitude"),
|
|
476
|
+
commissionedAt: DateTimeString.optional().describe("Updated commissioning date"),
|
|
477
|
+
decommissionedAt: DateTimeString.optional().describe("Decommissioning date"),
|
|
478
|
+
tags: z.array(z.string()).optional().describe("Updated tags")
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
async ({
|
|
482
|
+
id,
|
|
483
|
+
name,
|
|
484
|
+
commodity,
|
|
485
|
+
kind,
|
|
486
|
+
code,
|
|
487
|
+
capacityPerDay,
|
|
488
|
+
capacityUnit,
|
|
489
|
+
workingInterestPct,
|
|
490
|
+
operatorLeadId,
|
|
491
|
+
location,
|
|
492
|
+
latitude,
|
|
493
|
+
longitude,
|
|
494
|
+
commissionedAt,
|
|
495
|
+
decommissionedAt,
|
|
496
|
+
tags
|
|
497
|
+
}) => {
|
|
498
|
+
try {
|
|
499
|
+
const input = {};
|
|
500
|
+
if (name !== void 0) input.name = name;
|
|
501
|
+
if (commodity !== void 0) input.commodity = commodity;
|
|
502
|
+
if (kind !== void 0) input.kind = kind;
|
|
503
|
+
if (code !== void 0) input.code = code;
|
|
504
|
+
if (capacityPerDay !== void 0) input.capacityPerDay = capacityPerDay;
|
|
505
|
+
if (capacityUnit !== void 0) input.capacityUnit = capacityUnit;
|
|
506
|
+
if (workingInterestPct !== void 0) input.workingInterestPct = workingInterestPct;
|
|
507
|
+
if (operatorLeadId !== void 0) input.operatorLeadId = operatorLeadId;
|
|
508
|
+
if (location !== void 0) input.location = location;
|
|
509
|
+
if (latitude !== void 0) input.latitude = latitude;
|
|
510
|
+
if (longitude !== void 0) input.longitude = longitude;
|
|
511
|
+
if (commissionedAt !== void 0) input.commissionedAt = commissionedAt;
|
|
512
|
+
if (decommissionedAt !== void 0) input.decommissionedAt = decommissionedAt;
|
|
513
|
+
if (tags !== void 0) input.tags = tags;
|
|
514
|
+
if (Object.keys(input).length === 0) {
|
|
515
|
+
return errorResult("No updates specified \u2014 provide at least one mutable asset field");
|
|
516
|
+
}
|
|
517
|
+
const data = await ctx.gql.workspace.request(UPDATE_ASSET, { id, input });
|
|
518
|
+
return jsonResult(data.theUpdateAsset);
|
|
519
|
+
} catch (error) {
|
|
520
|
+
ctx.logger.error("theglobalfuel assets_update failed", { error: String(error) });
|
|
521
|
+
return errorResult(
|
|
522
|
+
`Failed to update asset: ${error instanceof Error ? error.message : String(error)}`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
server.registerTool(
|
|
528
|
+
track(mcpToolName(ctx.productName, "assets_transition")),
|
|
529
|
+
{
|
|
530
|
+
title: "Transition Asset",
|
|
531
|
+
description: "Advance an asset through its lifecycle (validated transitions), e.g. EXPLORATION \u2192 APPRAISAL \u2192 DEVELOPMENT \u2192 PRODUCING.",
|
|
532
|
+
inputSchema: {
|
|
533
|
+
id: z.string().describe("Asset ID"),
|
|
534
|
+
status: AssetStatusEnum.describe("Target lifecycle status")
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
async ({ id, status }) => {
|
|
538
|
+
try {
|
|
539
|
+
const data = await ctx.gql.workspace.request(TRANSITION_ASSET, { id, status });
|
|
540
|
+
return jsonResult(data.theTransitionAsset);
|
|
541
|
+
} catch (error) {
|
|
542
|
+
ctx.logger.error("theglobalfuel assets_transition failed", { error: String(error) });
|
|
543
|
+
return errorResult(
|
|
544
|
+
`Failed to transition asset: ${error instanceof Error ? error.message : String(error)}`
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
);
|
|
549
|
+
server.registerTool(
|
|
550
|
+
track(mcpToolName(ctx.productName, "assets_retire")),
|
|
551
|
+
{
|
|
552
|
+
title: "Retire Asset",
|
|
553
|
+
description: "Retire (decommission) an asset. Returns true on success.",
|
|
554
|
+
inputSchema: { id: z.string().describe("Asset ID") }
|
|
555
|
+
},
|
|
556
|
+
async ({ id }) => {
|
|
557
|
+
try {
|
|
558
|
+
const data = await ctx.gql.workspace.request(
|
|
559
|
+
RETIRE_ASSET,
|
|
560
|
+
{ id }
|
|
561
|
+
);
|
|
562
|
+
return jsonResult({ retired: data.theRetireAsset });
|
|
563
|
+
} catch (error) {
|
|
564
|
+
ctx.logger.error("theglobalfuel assets_retire failed", { error: String(error) });
|
|
565
|
+
return errorResult(
|
|
566
|
+
`Failed to retire asset: ${error instanceof Error ? error.message : String(error)}`
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
function registerProductionTools(server, ctx, track) {
|
|
573
|
+
server.registerTool(
|
|
574
|
+
track(mcpToolName(ctx.productName, "production_list")),
|
|
575
|
+
{
|
|
576
|
+
title: "List Production Records",
|
|
577
|
+
description: "List production records, optionally filtered by asset, with pagination. Returns a connection ({ items, pageInfo }).",
|
|
578
|
+
inputSchema: {
|
|
579
|
+
assetId: z.string().optional().describe("Filter by asset ID"),
|
|
580
|
+
limit: z.number().int().optional().describe("Page size (default 50)"),
|
|
581
|
+
offset: z.number().int().optional().describe("Pagination offset (default 0)")
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
async ({ assetId, limit, offset }) => {
|
|
585
|
+
try {
|
|
586
|
+
const data = await ctx.gql.workspace.request(LIST_PRODUCTION_RECORDS, {
|
|
587
|
+
assetId,
|
|
588
|
+
pagination: { limit: limit ?? 50, offset: offset ?? 0 }
|
|
589
|
+
});
|
|
590
|
+
return jsonResult(data.theListProductionRecords);
|
|
591
|
+
} catch (error) {
|
|
592
|
+
ctx.logger.error("theglobalfuel production_list failed", { error: String(error) });
|
|
593
|
+
return errorResult(
|
|
594
|
+
`Failed to list production records: ${error instanceof Error ? error.message : String(error)}`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
);
|
|
599
|
+
server.registerTool(
|
|
600
|
+
track(mcpToolName(ctx.productName, "production_record")),
|
|
601
|
+
{
|
|
602
|
+
title: "Record Production",
|
|
603
|
+
description: "Record a production figure for an asset over a period. `assetId`, `periodStart`, `periodEnd`, and `volume` are required.",
|
|
604
|
+
inputSchema: {
|
|
605
|
+
assetId: z.string().min(1).describe("Asset the production is recorded against"),
|
|
606
|
+
periodStart: DateTimeString.describe("Production period start"),
|
|
607
|
+
periodEnd: DateTimeString.describe("Production period end"),
|
|
608
|
+
volume: z.number().describe("Produced volume in the given unit"),
|
|
609
|
+
unit: UnitEnum.optional().describe("Volume unit (default BARRELS)"),
|
|
610
|
+
grade: z.number().optional().describe("Average grade / quality factor"),
|
|
611
|
+
downtimeHours: z.number().optional().describe("Downtime hours during the period"),
|
|
612
|
+
notes: z.string().optional().describe("Free-text notes")
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
async ({ assetId, periodStart, periodEnd, volume, unit, grade, downtimeHours, notes }) => {
|
|
616
|
+
try {
|
|
617
|
+
const input = { assetId, periodStart, periodEnd, volume };
|
|
618
|
+
if (unit !== void 0) input.unit = unit;
|
|
619
|
+
if (grade !== void 0) input.grade = grade;
|
|
620
|
+
if (downtimeHours !== void 0) input.downtimeHours = downtimeHours;
|
|
621
|
+
if (notes !== void 0) input.notes = notes;
|
|
622
|
+
const data = await ctx.gql.workspace.request(RECORD_PRODUCTION, { input });
|
|
623
|
+
return jsonResult(data.theRecordProduction);
|
|
624
|
+
} catch (error) {
|
|
625
|
+
ctx.logger.error("theglobalfuel production_record failed", { error: String(error) });
|
|
626
|
+
return errorResult(
|
|
627
|
+
`Failed to record production: ${error instanceof Error ? error.message : String(error)}`
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
function registerReserveTools(server, ctx, track) {
|
|
634
|
+
server.registerTool(
|
|
635
|
+
track(mcpToolName(ctx.productName, "reserves_list")),
|
|
636
|
+
{
|
|
637
|
+
title: "List Reserve Estimates",
|
|
638
|
+
description: "List reserve estimates, optionally filtered by asset and/or reserve category. Returns a plain array.",
|
|
639
|
+
inputSchema: {
|
|
640
|
+
assetId: z.string().optional().describe("Filter by asset ID"),
|
|
641
|
+
category: ReserveCategoryEnum.optional().describe("Filter by reserve category")
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
async ({ assetId, category }) => {
|
|
645
|
+
try {
|
|
646
|
+
const data = await ctx.gql.workspace.request(LIST_RESERVE_ESTIMATES, { assetId, category });
|
|
647
|
+
return jsonResult(data.theListReserveEstimates);
|
|
648
|
+
} catch (error) {
|
|
649
|
+
ctx.logger.error("theglobalfuel reserves_list failed", { error: String(error) });
|
|
650
|
+
return errorResult(
|
|
651
|
+
`Failed to list reserve estimates: ${error instanceof Error ? error.message : String(error)}`
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
);
|
|
656
|
+
server.registerTool(
|
|
657
|
+
track(mcpToolName(ctx.productName, "reserves_create")),
|
|
658
|
+
{
|
|
659
|
+
title: "Create Reserve Estimate",
|
|
660
|
+
description: "Create a reserve estimate for an asset. `assetId`, `asOfDate`, and `recoverable` are required; `category` defaults to PROVED.",
|
|
661
|
+
inputSchema: {
|
|
662
|
+
assetId: z.string().min(1).describe("Asset the estimate is for"),
|
|
663
|
+
asOfDate: DateTimeString.describe("As-of valuation date"),
|
|
664
|
+
recoverable: z.number().describe("Recoverable quantity in the given unit"),
|
|
665
|
+
category: ReserveCategoryEnum.optional().describe("Reserve category (default PROVED)"),
|
|
666
|
+
recoveryFactor: z.number().optional().describe("Recovery factor (0\u20131)"),
|
|
667
|
+
unit: UnitEnum.optional().describe("Unit for recoverable (default BARRELS)"),
|
|
668
|
+
methodology: z.string().optional().describe("Estimation methodology"),
|
|
669
|
+
notes: z.string().optional().describe("Free-text notes")
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
async ({
|
|
673
|
+
assetId,
|
|
674
|
+
asOfDate,
|
|
675
|
+
recoverable,
|
|
676
|
+
category,
|
|
677
|
+
recoveryFactor,
|
|
678
|
+
unit,
|
|
679
|
+
methodology,
|
|
680
|
+
notes
|
|
681
|
+
}) => {
|
|
682
|
+
try {
|
|
683
|
+
const input = { assetId, asOfDate, recoverable };
|
|
684
|
+
if (category !== void 0) input.category = category;
|
|
685
|
+
if (recoveryFactor !== void 0) input.recoveryFactor = recoveryFactor;
|
|
686
|
+
if (unit !== void 0) input.unit = unit;
|
|
687
|
+
if (methodology !== void 0) input.methodology = methodology;
|
|
688
|
+
if (notes !== void 0) input.notes = notes;
|
|
689
|
+
const data = await ctx.gql.workspace.request(CREATE_RESERVE_ESTIMATE, { input });
|
|
690
|
+
return jsonResult(data.theCreateReserveEstimate);
|
|
691
|
+
} catch (error) {
|
|
692
|
+
ctx.logger.error("theglobalfuel reserves_create failed", { error: String(error) });
|
|
693
|
+
return errorResult(
|
|
694
|
+
`Failed to create reserve estimate: ${error instanceof Error ? error.message : String(error)}`
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
function registerContractTools(server, ctx, track) {
|
|
701
|
+
server.registerTool(
|
|
702
|
+
track(mcpToolName(ctx.productName, "contracts_get")),
|
|
703
|
+
{
|
|
704
|
+
title: "Get Offtake Contract",
|
|
705
|
+
description: "Fetch a single offtake contract by ID, including its shipments.",
|
|
706
|
+
inputSchema: { id: z.string().describe("Contract ID") }
|
|
707
|
+
},
|
|
708
|
+
async ({ id }) => {
|
|
709
|
+
try {
|
|
710
|
+
const data = await ctx.gql.workspace.request(GET_CONTRACT, { id });
|
|
711
|
+
if (!data.theContract) return errorResult(`Contract ${id} not found`);
|
|
712
|
+
return jsonResult(data.theContract);
|
|
713
|
+
} catch (error) {
|
|
714
|
+
ctx.logger.error("theglobalfuel contracts_get failed", { error: String(error) });
|
|
715
|
+
return errorResult(
|
|
716
|
+
`Failed to get contract: ${error instanceof Error ? error.message : String(error)}`
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
);
|
|
721
|
+
server.registerTool(
|
|
722
|
+
track(mcpToolName(ctx.productName, "contracts_list")),
|
|
723
|
+
{
|
|
724
|
+
title: "List Offtake Contracts",
|
|
725
|
+
description: "List offtake contracts with optional commodity/side/status filters and pagination. Returns a connection ({ items, pageInfo }).",
|
|
726
|
+
inputSchema: {
|
|
727
|
+
commodity: CommodityTypeEnum.optional().describe("Filter by commodity"),
|
|
728
|
+
side: ContractSideEnum.optional().describe("Filter by BUY/SELL side"),
|
|
729
|
+
status: ContractStatusEnum.optional().describe("Filter by contract status"),
|
|
730
|
+
limit: z.number().int().optional().describe("Page size (default 50)"),
|
|
731
|
+
offset: z.number().int().optional().describe("Pagination offset (default 0)")
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
async ({ commodity, side, status, limit, offset }) => {
|
|
735
|
+
try {
|
|
736
|
+
const data = await ctx.gql.workspace.request(LIST_CONTRACTS, {
|
|
737
|
+
commodity,
|
|
738
|
+
side,
|
|
739
|
+
status,
|
|
740
|
+
pagination: { limit: limit ?? 50, offset: offset ?? 0 }
|
|
741
|
+
});
|
|
742
|
+
return jsonResult(data.theListContracts);
|
|
743
|
+
} catch (error) {
|
|
744
|
+
ctx.logger.error("theglobalfuel contracts_list failed", { error: String(error) });
|
|
745
|
+
return errorResult(
|
|
746
|
+
`Failed to list contracts: ${error instanceof Error ? error.message : String(error)}`
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
);
|
|
751
|
+
server.registerTool(
|
|
752
|
+
track(mcpToolName(ctx.productName, "contracts_create")),
|
|
753
|
+
{
|
|
754
|
+
title: "Create Offtake Contract",
|
|
755
|
+
description: "Create an offtake contract. `reference`, `counterparty`, and `commodity` are required; `side` defaults to SELL and `pricingBasis` to FIXED.",
|
|
756
|
+
inputSchema: {
|
|
757
|
+
reference: z.string().min(1).describe("Unique contract reference"),
|
|
758
|
+
counterparty: z.string().min(1).describe("Counterparty name"),
|
|
759
|
+
commodity: CommodityTypeEnum.describe("Contracted commodity"),
|
|
760
|
+
side: ContractSideEnum.optional().describe("BUY or SELL (default SELL)"),
|
|
761
|
+
contractedVolume: z.number().optional().describe("Total contracted volume"),
|
|
762
|
+
unit: UnitEnum.optional().describe("Volume unit (default BARRELS)"),
|
|
763
|
+
pricePerUnit: z.number().optional().describe("Fixed price per unit"),
|
|
764
|
+
currency: z.string().optional().describe("Pricing currency (e.g. USD)"),
|
|
765
|
+
priceIndex: z.string().optional().describe("Reference price index (for index-linked)"),
|
|
766
|
+
pricingBasis: PricingBasisEnum.optional().describe("Pricing basis (default FIXED)"),
|
|
767
|
+
deliveryLocation: z.string().optional().describe("Delivery location"),
|
|
768
|
+
startDate: DateTimeString.optional().describe("Contract start date"),
|
|
769
|
+
endDate: DateTimeString.optional().describe("Contract end date"),
|
|
770
|
+
notes: z.string().optional().describe("Free-text notes"),
|
|
771
|
+
tags: z.array(z.string()).optional().describe("Free-form tags")
|
|
772
|
+
}
|
|
773
|
+
},
|
|
774
|
+
async ({
|
|
775
|
+
reference,
|
|
776
|
+
counterparty,
|
|
777
|
+
commodity,
|
|
778
|
+
side,
|
|
779
|
+
contractedVolume,
|
|
780
|
+
unit,
|
|
781
|
+
pricePerUnit,
|
|
782
|
+
currency,
|
|
783
|
+
priceIndex,
|
|
784
|
+
pricingBasis,
|
|
785
|
+
deliveryLocation,
|
|
786
|
+
startDate,
|
|
787
|
+
endDate,
|
|
788
|
+
notes,
|
|
789
|
+
tags
|
|
790
|
+
}) => {
|
|
791
|
+
try {
|
|
792
|
+
const input = { reference, counterparty, commodity };
|
|
793
|
+
if (side !== void 0) input.side = side;
|
|
794
|
+
if (contractedVolume !== void 0) input.contractedVolume = contractedVolume;
|
|
795
|
+
if (unit !== void 0) input.unit = unit;
|
|
796
|
+
if (pricePerUnit !== void 0) input.pricePerUnit = pricePerUnit;
|
|
797
|
+
if (currency !== void 0) input.currency = currency;
|
|
798
|
+
if (priceIndex !== void 0) input.priceIndex = priceIndex;
|
|
799
|
+
if (pricingBasis !== void 0) input.pricingBasis = pricingBasis;
|
|
800
|
+
if (deliveryLocation !== void 0) input.deliveryLocation = deliveryLocation;
|
|
801
|
+
if (startDate !== void 0) input.startDate = startDate;
|
|
802
|
+
if (endDate !== void 0) input.endDate = endDate;
|
|
803
|
+
if (notes !== void 0) input.notes = notes;
|
|
804
|
+
if (tags !== void 0) input.tags = tags;
|
|
805
|
+
const data = await ctx.gql.workspace.request(CREATE_CONTRACT, { input });
|
|
806
|
+
return jsonResult(data.theCreateContract);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
ctx.logger.error("theglobalfuel contracts_create failed", { error: String(error) });
|
|
809
|
+
return errorResult(
|
|
810
|
+
`Failed to create contract: ${error instanceof Error ? error.message : String(error)}`
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
server.registerTool(
|
|
816
|
+
track(mcpToolName(ctx.productName, "contracts_update")),
|
|
817
|
+
{
|
|
818
|
+
title: "Update Offtake Contract",
|
|
819
|
+
description: "Update an offtake contract. At least one mutable field must be provided. Use `contracts_transition` for lifecycle changes.",
|
|
820
|
+
inputSchema: {
|
|
821
|
+
id: z.string().describe("Contract ID"),
|
|
822
|
+
counterparty: z.string().optional().describe("Updated counterparty"),
|
|
823
|
+
contractedVolume: z.number().optional().describe("Updated contracted volume"),
|
|
824
|
+
unit: UnitEnum.optional().describe("Updated volume unit"),
|
|
825
|
+
pricePerUnit: z.number().optional().describe("Updated price per unit"),
|
|
826
|
+
currency: z.string().optional().describe("Updated currency"),
|
|
827
|
+
priceIndex: z.string().optional().describe("Updated price index"),
|
|
828
|
+
pricingBasis: PricingBasisEnum.optional().describe("Updated pricing basis"),
|
|
829
|
+
deliveryLocation: z.string().optional().describe("Updated delivery location"),
|
|
830
|
+
startDate: DateTimeString.optional().describe("Updated start date"),
|
|
831
|
+
endDate: DateTimeString.optional().describe("Updated end date"),
|
|
832
|
+
notes: z.string().optional().describe("Updated notes"),
|
|
833
|
+
tags: z.array(z.string()).optional().describe("Updated tags")
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
async ({
|
|
837
|
+
id,
|
|
838
|
+
counterparty,
|
|
839
|
+
contractedVolume,
|
|
840
|
+
unit,
|
|
841
|
+
pricePerUnit,
|
|
842
|
+
currency,
|
|
843
|
+
priceIndex,
|
|
844
|
+
pricingBasis,
|
|
845
|
+
deliveryLocation,
|
|
846
|
+
startDate,
|
|
847
|
+
endDate,
|
|
848
|
+
notes,
|
|
849
|
+
tags
|
|
850
|
+
}) => {
|
|
851
|
+
try {
|
|
852
|
+
const input = {};
|
|
853
|
+
if (counterparty !== void 0) input.counterparty = counterparty;
|
|
854
|
+
if (contractedVolume !== void 0) input.contractedVolume = contractedVolume;
|
|
855
|
+
if (unit !== void 0) input.unit = unit;
|
|
856
|
+
if (pricePerUnit !== void 0) input.pricePerUnit = pricePerUnit;
|
|
857
|
+
if (currency !== void 0) input.currency = currency;
|
|
858
|
+
if (priceIndex !== void 0) input.priceIndex = priceIndex;
|
|
859
|
+
if (pricingBasis !== void 0) input.pricingBasis = pricingBasis;
|
|
860
|
+
if (deliveryLocation !== void 0) input.deliveryLocation = deliveryLocation;
|
|
861
|
+
if (startDate !== void 0) input.startDate = startDate;
|
|
862
|
+
if (endDate !== void 0) input.endDate = endDate;
|
|
863
|
+
if (notes !== void 0) input.notes = notes;
|
|
864
|
+
if (tags !== void 0) input.tags = tags;
|
|
865
|
+
if (Object.keys(input).length === 0) {
|
|
866
|
+
return errorResult("No updates specified \u2014 provide at least one mutable contract field");
|
|
867
|
+
}
|
|
868
|
+
const data = await ctx.gql.workspace.request(UPDATE_CONTRACT, { id, input });
|
|
869
|
+
return jsonResult(data.theUpdateContract);
|
|
870
|
+
} catch (error) {
|
|
871
|
+
ctx.logger.error("theglobalfuel contracts_update failed", { error: String(error) });
|
|
872
|
+
return errorResult(
|
|
873
|
+
`Failed to update contract: ${error instanceof Error ? error.message : String(error)}`
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
);
|
|
878
|
+
server.registerTool(
|
|
879
|
+
track(mcpToolName(ctx.productName, "contracts_transition")),
|
|
880
|
+
{
|
|
881
|
+
title: "Transition Offtake Contract",
|
|
882
|
+
description: "Advance an offtake contract through its lifecycle (validated transitions), e.g. DRAFT \u2192 NEGOTIATION \u2192 SIGNED \u2192 ACTIVE \u2192 COMPLETED.",
|
|
883
|
+
inputSchema: {
|
|
884
|
+
id: z.string().describe("Contract ID"),
|
|
885
|
+
status: ContractStatusEnum.describe("Target contract status")
|
|
886
|
+
}
|
|
887
|
+
},
|
|
888
|
+
async ({ id, status }) => {
|
|
889
|
+
try {
|
|
890
|
+
const data = await ctx.gql.workspace.request(TRANSITION_CONTRACT, { id, status });
|
|
891
|
+
return jsonResult(data.theTransitionContract);
|
|
892
|
+
} catch (error) {
|
|
893
|
+
ctx.logger.error("theglobalfuel contracts_transition failed", { error: String(error) });
|
|
894
|
+
return errorResult(
|
|
895
|
+
`Failed to transition contract: ${error instanceof Error ? error.message : String(error)}`
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
function registerShipmentTools(server, ctx, track) {
|
|
902
|
+
server.registerTool(
|
|
903
|
+
track(mcpToolName(ctx.productName, "shipments_list")),
|
|
904
|
+
{
|
|
905
|
+
title: "List Shipments",
|
|
906
|
+
description: "List commodity shipments, optionally filtered by contract and/or status. Returns a plain array.",
|
|
907
|
+
inputSchema: {
|
|
908
|
+
contractId: z.string().optional().describe("Filter by contract ID"),
|
|
909
|
+
status: ShipmentStatusEnum.optional().describe("Filter by shipment status")
|
|
910
|
+
}
|
|
911
|
+
},
|
|
912
|
+
async ({ contractId, status }) => {
|
|
913
|
+
try {
|
|
914
|
+
const data = await ctx.gql.workspace.request(LIST_SHIPMENTS, { contractId, status });
|
|
915
|
+
return jsonResult(data.theListShipments);
|
|
916
|
+
} catch (error) {
|
|
917
|
+
ctx.logger.error("theglobalfuel shipments_list failed", { error: String(error) });
|
|
918
|
+
return errorResult(
|
|
919
|
+
`Failed to list shipments: ${error instanceof Error ? error.message : String(error)}`
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
);
|
|
924
|
+
server.registerTool(
|
|
925
|
+
track(mcpToolName(ctx.productName, "shipments_schedule")),
|
|
926
|
+
{
|
|
927
|
+
title: "Schedule Shipment",
|
|
928
|
+
description: "Schedule a shipment against a contract. `contractId`, `reference`, and `volume` are required; `mode` defaults to PIPELINE.",
|
|
929
|
+
inputSchema: {
|
|
930
|
+
contractId: z.string().min(1).describe("Contract the shipment fulfils"),
|
|
931
|
+
reference: z.string().min(1).describe("Unique shipment reference"),
|
|
932
|
+
volume: z.number().describe("Shipment volume in the given unit"),
|
|
933
|
+
unit: UnitEnum.optional().describe("Volume unit (default BARRELS)"),
|
|
934
|
+
mode: TransportModeEnum.optional().describe("Transport mode (default PIPELINE)"),
|
|
935
|
+
origin: z.string().optional().describe("Origin location"),
|
|
936
|
+
destination: z.string().optional().describe("Destination location"),
|
|
937
|
+
carrier: z.string().optional().describe("Carrier / transporter name"),
|
|
938
|
+
scheduledAt: DateTimeString.optional().describe("Scheduled departure time"),
|
|
939
|
+
documentFileId: z.string().optional().describe("wspace-files-svc File ID (bill of lading / certificate)"),
|
|
940
|
+
notes: z.string().optional().describe("Free-text notes")
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
async ({
|
|
944
|
+
contractId,
|
|
945
|
+
reference,
|
|
946
|
+
volume,
|
|
947
|
+
unit,
|
|
948
|
+
mode,
|
|
949
|
+
origin,
|
|
950
|
+
destination,
|
|
951
|
+
carrier,
|
|
952
|
+
scheduledAt,
|
|
953
|
+
documentFileId,
|
|
954
|
+
notes
|
|
955
|
+
}) => {
|
|
956
|
+
try {
|
|
957
|
+
const input = { contractId, reference, volume };
|
|
958
|
+
if (unit !== void 0) input.unit = unit;
|
|
959
|
+
if (mode !== void 0) input.mode = mode;
|
|
960
|
+
if (origin !== void 0) input.origin = origin;
|
|
961
|
+
if (destination !== void 0) input.destination = destination;
|
|
962
|
+
if (carrier !== void 0) input.carrier = carrier;
|
|
963
|
+
if (scheduledAt !== void 0) input.scheduledAt = scheduledAt;
|
|
964
|
+
if (documentFileId !== void 0) input.documentFileId = documentFileId;
|
|
965
|
+
if (notes !== void 0) input.notes = notes;
|
|
966
|
+
const data = await ctx.gql.workspace.request(SCHEDULE_SHIPMENT, { input });
|
|
967
|
+
return jsonResult(data.theScheduleShipment);
|
|
968
|
+
} catch (error) {
|
|
969
|
+
ctx.logger.error("theglobalfuel shipments_schedule failed", { error: String(error) });
|
|
970
|
+
return errorResult(
|
|
971
|
+
`Failed to schedule shipment: ${error instanceof Error ? error.message : String(error)}`
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
);
|
|
976
|
+
server.registerTool(
|
|
977
|
+
track(mcpToolName(ctx.productName, "shipments_deliver")),
|
|
978
|
+
{
|
|
979
|
+
title: "Deliver Shipment",
|
|
980
|
+
description: "Mark a shipment delivered and roll its volume into the contract's delivered total.",
|
|
981
|
+
inputSchema: { id: z.string().describe("Shipment ID") }
|
|
982
|
+
},
|
|
983
|
+
async ({ id }) => {
|
|
984
|
+
try {
|
|
985
|
+
const data = await ctx.gql.workspace.request(DELIVER_SHIPMENT, { id });
|
|
986
|
+
return jsonResult(data.theDeliverShipment);
|
|
987
|
+
} catch (error) {
|
|
988
|
+
ctx.logger.error("theglobalfuel shipments_deliver failed", { error: String(error) });
|
|
989
|
+
return errorResult(
|
|
990
|
+
`Failed to deliver shipment: ${error instanceof Error ? error.message : String(error)}`
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
function registerInventoryTools(server, ctx, track) {
|
|
997
|
+
server.registerTool(
|
|
998
|
+
track(mcpToolName(ctx.productName, "inventory_list")),
|
|
999
|
+
{
|
|
1000
|
+
title: "List Inventory Lots",
|
|
1001
|
+
description: "List inventory lots with optional commodity/status filters and pagination. Returns a connection ({ items, pageInfo }).",
|
|
1002
|
+
inputSchema: {
|
|
1003
|
+
commodity: CommodityTypeEnum.optional().describe("Filter by commodity"),
|
|
1004
|
+
status: InventoryStatusEnum.optional().describe("Filter by inventory status"),
|
|
1005
|
+
limit: z.number().int().optional().describe("Page size (default 50)"),
|
|
1006
|
+
offset: z.number().int().optional().describe("Pagination offset (default 0)")
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
1009
|
+
async ({ commodity, status, limit, offset }) => {
|
|
1010
|
+
try {
|
|
1011
|
+
const data = await ctx.gql.workspace.request(LIST_INVENTORY_LOTS, {
|
|
1012
|
+
commodity,
|
|
1013
|
+
status,
|
|
1014
|
+
pagination: { limit: limit ?? 50, offset: offset ?? 0 }
|
|
1015
|
+
});
|
|
1016
|
+
return jsonResult(data.theListInventoryLots);
|
|
1017
|
+
} catch (error) {
|
|
1018
|
+
ctx.logger.error("theglobalfuel inventory_list failed", { error: String(error) });
|
|
1019
|
+
return errorResult(
|
|
1020
|
+
`Failed to list inventory lots: ${error instanceof Error ? error.message : String(error)}`
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
);
|
|
1025
|
+
server.registerTool(
|
|
1026
|
+
track(mcpToolName(ctx.productName, "inventory_create")),
|
|
1027
|
+
{
|
|
1028
|
+
title: "Create Inventory Lot",
|
|
1029
|
+
description: "Create an inventory lot. `lotCode`, `commodity`, and `quantity` are required; `unit` defaults to BARRELS.",
|
|
1030
|
+
inputSchema: {
|
|
1031
|
+
lotCode: z.string().min(1).describe("Unique lot code"),
|
|
1032
|
+
commodity: CommodityTypeEnum.describe("Commodity stored in the lot"),
|
|
1033
|
+
quantity: z.number().describe("Quantity in the given unit"),
|
|
1034
|
+
unit: UnitEnum.optional().describe("Quantity unit (default BARRELS)"),
|
|
1035
|
+
grade: z.number().optional().describe("Average grade / quality factor"),
|
|
1036
|
+
unitValue: z.number().optional().describe("Per-unit value"),
|
|
1037
|
+
currency: z.string().optional().describe("Currency for unitValue"),
|
|
1038
|
+
location: z.string().optional().describe("Storage location"),
|
|
1039
|
+
assetId: z.string().optional().describe("Source asset ID"),
|
|
1040
|
+
producedAt: DateTimeString.optional().describe("Production / acquisition date"),
|
|
1041
|
+
notes: z.string().optional().describe("Free-text notes")
|
|
1042
|
+
}
|
|
1043
|
+
},
|
|
1044
|
+
async ({
|
|
1045
|
+
lotCode,
|
|
1046
|
+
commodity,
|
|
1047
|
+
quantity,
|
|
1048
|
+
unit,
|
|
1049
|
+
grade,
|
|
1050
|
+
unitValue,
|
|
1051
|
+
currency,
|
|
1052
|
+
location,
|
|
1053
|
+
assetId,
|
|
1054
|
+
producedAt,
|
|
1055
|
+
notes
|
|
1056
|
+
}) => {
|
|
1057
|
+
try {
|
|
1058
|
+
const input = { lotCode, commodity, quantity };
|
|
1059
|
+
if (unit !== void 0) input.unit = unit;
|
|
1060
|
+
if (grade !== void 0) input.grade = grade;
|
|
1061
|
+
if (unitValue !== void 0) input.unitValue = unitValue;
|
|
1062
|
+
if (currency !== void 0) input.currency = currency;
|
|
1063
|
+
if (location !== void 0) input.location = location;
|
|
1064
|
+
if (assetId !== void 0) input.assetId = assetId;
|
|
1065
|
+
if (producedAt !== void 0) input.producedAt = producedAt;
|
|
1066
|
+
if (notes !== void 0) input.notes = notes;
|
|
1067
|
+
const data = await ctx.gql.workspace.request(CREATE_INVENTORY_LOT, { input });
|
|
1068
|
+
return jsonResult(data.theCreateInventoryLot);
|
|
1069
|
+
} catch (error) {
|
|
1070
|
+
ctx.logger.error("theglobalfuel inventory_create failed", { error: String(error) });
|
|
1071
|
+
return errorResult(
|
|
1072
|
+
`Failed to create inventory lot: ${error instanceof Error ? error.message : String(error)}`
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
server.registerTool(
|
|
1078
|
+
track(mcpToolName(ctx.productName, "inventory_set_status")),
|
|
1079
|
+
{
|
|
1080
|
+
title: "Set Inventory Lot Status",
|
|
1081
|
+
description: "Set the status of an inventory lot (AVAILABLE / RESERVED / IN_TRANSIT / CONSUMED / WRITTEN_OFF).",
|
|
1082
|
+
inputSchema: {
|
|
1083
|
+
id: z.string().describe("Inventory lot ID"),
|
|
1084
|
+
status: InventoryStatusEnum.describe("New inventory status")
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
async ({ id, status }) => {
|
|
1088
|
+
try {
|
|
1089
|
+
const data = await ctx.gql.workspace.request(SET_INVENTORY_LOT_STATUS, { id, status });
|
|
1090
|
+
return jsonResult(data.theSetInventoryLotStatus);
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
ctx.logger.error("theglobalfuel inventory_set_status failed", { error: String(error) });
|
|
1093
|
+
return errorResult(
|
|
1094
|
+
`Failed to set inventory lot status: ${error instanceof Error ? error.message : String(error)}`
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
function registerEmissionTools(server, ctx, track) {
|
|
1101
|
+
server.registerTool(
|
|
1102
|
+
track(mcpToolName(ctx.productName, "emissions_list")),
|
|
1103
|
+
{
|
|
1104
|
+
title: "List Emission Records",
|
|
1105
|
+
description: "List GHG emission records with optional asset/scope filters and pagination. Returns a connection ({ items, pageInfo }).",
|
|
1106
|
+
inputSchema: {
|
|
1107
|
+
assetId: z.string().optional().describe("Filter by asset ID"),
|
|
1108
|
+
scope: EmissionScopeEnum.optional().describe("Filter by emission scope"),
|
|
1109
|
+
limit: z.number().int().optional().describe("Page size (default 50)"),
|
|
1110
|
+
offset: z.number().int().optional().describe("Pagination offset (default 0)")
|
|
1111
|
+
}
|
|
1112
|
+
},
|
|
1113
|
+
async ({ assetId, scope, limit, offset }) => {
|
|
1114
|
+
try {
|
|
1115
|
+
const data = await ctx.gql.workspace.request(LIST_EMISSION_RECORDS, {
|
|
1116
|
+
assetId,
|
|
1117
|
+
scope,
|
|
1118
|
+
pagination: { limit: limit ?? 50, offset: offset ?? 0 }
|
|
1119
|
+
});
|
|
1120
|
+
return jsonResult(data.theListEmissionRecords);
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
ctx.logger.error("theglobalfuel emissions_list failed", { error: String(error) });
|
|
1123
|
+
return errorResult(
|
|
1124
|
+
`Failed to list emission records: ${error instanceof Error ? error.message : String(error)}`
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
);
|
|
1129
|
+
server.registerTool(
|
|
1130
|
+
track(mcpToolName(ctx.productName, "emissions_record")),
|
|
1131
|
+
{
|
|
1132
|
+
title: "Record Emission",
|
|
1133
|
+
description: "Record a GHG emission figure for a period. `co2eTonnes`, `periodStart`, and `periodEnd` are required; `scope` defaults to SCOPE_1.",
|
|
1134
|
+
inputSchema: {
|
|
1135
|
+
co2eTonnes: z.number().describe("CO2-equivalent tonnes emitted"),
|
|
1136
|
+
periodStart: DateTimeString.describe("Reporting period start"),
|
|
1137
|
+
periodEnd: DateTimeString.describe("Reporting period end"),
|
|
1138
|
+
scope: EmissionScopeEnum.optional().describe("Emission scope (default SCOPE_1)"),
|
|
1139
|
+
assetId: z.string().optional().describe("Asset the emission is attributed to"),
|
|
1140
|
+
source: z.string().optional().describe("Emission source description"),
|
|
1141
|
+
methodology: z.string().optional().describe("Calculation methodology"),
|
|
1142
|
+
notes: z.string().optional().describe("Free-text notes")
|
|
1143
|
+
}
|
|
1144
|
+
},
|
|
1145
|
+
async ({ co2eTonnes, periodStart, periodEnd, scope, assetId, source, methodology, notes }) => {
|
|
1146
|
+
try {
|
|
1147
|
+
const input = { co2eTonnes, periodStart, periodEnd };
|
|
1148
|
+
if (scope !== void 0) input.scope = scope;
|
|
1149
|
+
if (assetId !== void 0) input.assetId = assetId;
|
|
1150
|
+
if (source !== void 0) input.source = source;
|
|
1151
|
+
if (methodology !== void 0) input.methodology = methodology;
|
|
1152
|
+
if (notes !== void 0) input.notes = notes;
|
|
1153
|
+
const data = await ctx.gql.workspace.request(RECORD_EMISSION, { input });
|
|
1154
|
+
return jsonResult(data.theRecordEmission);
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
ctx.logger.error("theglobalfuel emissions_record failed", { error: String(error) });
|
|
1157
|
+
return errorResult(
|
|
1158
|
+
`Failed to record emission: ${error instanceof Error ? error.message : String(error)}`
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
);
|
|
1163
|
+
server.registerTool(
|
|
1164
|
+
track(mcpToolName(ctx.productName, "emissions_verify")),
|
|
1165
|
+
{
|
|
1166
|
+
title: "Verify Emission",
|
|
1167
|
+
description: "Mark an emission figure third-party verified.",
|
|
1168
|
+
inputSchema: { id: z.string().describe("Emission record ID") }
|
|
1169
|
+
},
|
|
1170
|
+
async ({ id }) => {
|
|
1171
|
+
try {
|
|
1172
|
+
const data = await ctx.gql.workspace.request(VERIFY_EMISSION, { id });
|
|
1173
|
+
return jsonResult(data.theVerifyEmission);
|
|
1174
|
+
} catch (error) {
|
|
1175
|
+
ctx.logger.error("theglobalfuel emissions_verify failed", { error: String(error) });
|
|
1176
|
+
return errorResult(
|
|
1177
|
+
`Failed to verify emission: ${error instanceof Error ? error.message : String(error)}`
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
function registerComplianceTools(server, ctx, track) {
|
|
1184
|
+
server.registerTool(
|
|
1185
|
+
track(mcpToolName(ctx.productName, "compliance_get")),
|
|
1186
|
+
{
|
|
1187
|
+
title: "Get Compliance Certification",
|
|
1188
|
+
description: "Fetch a single compliance certification by ID, including its evidence file reference.",
|
|
1189
|
+
inputSchema: { id: z.string().describe("Compliance certification ID") }
|
|
1190
|
+
},
|
|
1191
|
+
async ({ id }) => {
|
|
1192
|
+
try {
|
|
1193
|
+
const data = await ctx.gql.workspace.request(GET_COMPLIANCE_CERT, { id });
|
|
1194
|
+
if (!data.theComplianceCert) return errorResult(`Compliance certification ${id} not found`);
|
|
1195
|
+
return jsonResult(data.theComplianceCert);
|
|
1196
|
+
} catch (error) {
|
|
1197
|
+
ctx.logger.error("theglobalfuel compliance_get failed", { error: String(error) });
|
|
1198
|
+
return errorResult(
|
|
1199
|
+
`Failed to get compliance certification: ${error instanceof Error ? error.message : String(error)}`
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
server.registerTool(
|
|
1205
|
+
track(mcpToolName(ctx.productName, "compliance_list")),
|
|
1206
|
+
{
|
|
1207
|
+
title: "List Compliance Certifications",
|
|
1208
|
+
description: "List compliance certifications with optional asset/category/status filters. Returns a plain array.",
|
|
1209
|
+
inputSchema: {
|
|
1210
|
+
assetId: z.string().optional().describe("Filter by asset ID"),
|
|
1211
|
+
category: ComplianceCategoryEnum.optional().describe("Filter by category"),
|
|
1212
|
+
status: ComplianceStatusEnum.optional().describe("Filter by status")
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
async ({ assetId, category, status }) => {
|
|
1216
|
+
try {
|
|
1217
|
+
const data = await ctx.gql.workspace.request(LIST_COMPLIANCE_CERTS, { assetId, category, status });
|
|
1218
|
+
return jsonResult(data.theListComplianceCerts);
|
|
1219
|
+
} catch (error) {
|
|
1220
|
+
ctx.logger.error("theglobalfuel compliance_list failed", { error: String(error) });
|
|
1221
|
+
return errorResult(
|
|
1222
|
+
`Failed to list compliance certifications: ${error instanceof Error ? error.message : String(error)}`
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
);
|
|
1227
|
+
server.registerTool(
|
|
1228
|
+
track(mcpToolName(ctx.productName, "compliance_create")),
|
|
1229
|
+
{
|
|
1230
|
+
title: "Create Compliance Certification",
|
|
1231
|
+
description: "Create a compliance certification (permit, license, audit, carbon credit, etc.). `title` is required; `category` defaults to ENVIRONMENTAL_PERMIT.",
|
|
1232
|
+
inputSchema: {
|
|
1233
|
+
title: z.string().min(1).describe("Certification title"),
|
|
1234
|
+
category: ComplianceCategoryEnum.optional().describe(
|
|
1235
|
+
"Category (default ENVIRONMENTAL_PERMIT)"
|
|
1236
|
+
),
|
|
1237
|
+
assetId: z.string().optional().describe("Related asset ID"),
|
|
1238
|
+
authority: z.string().optional().describe("Issuing authority"),
|
|
1239
|
+
certNumber: z.string().optional().describe("Certificate / permit number"),
|
|
1240
|
+
evidenceFileId: z.string().optional().describe("wspace-files-svc File ID for the certificate document"),
|
|
1241
|
+
issuedAt: DateTimeString.optional().describe("Issue date"),
|
|
1242
|
+
expiresAt: DateTimeString.optional().describe("Expiry date"),
|
|
1243
|
+
ownerId: z.string().optional().describe("Owning user ID"),
|
|
1244
|
+
notes: z.string().optional().describe("Free-text notes"),
|
|
1245
|
+
tags: z.array(z.string()).optional().describe("Free-form tags")
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
async ({
|
|
1249
|
+
title,
|
|
1250
|
+
category,
|
|
1251
|
+
assetId,
|
|
1252
|
+
authority,
|
|
1253
|
+
certNumber,
|
|
1254
|
+
evidenceFileId,
|
|
1255
|
+
issuedAt,
|
|
1256
|
+
expiresAt,
|
|
1257
|
+
ownerId,
|
|
1258
|
+
notes,
|
|
1259
|
+
tags
|
|
1260
|
+
}) => {
|
|
1261
|
+
try {
|
|
1262
|
+
const input = { title };
|
|
1263
|
+
if (category !== void 0) input.category = category;
|
|
1264
|
+
if (assetId !== void 0) input.assetId = assetId;
|
|
1265
|
+
if (authority !== void 0) input.authority = authority;
|
|
1266
|
+
if (certNumber !== void 0) input.certNumber = certNumber;
|
|
1267
|
+
if (evidenceFileId !== void 0) input.evidenceFileId = evidenceFileId;
|
|
1268
|
+
if (issuedAt !== void 0) input.issuedAt = issuedAt;
|
|
1269
|
+
if (expiresAt !== void 0) input.expiresAt = expiresAt;
|
|
1270
|
+
if (ownerId !== void 0) input.ownerId = ownerId;
|
|
1271
|
+
if (notes !== void 0) input.notes = notes;
|
|
1272
|
+
if (tags !== void 0) input.tags = tags;
|
|
1273
|
+
const data = await ctx.gql.workspace.request(CREATE_COMPLIANCE_CERT, { input });
|
|
1274
|
+
return jsonResult(data.theCreateComplianceCert);
|
|
1275
|
+
} catch (error) {
|
|
1276
|
+
ctx.logger.error("theglobalfuel compliance_create failed", { error: String(error) });
|
|
1277
|
+
return errorResult(
|
|
1278
|
+
`Failed to create compliance certification: ${error instanceof Error ? error.message : String(error)}`
|
|
1279
|
+
);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
);
|
|
1283
|
+
server.registerTool(
|
|
1284
|
+
track(mcpToolName(ctx.productName, "compliance_transition")),
|
|
1285
|
+
{
|
|
1286
|
+
title: "Transition Compliance Certification",
|
|
1287
|
+
description: "Advance a compliance certification through its lifecycle (validated transitions), e.g. PENDING \u2192 SUBMITTED \u2192 APPROVED.",
|
|
1288
|
+
inputSchema: {
|
|
1289
|
+
id: z.string().describe("Compliance certification ID"),
|
|
1290
|
+
status: ComplianceStatusEnum.describe("Target status")
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
async ({ id, status }) => {
|
|
1294
|
+
try {
|
|
1295
|
+
const data = await ctx.gql.workspace.request(TRANSITION_COMPLIANCE_CERT, { id, status });
|
|
1296
|
+
return jsonResult(data.theTransitionComplianceCert);
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
ctx.logger.error("theglobalfuel compliance_transition failed", { error: String(error) });
|
|
1299
|
+
return errorResult(
|
|
1300
|
+
`Failed to transition compliance certification: ${error instanceof Error ? error.message : String(error)}`
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// src/modules/theglobalfuel/tools/health.ts
|
|
1308
|
+
function registerHealthTools(server, ctx, track) {
|
|
1309
|
+
server.registerTool(
|
|
1310
|
+
track(mcpToolName(ctx.productName, "health")),
|
|
1311
|
+
{
|
|
1312
|
+
title: "Theglobalfuel Health Check",
|
|
1313
|
+
description: "Public liveness/identity probe for the Theglobalfuel subgraph (theHealth). Requires no authentication.",
|
|
1314
|
+
inputSchema: {}
|
|
1315
|
+
},
|
|
1316
|
+
async () => {
|
|
1317
|
+
try {
|
|
1318
|
+
const data = await ctx.gql.workspace.request(HEALTH, {});
|
|
1319
|
+
return jsonResult({ ok: true, status: data.theHealth });
|
|
1320
|
+
} catch (error) {
|
|
1321
|
+
ctx.logger.error("theglobalfuel health failed", { error: String(error) });
|
|
1322
|
+
return errorResult(
|
|
1323
|
+
`Theglobalfuel health check failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
// src/modules/theglobalfuel/resources.ts
|
|
1331
|
+
function registerTheglobalfuelResources(server, ctx, track) {
|
|
1332
|
+
const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
|
|
1333
|
+
const assetsUri = track(mcpResourceUri(ctx.productName, "assets"));
|
|
1334
|
+
const contractsUri = track(mcpResourceUri(ctx.productName, "contracts"));
|
|
1335
|
+
const inventoryUri = track(mcpResourceUri(ctx.productName, "inventory"));
|
|
1336
|
+
server.registerResource(
|
|
1337
|
+
"theglobalfuel-schema",
|
|
1338
|
+
schemaUri,
|
|
1339
|
+
{
|
|
1340
|
+
title: "Theglobalfuel Domain Schema",
|
|
1341
|
+
description: "Overview of the Theglobalfuel resource-operating-system domain \u2014 entities, enums, and the per-entity tool surface.",
|
|
1342
|
+
mimeType: "text/plain"
|
|
1343
|
+
},
|
|
1344
|
+
async () => {
|
|
1345
|
+
ctx.logger.debug(`Resource ${schemaUri} requested`);
|
|
1346
|
+
const schema = `# Theglobalfuel Domain (Overview)
|
|
1347
|
+
|
|
1348
|
+
Energy, Mineral & Commodity Resource Operating System \u2014 the federated system of
|
|
1349
|
+
record for resource assets, production, reserves, offtake contracts, shipments,
|
|
1350
|
+
inventory, and ESG (emissions & compliance).
|
|
1351
|
+
|
|
1352
|
+
## Entities
|
|
1353
|
+
- TheAsset \u2014 a resource asset (well, mine, field, plant, pipeline, ...)
|
|
1354
|
+
- TheProductionRecord \u2014 periodic production captured against an asset
|
|
1355
|
+
- TheReserveEstimate \u2014 recoverable-reserve estimate for an asset
|
|
1356
|
+
- TheOfftakeContract \u2014 a BUY/SELL offtake contract (+ shipments)
|
|
1357
|
+
- TheShipment \u2014 a commodity shipment fulfilling a contract
|
|
1358
|
+
- TheInventoryLot \u2014 a stored commodity lot
|
|
1359
|
+
- TheEmissionRecord \u2014 a GHG emission figure (Scope 1/2/3)
|
|
1360
|
+
- TheComplianceCert \u2014 a regulatory / ESG certification (permit, license, audit)
|
|
1361
|
+
|
|
1362
|
+
## Enums
|
|
1363
|
+
- TheCommodityType: BAUXITE, BIOFUEL, COAL, COPPER, CRUDE_OIL, ELECTRICITY, GOLD, HYDROGEN, IRON_ORE, LITHIUM, LNG, NATURAL_GAS, RARE_EARTH
|
|
1364
|
+
- TheAssetKind: GAS_FIELD, MINE, OIL_FIELD, PIPELINE, POWER_PLANT, PROCESSING_PLANT, QUARRY, REFINERY, SOLAR_FARM, STORAGE_TERMINAL, WELL, WIND_FARM
|
|
1365
|
+
- TheAssetStatus: APPRAISAL, DECOMMISSIONING, DEVELOPMENT, EXPLORATION, PRODUCING, RETIRED, SUSPENDED
|
|
1366
|
+
- TheContractSide: BUY, SELL
|
|
1367
|
+
- TheContractStatus: ACTIVE, COMPLETED, DRAFT, NEGOTIATION, SIGNED, SUSPENDED, TERMINATED
|
|
1368
|
+
- TheShipmentStatus: CANCELLED, DELIVERED, IN_TRANSIT, LOADING, SCHEDULED
|
|
1369
|
+
- TheInventoryStatus: AVAILABLE, CONSUMED, IN_TRANSIT, RESERVED, WRITTEN_OFF
|
|
1370
|
+
- TheEmissionScope: SCOPE_1, SCOPE_2, SCOPE_3
|
|
1371
|
+
- TheComplianceStatus: APPROVED, EXPIRED, PENDING, REJECTED, REVOKED, SUBMITTED
|
|
1372
|
+
- TheUnit: BARRELS, CUBIC_METERS, GJ, KILOGRAMS, MCF, MWH, TONNES
|
|
1373
|
+
|
|
1374
|
+
## Tool groups
|
|
1375
|
+
assets, production, reserves, contracts, shipments, inventory, emissions, compliance, health.
|
|
1376
|
+
All run against the WORKSPACE gateway (workspace-scoped) except the public health probe.
|
|
1377
|
+
`;
|
|
1378
|
+
return {
|
|
1379
|
+
contents: [{ uri: schemaUri, text: schema, mimeType: "text/plain" }]
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
);
|
|
1383
|
+
server.registerResource(
|
|
1384
|
+
"theglobalfuel-assets",
|
|
1385
|
+
assetsUri,
|
|
1386
|
+
{
|
|
1387
|
+
title: "Theglobalfuel Asset Registry",
|
|
1388
|
+
description: "The first 50 resource assets in the bound workspace.",
|
|
1389
|
+
mimeType: "application/json"
|
|
1390
|
+
},
|
|
1391
|
+
async () => {
|
|
1392
|
+
ctx.logger.debug(`Resource ${assetsUri} requested`);
|
|
1393
|
+
try {
|
|
1394
|
+
const data = await ctx.gql.workspace.request(LIST_ASSETS, {
|
|
1395
|
+
pagination: { limit: 50, offset: 0 }
|
|
1396
|
+
});
|
|
1397
|
+
return {
|
|
1398
|
+
contents: [
|
|
1399
|
+
{
|
|
1400
|
+
uri: assetsUri,
|
|
1401
|
+
text: JSON.stringify(data.theListAssets, null, 2),
|
|
1402
|
+
mimeType: "application/json"
|
|
1403
|
+
}
|
|
1404
|
+
]
|
|
1405
|
+
};
|
|
1406
|
+
} catch (error) {
|
|
1407
|
+
return {
|
|
1408
|
+
contents: [
|
|
1409
|
+
{
|
|
1410
|
+
uri: assetsUri,
|
|
1411
|
+
text: JSON.stringify({
|
|
1412
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1413
|
+
}),
|
|
1414
|
+
mimeType: "application/json"
|
|
1415
|
+
}
|
|
1416
|
+
]
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
);
|
|
1421
|
+
server.registerResource(
|
|
1422
|
+
"theglobalfuel-contracts",
|
|
1423
|
+
contractsUri,
|
|
1424
|
+
{
|
|
1425
|
+
title: "Theglobalfuel Offtake Contracts",
|
|
1426
|
+
description: "The first 50 offtake contracts in the bound workspace.",
|
|
1427
|
+
mimeType: "application/json"
|
|
1428
|
+
},
|
|
1429
|
+
async () => {
|
|
1430
|
+
ctx.logger.debug(`Resource ${contractsUri} requested`);
|
|
1431
|
+
try {
|
|
1432
|
+
const data = await ctx.gql.workspace.request(
|
|
1433
|
+
LIST_CONTRACTS,
|
|
1434
|
+
{
|
|
1435
|
+
pagination: { limit: 50, offset: 0 }
|
|
1436
|
+
}
|
|
1437
|
+
);
|
|
1438
|
+
return {
|
|
1439
|
+
contents: [
|
|
1440
|
+
{
|
|
1441
|
+
uri: contractsUri,
|
|
1442
|
+
text: JSON.stringify(data.theListContracts, null, 2),
|
|
1443
|
+
mimeType: "application/json"
|
|
1444
|
+
}
|
|
1445
|
+
]
|
|
1446
|
+
};
|
|
1447
|
+
} catch (error) {
|
|
1448
|
+
return {
|
|
1449
|
+
contents: [
|
|
1450
|
+
{
|
|
1451
|
+
uri: contractsUri,
|
|
1452
|
+
text: JSON.stringify({
|
|
1453
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1454
|
+
}),
|
|
1455
|
+
mimeType: "application/json"
|
|
1456
|
+
}
|
|
1457
|
+
]
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
);
|
|
1462
|
+
server.registerResource(
|
|
1463
|
+
"theglobalfuel-inventory",
|
|
1464
|
+
inventoryUri,
|
|
1465
|
+
{
|
|
1466
|
+
title: "Theglobalfuel Inventory Lots",
|
|
1467
|
+
description: "The first 50 inventory lots in the bound workspace.",
|
|
1468
|
+
mimeType: "application/json"
|
|
1469
|
+
},
|
|
1470
|
+
async () => {
|
|
1471
|
+
ctx.logger.debug(`Resource ${inventoryUri} requested`);
|
|
1472
|
+
try {
|
|
1473
|
+
const data = await ctx.gql.workspace.request(
|
|
1474
|
+
LIST_INVENTORY_LOTS,
|
|
1475
|
+
{ pagination: { limit: 50, offset: 0 } }
|
|
1476
|
+
);
|
|
1477
|
+
return {
|
|
1478
|
+
contents: [
|
|
1479
|
+
{
|
|
1480
|
+
uri: inventoryUri,
|
|
1481
|
+
text: JSON.stringify(data.theListInventoryLots, null, 2),
|
|
1482
|
+
mimeType: "application/json"
|
|
1483
|
+
}
|
|
1484
|
+
]
|
|
1485
|
+
};
|
|
1486
|
+
} catch (error) {
|
|
1487
|
+
return {
|
|
1488
|
+
contents: [
|
|
1489
|
+
{
|
|
1490
|
+
uri: inventoryUri,
|
|
1491
|
+
text: JSON.stringify({
|
|
1492
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1493
|
+
}),
|
|
1494
|
+
mimeType: "application/json"
|
|
1495
|
+
}
|
|
1496
|
+
]
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
function registerTheglobalfuelPrompts(server, ctx, track) {
|
|
1503
|
+
const p = ctx.productName;
|
|
1504
|
+
const onboardingName = track(mcpPromptName(p, "asset-onboarding"));
|
|
1505
|
+
const opsName = track(mcpPromptName(p, "trade-ops"));
|
|
1506
|
+
server.registerPrompt(
|
|
1507
|
+
onboardingName,
|
|
1508
|
+
{
|
|
1509
|
+
title: "Asset Onboarding",
|
|
1510
|
+
description: "Guide for bringing a new resource asset online: register the asset, capture an initial production record, log a reserve estimate, and transition it into production.",
|
|
1511
|
+
argsSchema: {
|
|
1512
|
+
name: z.string().optional().describe("Asset name"),
|
|
1513
|
+
commodity: z.string().optional().describe("Commodity type")
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
({ name, commodity }) => {
|
|
1517
|
+
ctx.logger.debug(`Prompt ${onboardingName} called`, { name, commodity });
|
|
1518
|
+
const nameNote = name ? `Use the asset name "${name}".` : "Ask the user for the asset name.";
|
|
1519
|
+
const commodityNote = commodity ? `Use commodity ${commodity}.` : "Help the user pick a TheCommodityType.";
|
|
1520
|
+
return {
|
|
1521
|
+
messages: [
|
|
1522
|
+
{
|
|
1523
|
+
role: "user",
|
|
1524
|
+
content: {
|
|
1525
|
+
type: "text",
|
|
1526
|
+
text: `Help me onboard a new Theglobalfuel resource asset.
|
|
1527
|
+
|
|
1528
|
+
1. **Register Asset**: Use ${p}_assets_create. ${nameNote} ${commodityNote} Pick the asset kind (well, mine, field, plant, ...) and set capacityPerDay/capacityUnit and workingInterestPct if known.
|
|
1529
|
+
2. **Log Reserves**: Use ${p}_reserves_create with the new assetId, an asOfDate, a recoverable quantity, and a reserve category (PROVED/PROBABLE/...).
|
|
1530
|
+
3. **Capture Production**: Use ${p}_production_record for the first reporting period (periodStart, periodEnd, volume, unit).
|
|
1531
|
+
4. **Verify**: Use ${p}_assets_get to confirm the asset shows its production records and reserve estimates.
|
|
1532
|
+
5. **Go Live**: Use ${p}_assets_transition with status=DEVELOPMENT then PRODUCING when the asset is online.
|
|
1533
|
+
|
|
1534
|
+
Show results at each step and confirm before transitioning to PRODUCING.`
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
]
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
);
|
|
1541
|
+
server.registerPrompt(
|
|
1542
|
+
opsName,
|
|
1543
|
+
{
|
|
1544
|
+
title: "Trade & ESG Operations",
|
|
1545
|
+
description: "Daily operations workflow: review offtake contracts, advance shipments, reconcile inventory, and keep emissions & compliance current.",
|
|
1546
|
+
argsSchema: {
|
|
1547
|
+
contractId: z.string().optional().describe("Contract ID to operate")
|
|
1548
|
+
}
|
|
1549
|
+
},
|
|
1550
|
+
({ contractId }) => {
|
|
1551
|
+
ctx.logger.debug(`Prompt ${opsName} called`, { contractId });
|
|
1552
|
+
const contractNote = contractId ? `Operate contract "${contractId}".` : `First list contracts with ${p}_contracts_list and pick one.`;
|
|
1553
|
+
return {
|
|
1554
|
+
messages: [
|
|
1555
|
+
{
|
|
1556
|
+
role: "user",
|
|
1557
|
+
content: {
|
|
1558
|
+
type: "text",
|
|
1559
|
+
text: `Run daily Theglobalfuel trade & ESG operations. ${contractNote}
|
|
1560
|
+
|
|
1561
|
+
1. **Contracts**: Use ${p}_contracts_list (filter by status=ACTIVE) and ${p}_contracts_get to review delivered vs contracted volume.
|
|
1562
|
+
2. **Shipments**: Use ${p}_shipments_list filtered by contractId. Schedule new shipments with ${p}_shipments_schedule and mark arrivals with ${p}_shipments_deliver (this rolls volume into the contract).
|
|
1563
|
+
3. **Inventory**: Use ${p}_inventory_list to check available lots; use ${p}_inventory_set_status to RESERVED/IN_TRANSIT/CONSUMED as lots move.
|
|
1564
|
+
4. **Emissions**: Use ${p}_emissions_list for the period; record new figures with ${p}_emissions_record and mark audited ones with ${p}_emissions_verify.
|
|
1565
|
+
5. **Compliance**: Use ${p}_compliance_list to find permits/licenses near expiry; advance pending ones with ${p}_compliance_transition.
|
|
1566
|
+
|
|
1567
|
+
Summarize what needs attention after each step.`
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
]
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// src/modules/theglobalfuel/index.ts
|
|
1577
|
+
var theglobalfuelModule = {
|
|
1578
|
+
id: "theglobalfuel",
|
|
1579
|
+
version: "0.0.1",
|
|
1580
|
+
displayName: "Theglobalfuel",
|
|
1581
|
+
dependsOn: ["auth"],
|
|
1582
|
+
capabilities: { tools: {}, resources: {}, prompts: {} },
|
|
1583
|
+
register(server, ctx) {
|
|
1584
|
+
const tools = [];
|
|
1585
|
+
const resources = [];
|
|
1586
|
+
const prompts = [];
|
|
1587
|
+
const trackTool = (n) => {
|
|
1588
|
+
tools.push(n);
|
|
1589
|
+
return n;
|
|
1590
|
+
};
|
|
1591
|
+
const trackResource = (uri) => {
|
|
1592
|
+
resources.push(uri);
|
|
1593
|
+
return uri;
|
|
1594
|
+
};
|
|
1595
|
+
const trackPrompt = (n) => {
|
|
1596
|
+
prompts.push(n);
|
|
1597
|
+
return n;
|
|
1598
|
+
};
|
|
1599
|
+
registerAssetTools(server, ctx, trackTool);
|
|
1600
|
+
registerProductionTools(server, ctx, trackTool);
|
|
1601
|
+
registerReserveTools(server, ctx, trackTool);
|
|
1602
|
+
registerContractTools(server, ctx, trackTool);
|
|
1603
|
+
registerShipmentTools(server, ctx, trackTool);
|
|
1604
|
+
registerInventoryTools(server, ctx, trackTool);
|
|
1605
|
+
registerEmissionTools(server, ctx, trackTool);
|
|
1606
|
+
registerComplianceTools(server, ctx, trackTool);
|
|
1607
|
+
registerHealthTools(server, ctx, trackTool);
|
|
1608
|
+
registerTheglobalfuelResources(server, ctx, trackResource);
|
|
1609
|
+
registerTheglobalfuelPrompts(server, ctx, trackPrompt);
|
|
1610
|
+
return { tools, resources, prompts };
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
var theglobalfuel_default = theglobalfuelModule;
|
|
1614
|
+
|
|
1615
|
+
export { theglobalfuel_default as default };
|
|
1616
|
+
//# sourceMappingURL=index.js.map
|
|
1617
|
+
//# sourceMappingURL=index.js.map
|