agent-spreadsheet-sdk 0.12.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.
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @typedef {object} BackendCapabilities
3
+ * @property {boolean} supportsDescribeWorkbook
4
+ * @property {boolean} supportsNamedRanges
5
+ * @property {boolean} supportsNamedRangeMutations
6
+ * @property {boolean} supportsSheetOverview
7
+ * @property {boolean} supportsListSheets
8
+ * @property {boolean} supportsRangeValues
9
+ * @property {boolean} supportsFindValue
10
+ * @property {boolean} supportsReadTable
11
+ * @property {boolean} supportsSheetPage
12
+ * @property {boolean} supportsGridExport
13
+ * @property {boolean} supportsTransformBatch
14
+ * @property {boolean} supportsStructureBatch
15
+ * @property {boolean} supportsReplaceInFormulas
16
+ * @property {boolean} supportsVerification
17
+ * @property {boolean} supportsForkLifecycle
18
+ * @property {boolean} supportsStaging
19
+ * @property {boolean} supportsSessionLifecycle
20
+ * @property {boolean} supportsExportWorkbook
21
+ */
22
+
23
+ /** @type {Readonly<BackendCapabilities>} */
24
+ const MCP_CAPABILITIES = Object.freeze({
25
+ supportsDescribeWorkbook: true,
26
+ supportsNamedRanges: true,
27
+ supportsNamedRangeMutations: true,
28
+ supportsSheetOverview: true,
29
+ supportsListSheets: true,
30
+ supportsRangeValues: true,
31
+ supportsFindValue: true,
32
+ supportsReadTable: true,
33
+ supportsSheetPage: true,
34
+ supportsGridExport: true,
35
+ supportsTransformBatch: true,
36
+ supportsStructureBatch: true,
37
+ supportsReplaceInFormulas: true,
38
+ supportsVerification: true,
39
+ supportsForkLifecycle: true,
40
+ supportsStaging: true,
41
+ supportsSessionLifecycle: false,
42
+ supportsExportWorkbook: false
43
+ })
44
+
45
+ /** @type {Readonly<BackendCapabilities>} */
46
+ const WASM_CAPABILITIES = Object.freeze({
47
+ supportsDescribeWorkbook: true,
48
+ supportsNamedRanges: true,
49
+ supportsNamedRangeMutations: true,
50
+ supportsSheetOverview: true,
51
+ supportsListSheets: true,
52
+ supportsRangeValues: true,
53
+ supportsFindValue: true,
54
+ supportsReadTable: true,
55
+ supportsSheetPage: true,
56
+ supportsGridExport: true,
57
+ supportsTransformBatch: true,
58
+ supportsStructureBatch: false,
59
+ supportsReplaceInFormulas: false,
60
+ supportsVerification: false,
61
+ supportsForkLifecycle: false,
62
+ supportsStaging: false,
63
+ supportsSessionLifecycle: true,
64
+ supportsExportWorkbook: true
65
+ })
66
+
67
+ /**
68
+ * @param {Readonly<BackendCapabilities>} capabilities
69
+ * @returns {Readonly<BackendCapabilities>}
70
+ */
71
+ function freezeCapabilities(capabilities) {
72
+ return Object.freeze({ ...capabilities })
73
+ }
74
+
75
+ module.exports = {
76
+ MCP_CAPABILITIES,
77
+ WASM_CAPABILITIES,
78
+ freezeCapabilities
79
+ }
package/src/errors.js ADDED
@@ -0,0 +1,103 @@
1
+ class SpreadsheetSdkError extends Error {
2
+ /**
3
+ * @param {string} message
4
+ * @param {{
5
+ * code?: string,
6
+ * backend?: string,
7
+ * operation?: string,
8
+ * capability?: string,
9
+ * details?: Record<string, unknown>,
10
+ * cause?: unknown
11
+ * }} [options]
12
+ */
13
+ constructor(message, options = {}) {
14
+ super(message)
15
+ this.name = "SpreadsheetSdkError"
16
+ this.code = options.code || "SDK_ERROR"
17
+ this.backend = options.backend
18
+ this.operation = options.operation
19
+ this.capability = options.capability
20
+ this.details = options.details || {}
21
+
22
+ if (options.cause !== undefined) {
23
+ this.cause = options.cause
24
+ }
25
+ }
26
+ }
27
+
28
+ class CapabilityError extends SpreadsheetSdkError {
29
+ /**
30
+ * @param {{ backend: string, capability: string, method?: string }} params
31
+ */
32
+ constructor(params) {
33
+ super(
34
+ `${params.backend} backend does not support capability '${params.capability}'`,
35
+ {
36
+ code: "UNSUPPORTED_CAPABILITY",
37
+ backend: params.backend,
38
+ operation: params.method,
39
+ capability: params.capability,
40
+ details: { method: params.method }
41
+ }
42
+ )
43
+ this.name = "CapabilityError"
44
+ }
45
+ }
46
+
47
+ class BackendOperationError extends SpreadsheetSdkError {
48
+ /**
49
+ * @param {string} message
50
+ * @param {{ backend: string, operation: string, cause?: unknown, code?: string }} params
51
+ */
52
+ constructor(message, params) {
53
+ super(message, {
54
+ code: params.code || "BACKEND_OPERATION_FAILED",
55
+ backend: params.backend,
56
+ operation: params.operation,
57
+ cause: params.cause
58
+ })
59
+ this.name = "BackendOperationError"
60
+ }
61
+ }
62
+
63
+ /**
64
+ * @param {unknown} error
65
+ * @param {{ backend: string, operation: string }} params
66
+ */
67
+ function normalizeBackendError(error, params) {
68
+ if (error instanceof SpreadsheetSdkError) {
69
+ return error
70
+ }
71
+
72
+ if (error && typeof error === "object") {
73
+ const code = typeof error.code === "string" ? error.code : "BACKEND_OPERATION_FAILED"
74
+ const message = typeof error.message === "string" ? error.message : "backend operation failed"
75
+ return new BackendOperationError(message, {
76
+ code,
77
+ backend: params.backend,
78
+ operation: params.operation,
79
+ cause: error
80
+ })
81
+ }
82
+
83
+ if (error instanceof Error) {
84
+ return new BackendOperationError(error.message, {
85
+ backend: params.backend,
86
+ operation: params.operation,
87
+ cause: error
88
+ })
89
+ }
90
+
91
+ return new BackendOperationError("backend operation failed", {
92
+ backend: params.backend,
93
+ operation: params.operation,
94
+ cause: error
95
+ })
96
+ }
97
+
98
+ module.exports = {
99
+ SpreadsheetSdkError,
100
+ CapabilityError,
101
+ BackendOperationError,
102
+ normalizeBackendError
103
+ }
package/src/index.js ADDED
@@ -0,0 +1,21 @@
1
+ const { MCP_CAPABILITIES, WASM_CAPABILITIES, freezeCapabilities } = require("./capabilities")
2
+ const {
3
+ SpreadsheetSdkError,
4
+ CapabilityError,
5
+ BackendOperationError,
6
+ normalizeBackendError
7
+ } = require("./errors")
8
+ const { McpBackend } = require("./mcp-backend")
9
+ const { WasmBackend } = require("./wasm-backend")
10
+
11
+ module.exports = {
12
+ McpBackend,
13
+ WasmBackend,
14
+ MCP_CAPABILITIES,
15
+ WASM_CAPABILITIES,
16
+ freezeCapabilities,
17
+ SpreadsheetSdkError,
18
+ CapabilityError,
19
+ BackendOperationError,
20
+ normalizeBackendError
21
+ }
@@ -0,0 +1,497 @@
1
+ const { freezeCapabilities, MCP_CAPABILITIES } = require("./capabilities")
2
+ const {
3
+ requireCapability,
4
+ requiredString,
5
+ normalizeSheetPageResult,
6
+ normalizeGridExportResult,
7
+ normalizeTransformBatchResult,
8
+ normalizeStructureBatchResult,
9
+ normalizeReplaceInFormulasResult,
10
+ normalizeVerifyWorkbookResult,
11
+ normalizeDescribeWorkbookResult,
12
+ normalizeNamedRangesResult,
13
+ normalizeSheetOverviewResult,
14
+ normalizeFindValueResult,
15
+ normalizeReadTableResult
16
+ } = require("./backend")
17
+ const { SpreadsheetSdkError, normalizeBackendError } = require("./errors")
18
+
19
+ function normalizeSheetNames(items) {
20
+ return items.map((item) => {
21
+ if (typeof item === "string") {
22
+ return item
23
+ }
24
+ if (item && typeof item === "object" && typeof item.name === "string") {
25
+ return item.name
26
+ }
27
+ throw new SpreadsheetSdkError("invalid sheet summary in list_sheets response", {
28
+ code: "INVALID_RESPONSE",
29
+ backend: "mcp",
30
+ operation: "list_sheets"
31
+ })
32
+ })
33
+ }
34
+
35
+ function normalizeListSheetsResult(result) {
36
+ if (Array.isArray(result)) {
37
+ return normalizeSheetNames(result)
38
+ }
39
+ if (result && typeof result === "object") {
40
+ if (Array.isArray(result.sheets)) {
41
+ return normalizeSheetNames(result.sheets)
42
+ }
43
+ if (Array.isArray(result.sheet_names)) {
44
+ return normalizeSheetNames(result.sheet_names)
45
+ }
46
+ }
47
+ throw new SpreadsheetSdkError("invalid list_sheets response", {
48
+ code: "INVALID_RESPONSE",
49
+ backend: "mcp",
50
+ operation: "list_sheets"
51
+ })
52
+ }
53
+
54
+ function normalizeRangeValuesResult(result, fallbackSheetName) {
55
+ if (!result || typeof result !== "object") {
56
+ throw new SpreadsheetSdkError("invalid range_values response", {
57
+ code: "INVALID_RESPONSE",
58
+ backend: "mcp",
59
+ operation: "range_values"
60
+ })
61
+ }
62
+
63
+ const sheetName = typeof result.sheetName === "string"
64
+ ? result.sheetName
65
+ : typeof result.sheet_name === "string"
66
+ ? result.sheet_name
67
+ : fallbackSheetName
68
+
69
+ const values = Array.isArray(result.values) ? result.values : []
70
+ return { sheetName, values }
71
+ }
72
+
73
+ class McpBackend {
74
+ /**
75
+ * @param {{
76
+ * transport: { invoke?: (operation: string, params?: Record<string, unknown>) => unknown, [k: string]: unknown },
77
+ * capabilities?: import("./capabilities").BackendCapabilities
78
+ * }} params
79
+ */
80
+ constructor(params) {
81
+ if (!params || !params.transport || typeof params.transport !== "object") {
82
+ throw new SpreadsheetSdkError("McpBackend requires a transport object", {
83
+ code: "INVALID_ARGUMENT",
84
+ backend: "mcp"
85
+ })
86
+ }
87
+
88
+ this.kind = "mcp"
89
+ this._transport = params.transport
90
+ this._capabilities = freezeCapabilities(params.capabilities || MCP_CAPABILITIES)
91
+ }
92
+
93
+ getCapabilities() {
94
+ return this._capabilities
95
+ }
96
+
97
+ async describeWorkbook(input = {}) {
98
+ requireCapability(this, "supportsDescribeWorkbook", "describeWorkbook")
99
+ const workbookId = requiredString(
100
+ input.workbookId || input.workbook_id || input.contextId,
101
+ "workbookId"
102
+ )
103
+ const result = await this._call("describe_workbook", {
104
+ ...input,
105
+ workbook_id: workbookId
106
+ })
107
+ return normalizeDescribeWorkbookResult(result, workbookId)
108
+ }
109
+
110
+ async namedRanges(input = {}) {
111
+ requireCapability(this, "supportsNamedRanges", "namedRanges")
112
+ const workbookId = requiredString(
113
+ input.workbookId || input.workbook_id || input.contextId,
114
+ "workbookId"
115
+ )
116
+ const result = await this._call("named_ranges", {
117
+ ...input,
118
+ workbook_id: workbookId
119
+ })
120
+ return normalizeNamedRangesResult(result, workbookId)
121
+ }
122
+
123
+ async verifyWorkbook(input = {}) {
124
+ requireCapability(this, "supportsVerification", "verifyWorkbook")
125
+ const baselineWorkbookOrForkId = requiredString(
126
+ input.baselineWorkbookOrForkId || input.baseline_workbook_or_fork_id || input.baselineId || input.baseline_id,
127
+ "baselineWorkbookOrForkId"
128
+ )
129
+ const currentWorkbookOrForkId = requiredString(
130
+ input.currentWorkbookOrForkId || input.current_workbook_or_fork_id || input.currentId || input.current_id,
131
+ "currentWorkbookOrForkId"
132
+ )
133
+ const result = await this._call("verify_workbook", {
134
+ baseline_workbook_or_fork_id: baselineWorkbookOrForkId,
135
+ current_workbook_or_fork_id: currentWorkbookOrForkId,
136
+ targets: Array.isArray(input.targets) ? input.targets : [],
137
+ sheet_name: input.sheetName || input.sheet_name,
138
+ include_named_range_deltas: Boolean(input.includeNamedRangeDeltas || input.include_named_range_deltas),
139
+ errors_only: Boolean(input.errorsOnly || input.errors_only),
140
+ targets_only: Boolean(input.targetsOnly || input.targets_only)
141
+ })
142
+ return normalizeVerifyWorkbookResult(result, baselineWorkbookOrForkId, currentWorkbookOrForkId)
143
+ }
144
+
145
+ async verifyTargets(input = {}) {
146
+ return this.verifyWorkbook({
147
+ ...input,
148
+ targetsOnly: true,
149
+ targets_only: true
150
+ })
151
+ }
152
+
153
+ async verifyErrors(input = {}) {
154
+ return this.verifyWorkbook({
155
+ ...input,
156
+ errorsOnly: true,
157
+ errors_only: true
158
+ })
159
+ }
160
+
161
+ async defineName(input = {}) {
162
+ requireCapability(this, "supportsNamedRangeMutations", "defineName")
163
+ const forkId = requiredString(
164
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
165
+ "forkId"
166
+ )
167
+ const name = requiredString(input.name, "name")
168
+ const refersTo = requiredString(input.refersTo || input.refers_to, "refersTo")
169
+ return this._call("define_name", {
170
+ fork_id: forkId,
171
+ name,
172
+ refers_to: refersTo,
173
+ scope: input.scope,
174
+ scope_sheet_name: input.scope_sheet_name ?? input.scopeSheetName
175
+ })
176
+ }
177
+
178
+ async updateName(input = {}) {
179
+ requireCapability(this, "supportsNamedRangeMutations", "updateName")
180
+ const forkId = requiredString(
181
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
182
+ "forkId"
183
+ )
184
+ const name = requiredString(input.name, "name")
185
+ return this._call("update_name", {
186
+ fork_id: forkId,
187
+ name,
188
+ refers_to: input.refersTo ?? input.refers_to,
189
+ scope: input.scope,
190
+ scope_sheet_name: input.scope_sheet_name ?? input.scopeSheetName
191
+ })
192
+ }
193
+
194
+ async deleteName(input = {}) {
195
+ requireCapability(this, "supportsNamedRangeMutations", "deleteName")
196
+ const forkId = requiredString(
197
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
198
+ "forkId"
199
+ )
200
+ const name = requiredString(input.name, "name")
201
+ return this._call("delete_name", {
202
+ fork_id: forkId,
203
+ name,
204
+ scope: input.scope,
205
+ scope_sheet_name: input.scope_sheet_name ?? input.scopeSheetName
206
+ })
207
+ }
208
+
209
+ async sheetOverview(input = {}) {
210
+ requireCapability(this, "supportsSheetOverview", "sheetOverview")
211
+ const workbookId = requiredString(
212
+ input.workbookId || input.workbook_id || input.contextId,
213
+ "workbookId"
214
+ )
215
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
216
+ const result = await this._call("sheet_overview", {
217
+ ...input,
218
+ workbook_id: workbookId,
219
+ sheet_name: sheetName,
220
+ max_regions: input.max_regions ?? input.maxRegions,
221
+ max_headers: input.max_headers ?? input.maxHeaders,
222
+ include_headers: input.include_headers ?? input.includeHeaders
223
+ })
224
+
225
+ return normalizeSheetOverviewResult(result, sheetName, workbookId)
226
+ }
227
+
228
+ async listSheets(input = {}) {
229
+ requireCapability(this, "supportsListSheets", "listSheets")
230
+ const workbookId = requiredString(
231
+ input.workbookId || input.workbook_id || input.contextId,
232
+ "workbookId"
233
+ )
234
+ const result = await this._call("list_sheets", {
235
+ ...input,
236
+ workbook_id: workbookId
237
+ })
238
+ return normalizeListSheetsResult(result)
239
+ }
240
+
241
+ async rangeValues(input = {}) {
242
+ requireCapability(this, "supportsRangeValues", "rangeValues")
243
+ const workbookId = requiredString(
244
+ input.workbookId || input.workbook_id || input.contextId,
245
+ "workbookId"
246
+ )
247
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
248
+ const ranges = input.ranges
249
+
250
+ const result = await this._call("range_values", {
251
+ ...input,
252
+ workbook_id: workbookId,
253
+ sheet_name: sheetName,
254
+ ranges
255
+ })
256
+ return normalizeRangeValuesResult(result, sheetName)
257
+ }
258
+
259
+ async findValue(input = {}) {
260
+ requireCapability(this, "supportsFindValue", "findValue")
261
+ const workbookId = requiredString(
262
+ input.workbookId || input.workbook_id || input.contextId,
263
+ "workbookId"
264
+ )
265
+ const query = requiredString(input.query, "query")
266
+
267
+ const result = await this._call("find_value", {
268
+ ...input,
269
+ workbook_id: workbookId,
270
+ query,
271
+ sheet_name: input.sheet_name ?? input.sheetName,
272
+ case_sensitive: input.case_sensitive ?? input.caseSensitive,
273
+ limit: input.limit,
274
+ offset: input.offset
275
+ })
276
+
277
+ return normalizeFindValueResult(result, workbookId)
278
+ }
279
+
280
+ async readTable(input = {}) {
281
+ requireCapability(this, "supportsReadTable", "readTable")
282
+ const workbookId = requiredString(
283
+ input.workbookId || input.workbook_id || input.contextId,
284
+ "workbookId"
285
+ )
286
+
287
+ const result = await this._call("read_table", {
288
+ ...input,
289
+ workbook_id: workbookId,
290
+ sheet_name: input.sheet_name ?? input.sheetName,
291
+ include_headers: input.include_headers ?? input.includeHeaders,
292
+ include_types: input.include_types ?? input.includeTypes
293
+ })
294
+
295
+ return normalizeReadTableResult(result, workbookId, input.sheetName || input.sheet_name)
296
+ }
297
+
298
+ async sheetPage(input = {}) {
299
+ requireCapability(this, "supportsSheetPage", "sheetPage")
300
+ const workbookId = requiredString(
301
+ input.workbookId || input.workbook_id || input.contextId,
302
+ "workbookId"
303
+ )
304
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
305
+
306
+ const result = await this._call("sheet_page", {
307
+ ...input,
308
+ workbook_id: workbookId,
309
+ sheet_name: sheetName,
310
+ start_row: input.start_row ?? input.startRow,
311
+ page_size: input.page_size ?? input.pageSize,
312
+ columns: input.columns,
313
+ format: input.format,
314
+ columns_by_header: input.columns_by_header ?? input.columnsByHeader,
315
+ include_formulas: input.include_formulas ?? input.includeFormulas,
316
+ include_styles: input.include_styles ?? input.includeStyles,
317
+ include_header: input.include_header ?? input.includeHeader
318
+ })
319
+
320
+ return normalizeSheetPageResult(result, sheetName)
321
+ }
322
+
323
+ async gridExport(input = {}) {
324
+ requireCapability(this, "supportsGridExport", "gridExport")
325
+ const workbookId = requiredString(
326
+ input.workbookId || input.workbook_id || input.contextId,
327
+ "workbookId"
328
+ )
329
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
330
+
331
+ const result = await this._call("grid_export", {
332
+ ...input,
333
+ workbook_id: workbookId,
334
+ sheet_name: sheetName,
335
+ range: input.range
336
+ })
337
+
338
+ return normalizeGridExportResult(result)
339
+ }
340
+
341
+ async transformBatch(input = {}) {
342
+ requireCapability(this, "supportsTransformBatch", "transformBatch")
343
+ const forkId = requiredString(
344
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
345
+ "forkId"
346
+ )
347
+ const result = await this._call("transform_batch", {
348
+ ...input,
349
+ fork_id: forkId,
350
+ ops: input.ops,
351
+ mode: input.options?.dryRun ? "preview" : (input.mode ?? "apply")
352
+ })
353
+
354
+ return normalizeTransformBatchResult(result)
355
+ }
356
+
357
+ async structureBatch(input = {}) {
358
+ requireCapability(this, "supportsStructureBatch", "structureBatch")
359
+ const forkId = requiredString(
360
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
361
+ "forkId"
362
+ )
363
+ const result = await this._call("structure_batch", {
364
+ ...input,
365
+ fork_id: forkId,
366
+ ops: input.ops,
367
+ mode: input.mode ?? "apply",
368
+ impact_report: input.impactReport ?? input.impact_report,
369
+ show_formula_delta: input.showFormulaDelta ?? input.show_formula_delta
370
+ })
371
+
372
+ return normalizeStructureBatchResult(result)
373
+ }
374
+
375
+ async replaceInFormulas(input = {}) {
376
+ requireCapability(this, "supportsReplaceInFormulas", "replaceInFormulas")
377
+ const forkId = requiredString(
378
+ input.forkId || input.fork_id || input.workbookId || input.workbook_id || input.contextId,
379
+ "forkId"
380
+ )
381
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
382
+ const find = requiredString(input.find, "find")
383
+
384
+ const result = await this._call("replace_in_formulas", {
385
+ fork_id: forkId,
386
+ sheet_name: sheetName,
387
+ find,
388
+ replace: input.replace ?? "",
389
+ range: input.range,
390
+ regex: input.regex ?? false,
391
+ case_sensitive: input.caseSensitive ?? input.case_sensitive ?? true,
392
+ mode: input.options?.dryRun ? "preview" : (input.mode ?? "apply"),
393
+ label: input.label,
394
+ formula_parse_policy: input.formulaParsePolicy ?? input.formula_parse_policy
395
+ })
396
+
397
+ return normalizeReplaceInFormulasResult(result)
398
+ }
399
+
400
+ async createFork(input = {}) {
401
+ requireCapability(this, "supportsForkLifecycle", "createFork")
402
+ const workbookOrForkId = requiredString(
403
+ input.workbookOrForkId || input.workbook_or_fork_id || input.workbookId || input.workbook_id,
404
+ "workbookOrForkId"
405
+ )
406
+
407
+ return this._call("create_fork", {
408
+ ...input,
409
+ workbook_or_fork_id: workbookOrForkId
410
+ })
411
+ }
412
+
413
+ async listForks(input = {}) {
414
+ requireCapability(this, "supportsForkLifecycle", "listForks")
415
+ return this._call("list_forks", input)
416
+ }
417
+
418
+ async saveFork(input = {}) {
419
+ requireCapability(this, "supportsForkLifecycle", "saveFork")
420
+ return this._call("save_fork", input)
421
+ }
422
+
423
+ async discardFork(input = {}) {
424
+ requireCapability(this, "supportsForkLifecycle", "discardFork")
425
+ return this._call("discard_fork", input)
426
+ }
427
+
428
+ async listStagedChanges(input = {}) {
429
+ requireCapability(this, "supportsStaging", "listStagedChanges")
430
+ return this._call("list_staged_changes", input)
431
+ }
432
+
433
+ async applyStagedChange(input = {}) {
434
+ requireCapability(this, "supportsStaging", "applyStagedChange")
435
+ return this._call("apply_staged_change", input)
436
+ }
437
+
438
+ async discardStagedChange(input = {}) {
439
+ requireCapability(this, "supportsStaging", "discardStagedChange")
440
+ return this._call("discard_staged_change", input)
441
+ }
442
+
443
+ async createSession() {
444
+ requireCapability(this, "supportsSessionLifecycle", "createSession")
445
+ throw new SpreadsheetSdkError("createSession is not implemented for MCP backend", {
446
+ code: "UNSUPPORTED",
447
+ backend: this.kind,
448
+ operation: "createSession"
449
+ })
450
+ }
451
+
452
+ async exportWorkbook() {
453
+ requireCapability(this, "supportsExportWorkbook", "exportWorkbook")
454
+ throw new SpreadsheetSdkError("exportWorkbook is not implemented for MCP backend", {
455
+ code: "UNSUPPORTED",
456
+ backend: this.kind,
457
+ operation: "exportWorkbook"
458
+ })
459
+ }
460
+
461
+ async disposeSession() {
462
+ requireCapability(this, "supportsSessionLifecycle", "disposeSession")
463
+ throw new SpreadsheetSdkError("disposeSession is not implemented for MCP backend", {
464
+ code: "UNSUPPORTED",
465
+ backend: this.kind,
466
+ operation: "disposeSession"
467
+ })
468
+ }
469
+
470
+ async _call(operation, params) {
471
+ try {
472
+ if (typeof this._transport[operation] === "function") {
473
+ return await this._transport[operation](params)
474
+ }
475
+ if (typeof this._transport.invoke === "function") {
476
+ return await this._transport.invoke(operation, params)
477
+ }
478
+ throw new SpreadsheetSdkError(
479
+ `mcp transport does not implement '${operation}' or invoke()`,
480
+ {
481
+ code: "INVALID_ARGUMENT",
482
+ backend: this.kind,
483
+ operation
484
+ }
485
+ )
486
+ } catch (error) {
487
+ throw normalizeBackendError(error, {
488
+ backend: this.kind,
489
+ operation
490
+ })
491
+ }
492
+ }
493
+ }
494
+
495
+ module.exports = {
496
+ McpBackend
497
+ }