mcp-gsheets 1.5.4 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +410 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15748,6 +15748,399 @@ async function handleInsertRows(input) {
|
|
|
15748
15748
|
}
|
|
15749
15749
|
}
|
|
15750
15750
|
|
|
15751
|
+
// src/resources/index.ts
|
|
15752
|
+
function parseResourceUri(uri) {
|
|
15753
|
+
let path;
|
|
15754
|
+
if (uri.startsWith("spreadsheet://")) {
|
|
15755
|
+
path = uri.slice("spreadsheet://".length);
|
|
15756
|
+
} else {
|
|
15757
|
+
return null;
|
|
15758
|
+
}
|
|
15759
|
+
const parts = path.split("/");
|
|
15760
|
+
if (parts.length < 2) {
|
|
15761
|
+
return null;
|
|
15762
|
+
}
|
|
15763
|
+
const spreadsheetId = parts[0];
|
|
15764
|
+
if (parts[1] === "info" && spreadsheetId) {
|
|
15765
|
+
return { type: "info", spreadsheetId };
|
|
15766
|
+
}
|
|
15767
|
+
if (parts[1] === "sheets" && spreadsheetId) {
|
|
15768
|
+
return { type: "sheets", spreadsheetId };
|
|
15769
|
+
}
|
|
15770
|
+
if (parts[1] === "sheet" && parts.length >= 3 && spreadsheetId) {
|
|
15771
|
+
const sheetName = decodeURIComponent(parts.slice(2).join("/"));
|
|
15772
|
+
if (sheetName) {
|
|
15773
|
+
return { type: "sheet-data", spreadsheetId, sheetName };
|
|
15774
|
+
}
|
|
15775
|
+
}
|
|
15776
|
+
return null;
|
|
15777
|
+
}
|
|
15778
|
+
async function readSpreadsheetInfo(spreadsheetId, uri) {
|
|
15779
|
+
try {
|
|
15780
|
+
const sheets = await getAuthenticatedClient();
|
|
15781
|
+
const response = await sheets.spreadsheets.get({
|
|
15782
|
+
spreadsheetId,
|
|
15783
|
+
fields: "spreadsheetId,properties,spreadsheetUrl"
|
|
15784
|
+
});
|
|
15785
|
+
const data = {
|
|
15786
|
+
spreadsheetId: response.data.spreadsheetId,
|
|
15787
|
+
title: response.data.properties?.title,
|
|
15788
|
+
locale: response.data.properties?.locale,
|
|
15789
|
+
timeZone: response.data.properties?.timeZone,
|
|
15790
|
+
url: response.data.spreadsheetUrl
|
|
15791
|
+
};
|
|
15792
|
+
return {
|
|
15793
|
+
contents: [
|
|
15794
|
+
{
|
|
15795
|
+
uri,
|
|
15796
|
+
mimeType: "application/json",
|
|
15797
|
+
text: JSON.stringify(data, null, 2)
|
|
15798
|
+
}
|
|
15799
|
+
]
|
|
15800
|
+
};
|
|
15801
|
+
} catch (error) {
|
|
15802
|
+
const errorResponse = handleError(error);
|
|
15803
|
+
const errorText = errorResponse.content[0]?.text ?? "Unknown error";
|
|
15804
|
+
throw new Error(errorText);
|
|
15805
|
+
}
|
|
15806
|
+
}
|
|
15807
|
+
async function readSheetList(spreadsheetId, uri) {
|
|
15808
|
+
try {
|
|
15809
|
+
const sheets = await getAuthenticatedClient();
|
|
15810
|
+
const response = await sheets.spreadsheets.get({
|
|
15811
|
+
spreadsheetId,
|
|
15812
|
+
fields: "sheets.properties"
|
|
15813
|
+
});
|
|
15814
|
+
const sheetList = response.data.sheets?.map((sheet) => ({
|
|
15815
|
+
sheetId: sheet.properties?.sheetId,
|
|
15816
|
+
title: sheet.properties?.title,
|
|
15817
|
+
index: sheet.properties?.index,
|
|
15818
|
+
sheetType: sheet.properties?.sheetType,
|
|
15819
|
+
rowCount: sheet.properties?.gridProperties?.rowCount,
|
|
15820
|
+
columnCount: sheet.properties?.gridProperties?.columnCount,
|
|
15821
|
+
frozenRowCount: sheet.properties?.gridProperties?.frozenRowCount,
|
|
15822
|
+
frozenColumnCount: sheet.properties?.gridProperties?.frozenColumnCount
|
|
15823
|
+
})) || [];
|
|
15824
|
+
return {
|
|
15825
|
+
contents: [
|
|
15826
|
+
{
|
|
15827
|
+
uri,
|
|
15828
|
+
mimeType: "application/json",
|
|
15829
|
+
text: JSON.stringify({ sheets: sheetList }, null, 2)
|
|
15830
|
+
}
|
|
15831
|
+
]
|
|
15832
|
+
};
|
|
15833
|
+
} catch (error) {
|
|
15834
|
+
const errorResponse = handleError(error);
|
|
15835
|
+
const errorText = errorResponse.content[0]?.text ?? "Unknown error";
|
|
15836
|
+
throw new Error(errorText);
|
|
15837
|
+
}
|
|
15838
|
+
}
|
|
15839
|
+
async function readSheetData(spreadsheetId, sheetName, uri) {
|
|
15840
|
+
try {
|
|
15841
|
+
const sheets = await getAuthenticatedClient();
|
|
15842
|
+
const response = await sheets.spreadsheets.values.get({
|
|
15843
|
+
spreadsheetId,
|
|
15844
|
+
range: sheetName,
|
|
15845
|
+
valueRenderOption: "FORMATTED_VALUE"
|
|
15846
|
+
});
|
|
15847
|
+
const values = response.data.values || [];
|
|
15848
|
+
const data = {
|
|
15849
|
+
range: response.data.range,
|
|
15850
|
+
majorDimension: response.data.majorDimension,
|
|
15851
|
+
values,
|
|
15852
|
+
rowCount: values.length,
|
|
15853
|
+
columnCount: values[0]?.length || 0
|
|
15854
|
+
};
|
|
15855
|
+
return {
|
|
15856
|
+
contents: [
|
|
15857
|
+
{
|
|
15858
|
+
uri,
|
|
15859
|
+
mimeType: "application/json",
|
|
15860
|
+
text: JSON.stringify(data, null, 2)
|
|
15861
|
+
}
|
|
15862
|
+
]
|
|
15863
|
+
};
|
|
15864
|
+
} catch (error) {
|
|
15865
|
+
const errorResponse = handleError(error);
|
|
15866
|
+
const errorText = errorResponse.content[0]?.text ?? "Unknown error";
|
|
15867
|
+
throw new Error(errorText);
|
|
15868
|
+
}
|
|
15869
|
+
}
|
|
15870
|
+
var resourceTemplates = [
|
|
15871
|
+
{
|
|
15872
|
+
uriTemplate: "spreadsheet://{spreadsheetId}/info",
|
|
15873
|
+
name: "Spreadsheet Info",
|
|
15874
|
+
description: "Get metadata about a Google Spreadsheet including title, locale, timezone, and URL",
|
|
15875
|
+
mimeType: "application/json"
|
|
15876
|
+
},
|
|
15877
|
+
{
|
|
15878
|
+
uriTemplate: "spreadsheet://{spreadsheetId}/sheets",
|
|
15879
|
+
name: "Sheet List",
|
|
15880
|
+
description: "List all sheets in a spreadsheet with their properties (id, title, row/column counts, frozen rows/columns)",
|
|
15881
|
+
mimeType: "application/json"
|
|
15882
|
+
},
|
|
15883
|
+
{
|
|
15884
|
+
uriTemplate: "spreadsheet://{spreadsheetId}/sheet/{sheetName}",
|
|
15885
|
+
name: "Sheet Data",
|
|
15886
|
+
description: "Get all data from a specific sheet by name",
|
|
15887
|
+
mimeType: "application/json"
|
|
15888
|
+
}
|
|
15889
|
+
];
|
|
15890
|
+
async function handleResourceRead(uri) {
|
|
15891
|
+
const parsed = parseResourceUri(uri);
|
|
15892
|
+
if (!parsed) {
|
|
15893
|
+
throw new Error(
|
|
15894
|
+
`Invalid resource URI: ${uri}. Expected format: spreadsheet://{spreadsheetId}/info, spreadsheet://{spreadsheetId}/sheets, or spreadsheet://{spreadsheetId}/sheet/{sheetName}`
|
|
15895
|
+
);
|
|
15896
|
+
}
|
|
15897
|
+
switch (parsed.type) {
|
|
15898
|
+
case "info":
|
|
15899
|
+
return readSpreadsheetInfo(parsed.spreadsheetId, uri);
|
|
15900
|
+
case "sheets":
|
|
15901
|
+
return readSheetList(parsed.spreadsheetId, uri);
|
|
15902
|
+
case "sheet-data":
|
|
15903
|
+
if (!parsed.sheetName) {
|
|
15904
|
+
throw new Error("Sheet name is required for sheet-data resource");
|
|
15905
|
+
}
|
|
15906
|
+
return readSheetData(parsed.spreadsheetId, parsed.sheetName, uri);
|
|
15907
|
+
}
|
|
15908
|
+
}
|
|
15909
|
+
|
|
15910
|
+
// src/prompts/index.ts
|
|
15911
|
+
var createTablePrompt = {
|
|
15912
|
+
name: "create-table",
|
|
15913
|
+
description: "Guide for creating a new table with headers and data in a Google Spreadsheet",
|
|
15914
|
+
arguments: [
|
|
15915
|
+
{
|
|
15916
|
+
name: "spreadsheetId",
|
|
15917
|
+
description: "The ID of the target spreadsheet (from the URL)",
|
|
15918
|
+
required: true
|
|
15919
|
+
},
|
|
15920
|
+
{
|
|
15921
|
+
name: "sheetName",
|
|
15922
|
+
description: "Name of the sheet to create the table in (default: Sheet1)",
|
|
15923
|
+
required: false
|
|
15924
|
+
},
|
|
15925
|
+
{
|
|
15926
|
+
name: "dataDescription",
|
|
15927
|
+
description: "Description of the data/table you want to create",
|
|
15928
|
+
required: true
|
|
15929
|
+
}
|
|
15930
|
+
]
|
|
15931
|
+
};
|
|
15932
|
+
function handleCreateTable(args) {
|
|
15933
|
+
const spreadsheetId = args.spreadsheetId || "{spreadsheetId}";
|
|
15934
|
+
const sheetName = args.sheetName || "Sheet1";
|
|
15935
|
+
const dataDescription = args.dataDescription || "your data";
|
|
15936
|
+
return {
|
|
15937
|
+
description: `Create a table for: ${dataDescription}`,
|
|
15938
|
+
messages: [
|
|
15939
|
+
{
|
|
15940
|
+
role: "user",
|
|
15941
|
+
content: {
|
|
15942
|
+
type: "text",
|
|
15943
|
+
text: `I want to create a table in Google Sheets.
|
|
15944
|
+
|
|
15945
|
+
Spreadsheet ID: ${spreadsheetId}
|
|
15946
|
+
Sheet: ${sheetName}
|
|
15947
|
+
Data description: ${dataDescription}
|
|
15948
|
+
|
|
15949
|
+
Please help me:
|
|
15950
|
+
1. First, check if I have access to the spreadsheet using sheets_check_access
|
|
15951
|
+
2. Define appropriate column headers based on the data description
|
|
15952
|
+
3. Create the table structure using sheets_update_values
|
|
15953
|
+
4. Optionally format the header row (bold, background color) using sheets_format_cells
|
|
15954
|
+
|
|
15955
|
+
Please proceed step by step.`
|
|
15956
|
+
}
|
|
15957
|
+
}
|
|
15958
|
+
]
|
|
15959
|
+
};
|
|
15960
|
+
}
|
|
15961
|
+
var formatReportPrompt = {
|
|
15962
|
+
name: "format-report",
|
|
15963
|
+
description: "Format existing data as a professional report with headers, borders, and styling",
|
|
15964
|
+
arguments: [
|
|
15965
|
+
{
|
|
15966
|
+
name: "spreadsheetId",
|
|
15967
|
+
description: "The ID of the spreadsheet containing the data",
|
|
15968
|
+
required: true
|
|
15969
|
+
},
|
|
15970
|
+
{
|
|
15971
|
+
name: "range",
|
|
15972
|
+
description: 'The range containing data to format (e.g., "Sheet1!A1:E20")',
|
|
15973
|
+
required: true
|
|
15974
|
+
},
|
|
15975
|
+
{
|
|
15976
|
+
name: "reportStyle",
|
|
15977
|
+
description: 'Style preference: "professional", "minimal", or "colorful"',
|
|
15978
|
+
required: false
|
|
15979
|
+
}
|
|
15980
|
+
]
|
|
15981
|
+
};
|
|
15982
|
+
function handleFormatReport(args) {
|
|
15983
|
+
const spreadsheetId = args.spreadsheetId || "{spreadsheetId}";
|
|
15984
|
+
const range = args.range || "Sheet1!A1:E20";
|
|
15985
|
+
const reportStyle = args.reportStyle || "professional";
|
|
15986
|
+
const styleGuide = {
|
|
15987
|
+
professional: "navy blue headers with white text, light gray alternating rows, thin borders",
|
|
15988
|
+
minimal: "bold headers, subtle bottom border on header row only, clean white background",
|
|
15989
|
+
colorful: "vibrant colored headers, light pastel alternating row colors, medium borders"
|
|
15990
|
+
};
|
|
15991
|
+
return {
|
|
15992
|
+
description: `Format report in ${reportStyle} style`,
|
|
15993
|
+
messages: [
|
|
15994
|
+
{
|
|
15995
|
+
role: "user",
|
|
15996
|
+
content: {
|
|
15997
|
+
type: "text",
|
|
15998
|
+
text: `I want to format my data as a ${reportStyle} report.
|
|
15999
|
+
|
|
16000
|
+
Spreadsheet ID: ${spreadsheetId}
|
|
16001
|
+
Data range: ${range}
|
|
16002
|
+
Style: ${reportStyle} - ${styleGuide[reportStyle] || styleGuide["professional"]}
|
|
16003
|
+
|
|
16004
|
+
Please help me:
|
|
16005
|
+
1. First, read the data to understand its structure using sheets_get_values
|
|
16006
|
+
2. Format the header row (first row) with appropriate styling using sheets_format_cells
|
|
16007
|
+
3. Add borders to the data range using sheets_update_borders
|
|
16008
|
+
4. Optionally auto-resize columns for better readability
|
|
16009
|
+
|
|
16010
|
+
Use the ${reportStyle} style guidelines to make the report look great.`
|
|
16011
|
+
}
|
|
16012
|
+
}
|
|
16013
|
+
]
|
|
16014
|
+
};
|
|
16015
|
+
}
|
|
16016
|
+
var summarizeDataPrompt = {
|
|
16017
|
+
name: "summarize-data",
|
|
16018
|
+
description: "Analyze spreadsheet data and provide insights or create a summary",
|
|
16019
|
+
arguments: [
|
|
16020
|
+
{
|
|
16021
|
+
name: "spreadsheetId",
|
|
16022
|
+
description: "The ID of the spreadsheet to analyze",
|
|
16023
|
+
required: true
|
|
16024
|
+
},
|
|
16025
|
+
{
|
|
16026
|
+
name: "range",
|
|
16027
|
+
description: 'The range containing data to analyze (e.g., "Sheet1!A1:F100")',
|
|
16028
|
+
required: true
|
|
16029
|
+
},
|
|
16030
|
+
{
|
|
16031
|
+
name: "analysisType",
|
|
16032
|
+
description: 'Type of analysis: "overview", "statistics", or "trends"',
|
|
16033
|
+
required: false
|
|
16034
|
+
}
|
|
16035
|
+
]
|
|
16036
|
+
};
|
|
16037
|
+
function handleSummarizeData(args) {
|
|
16038
|
+
const spreadsheetId = args.spreadsheetId || "{spreadsheetId}";
|
|
16039
|
+
const range = args.range || "Sheet1!A:Z";
|
|
16040
|
+
const analysisType = args.analysisType || "overview";
|
|
16041
|
+
return {
|
|
16042
|
+
description: `Analyze data: ${analysisType}`,
|
|
16043
|
+
messages: [
|
|
16044
|
+
{
|
|
16045
|
+
role: "user",
|
|
16046
|
+
content: {
|
|
16047
|
+
type: "text",
|
|
16048
|
+
text: `I want to analyze and summarize my spreadsheet data.
|
|
16049
|
+
|
|
16050
|
+
Spreadsheet ID: ${spreadsheetId}
|
|
16051
|
+
Data range: ${range}
|
|
16052
|
+
Analysis type: ${analysisType}
|
|
16053
|
+
|
|
16054
|
+
Please help me:
|
|
16055
|
+
1. First, get the spreadsheet metadata using sheets_get_metadata to understand the structure
|
|
16056
|
+
2. Read the data from the specified range using sheets_get_values
|
|
16057
|
+
3. Analyze the data and provide:
|
|
16058
|
+
- Overview of the data structure (columns, rows, data types)
|
|
16059
|
+
- Key statistics (counts, sums, averages where applicable)
|
|
16060
|
+
- Notable patterns or insights
|
|
16061
|
+
4. Suggest any potential improvements to the data organization
|
|
16062
|
+
|
|
16063
|
+
Focus on a ${analysisType} analysis.`
|
|
16064
|
+
}
|
|
16065
|
+
}
|
|
16066
|
+
]
|
|
16067
|
+
};
|
|
16068
|
+
}
|
|
16069
|
+
var createChartGuidePrompt = {
|
|
16070
|
+
name: "create-chart-guide",
|
|
16071
|
+
description: "Step-by-step guide to create a chart from spreadsheet data",
|
|
16072
|
+
arguments: [
|
|
16073
|
+
{
|
|
16074
|
+
name: "spreadsheetId",
|
|
16075
|
+
description: "The ID of the spreadsheet containing the data",
|
|
16076
|
+
required: true
|
|
16077
|
+
},
|
|
16078
|
+
{
|
|
16079
|
+
name: "dataRange",
|
|
16080
|
+
description: 'The range containing data for the chart (e.g., "Sheet1!A1:B10")',
|
|
16081
|
+
required: true
|
|
16082
|
+
},
|
|
16083
|
+
{
|
|
16084
|
+
name: "chartType",
|
|
16085
|
+
description: 'Preferred chart type: "COLUMN", "BAR", "LINE", "PIE", "AREA", or "SCATTER"',
|
|
16086
|
+
required: false
|
|
16087
|
+
}
|
|
16088
|
+
]
|
|
16089
|
+
};
|
|
16090
|
+
function handleCreateChartGuide(args) {
|
|
16091
|
+
const spreadsheetId = args.spreadsheetId || "{spreadsheetId}";
|
|
16092
|
+
const dataRange = args.dataRange || "Sheet1!A1:B10";
|
|
16093
|
+
const chartType = args.chartType || "COLUMN";
|
|
16094
|
+
return {
|
|
16095
|
+
description: `Create ${chartType} chart`,
|
|
16096
|
+
messages: [
|
|
16097
|
+
{
|
|
16098
|
+
role: "user",
|
|
16099
|
+
content: {
|
|
16100
|
+
type: "text",
|
|
16101
|
+
text: `I want to create a ${chartType} chart from my spreadsheet data.
|
|
16102
|
+
|
|
16103
|
+
Spreadsheet ID: ${spreadsheetId}
|
|
16104
|
+
Data range: ${dataRange}
|
|
16105
|
+
Chart type: ${chartType}
|
|
16106
|
+
|
|
16107
|
+
Please help me:
|
|
16108
|
+
1. First, read the data to understand what we're visualizing using sheets_get_values
|
|
16109
|
+
2. Get the sheet ID needed for chart creation using sheets_get_metadata
|
|
16110
|
+
3. Create the chart using sheets_create_chart with appropriate configuration:
|
|
16111
|
+
- Title based on the data
|
|
16112
|
+
- Proper axis labels
|
|
16113
|
+
- Legend if needed
|
|
16114
|
+
4. Position the chart appropriately on the sheet
|
|
16115
|
+
|
|
16116
|
+
Provide the chart configuration and create it step by step.`
|
|
16117
|
+
}
|
|
16118
|
+
}
|
|
16119
|
+
]
|
|
16120
|
+
};
|
|
16121
|
+
}
|
|
16122
|
+
var allPrompts = [
|
|
16123
|
+
createTablePrompt,
|
|
16124
|
+
formatReportPrompt,
|
|
16125
|
+
summarizeDataPrompt,
|
|
16126
|
+
createChartGuidePrompt
|
|
16127
|
+
];
|
|
16128
|
+
var promptHandlers = /* @__PURE__ */ new Map([
|
|
16129
|
+
["create-table", handleCreateTable],
|
|
16130
|
+
["format-report", handleFormatReport],
|
|
16131
|
+
["summarize-data", handleSummarizeData],
|
|
16132
|
+
["create-chart-guide", handleCreateChartGuide]
|
|
16133
|
+
]);
|
|
16134
|
+
function handleGetPrompt(name, args) {
|
|
16135
|
+
const handler = promptHandlers.get(name);
|
|
16136
|
+
if (!handler) {
|
|
16137
|
+
throw new Error(
|
|
16138
|
+
`Unknown prompt: ${name}. Available prompts: ${allPrompts.map((p) => p.name).join(", ")}`
|
|
16139
|
+
);
|
|
16140
|
+
}
|
|
16141
|
+
return handler(args || {});
|
|
16142
|
+
}
|
|
16143
|
+
|
|
15751
16144
|
// src/index.ts
|
|
15752
16145
|
if (process.env.NODE_ENV !== "production") {
|
|
15753
16146
|
try {
|
|
@@ -15832,12 +16225,13 @@ async function main() {
|
|
|
15832
16225
|
const server = new Server(
|
|
15833
16226
|
{
|
|
15834
16227
|
name: "spreadsheet",
|
|
15835
|
-
version: "1.
|
|
16228
|
+
version: "1.6.0"
|
|
15836
16229
|
},
|
|
15837
16230
|
{
|
|
15838
16231
|
capabilities: {
|
|
15839
|
-
resources: {},
|
|
15840
|
-
tools: {}
|
|
16232
|
+
resources: { listChanged: false },
|
|
16233
|
+
tools: { listChanged: false },
|
|
16234
|
+
prompts: { listChanged: false }
|
|
15841
16235
|
}
|
|
15842
16236
|
}
|
|
15843
16237
|
);
|
|
@@ -15859,11 +16253,22 @@ async function main() {
|
|
|
15859
16253
|
throw error;
|
|
15860
16254
|
}
|
|
15861
16255
|
});
|
|
16256
|
+
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
|
|
16257
|
+
return { resourceTemplates };
|
|
16258
|
+
});
|
|
15862
16259
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
15863
16260
|
return { resources: [] };
|
|
15864
16261
|
});
|
|
15865
|
-
server.setRequestHandler(ReadResourceRequestSchema, async () => {
|
|
15866
|
-
|
|
16262
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
16263
|
+
const uri = request.params.uri;
|
|
16264
|
+
return handleResourceRead(uri);
|
|
16265
|
+
});
|
|
16266
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
16267
|
+
return { prompts: allPrompts };
|
|
16268
|
+
});
|
|
16269
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
16270
|
+
const { name, arguments: args } = request.params;
|
|
16271
|
+
return handleGetPrompt(name, args);
|
|
15867
16272
|
});
|
|
15868
16273
|
const transport = new StdioServerTransport();
|
|
15869
16274
|
await server.connect(transport);
|