@@ -45,7 +45,9 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
4545 }
4646
4747 if ( ! params . range ) {
48- return `https://graph.microsoft.com/v1.0/me/drive/items/${ spreadsheetId } /workbook/worksheets('Sheet1')/range(address='A1:Z1000')`
48+ // When no range is provided, first fetch the first worksheet name (to avoid hardcoding "Sheet1")
49+ // We'll read its default range after in transformResponse
50+ return `https://graph.microsoft.com/v1.0/me/drive/items/${ spreadsheetId } /workbook/worksheets?$select=name&$orderby=position&$top=1`
4951 }
5052
5153 const rangeInput = params . range . trim ( )
@@ -72,7 +74,65 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
7274 } ,
7375 } ,
7476
75- transformResponse : async ( response : Response ) => {
77+ transformResponse : async ( response : Response , params ?: MicrosoftExcelToolParams ) => {
78+ const defaultAddress = 'A1:Z1000' // Match Google Sheets default logic
79+
80+ // If we came from the worksheets listing (no range provided), resolve first sheet name then fetch range
81+ if ( response . url . includes ( '/workbook/worksheets?' ) ) {
82+ const listData = await response . json ( )
83+ const firstSheetName : string | undefined = listData ?. value ?. [ 0 ] ?. name
84+
85+ if ( ! firstSheetName ) {
86+ throw new Error ( 'No worksheets found in the Excel workbook' )
87+ }
88+
89+ const spreadsheetIdFromUrl = response . url . split ( '/drive/items/' ) [ 1 ] ?. split ( '/' ) [ 0 ] || ''
90+ const accessToken = params ?. accessToken
91+ if ( ! accessToken ) {
92+ throw new Error ( 'Access token is required to read Excel range' )
93+ }
94+
95+ const rangeUrl = `https://graph.microsoft.com/v1.0/me/drive/items/${ encodeURIComponent (
96+ spreadsheetIdFromUrl
97+ ) } /workbook/worksheets('${ encodeURIComponent ( firstSheetName ) } ')/range(address='${ defaultAddress } ')`
98+
99+ const rangeResp = await fetch ( rangeUrl , {
100+ headers : { Authorization : `Bearer ${ accessToken } ` } ,
101+ } )
102+
103+ if ( ! rangeResp . ok ) {
104+ // Normalize Microsoft Graph sheet/range errors to a friendly message
105+ throw new Error (
106+ 'Invalid range provided or worksheet not found. Provide a range like "Sheet1!A1:B2"'
107+ )
108+ }
109+
110+ const data = await rangeResp . json ( )
111+
112+ const metadata = {
113+ spreadsheetId : spreadsheetIdFromUrl ,
114+ properties : { } ,
115+ spreadsheetUrl : `https://graph.microsoft.com/v1.0/me/drive/items/${ spreadsheetIdFromUrl } ` ,
116+ }
117+
118+ const result : MicrosoftExcelReadResponse = {
119+ success : true ,
120+ output : {
121+ data : {
122+ range : data . range || `${ firstSheetName } !${ defaultAddress } ` ,
123+ values : data . values || [ ] ,
124+ } ,
125+ metadata : {
126+ spreadsheetId : metadata . spreadsheetId ,
127+ spreadsheetUrl : metadata . spreadsheetUrl ,
128+ } ,
129+ } ,
130+ }
131+
132+ return result
133+ }
134+
135+ // Normal path: caller supplied a range; just return the parsed result
76136 const data = await response . json ( )
77137
78138 const urlParts = response . url . split ( '/drive/items/' )
@@ -102,27 +162,20 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
102162 } ,
103163
104164 outputs : {
105- success : { type : 'boolean' , description : 'Operation success status' } ,
106- output : {
165+ data : {
107166 type : 'object' ,
108- description : 'Excel spreadsheet data and metadata ' ,
167+ description : 'Range data from the spreadsheet ' ,
109168 properties : {
110- data : {
111- type : 'object' ,
112- description : 'Range data from the spreadsheet' ,
113- properties : {
114- range : { type : 'string' , description : 'The range that was read' } ,
115- values : { type : 'array' , description : 'Array of rows containing cell values' } ,
116- } ,
117- } ,
118- metadata : {
119- type : 'object' ,
120- description : 'Spreadsheet metadata' ,
121- properties : {
122- spreadsheetId : { type : 'string' , description : 'The ID of the spreadsheet' } ,
123- spreadsheetUrl : { type : 'string' , description : 'URL to access the spreadsheet' } ,
124- } ,
125- } ,
169+ range : { type : 'string' , description : 'The range that was read' } ,
170+ values : { type : 'array' , description : 'Array of rows containing cell values' } ,
171+ } ,
172+ } ,
173+ metadata : {
174+ type : 'object' ,
175+ description : 'Spreadsheet metadata' ,
176+ properties : {
177+ spreadsheetId : { type : 'string' , description : 'The ID of the spreadsheet' } ,
178+ spreadsheetUrl : { type : 'string' , description : 'URL to access the spreadsheet' } ,
126179 } ,
127180 } ,
128181 } ,
0 commit comments