@softeria/ms-365-mcp-server 0.2.2 → 0.3.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/README.md +111 -155
- package/bin/download-openapi.mjs +49 -0
- package/bin/release.mjs +0 -1
- package/index.mjs +2 -2
- package/package.json +6 -2
- package/src/auth-tools.mjs +48 -35
- package/src/auth.mjs +1 -1
- package/src/cli.mjs +1 -2
- package/src/dynamic-tools.mjs +231 -0
- package/src/openapi-helpers.mjs +187 -0
- package/src/param-mapper.mjs +30 -0
- package/src/server.mjs +2 -8
- package/test/auth-tools.test.js +94 -0
- package/test/dynamic-tools.test.js +852 -0
- package/test/openapi-helpers.test.js +210 -0
- package/test/param-mapper.test.js +56 -0
- package/src/calendar-tools.mjs +0 -814
- package/src/excel-tools.mjs +0 -317
- package/src/files-tools.mjs +0 -554
- package/src/mail-tools.mjs +0 -159
package/README.md
CHANGED
|
@@ -4,26 +4,16 @@ Microsoft 365 MCP Server
|
|
|
4
4
|
|
|
5
5
|
A Model Context Protocol (MCP) server for interacting with Microsoft 365 services through the Graph API.
|
|
6
6
|
|
|
7
|
-
[](https://github.com/softeria-eu/ms-365-mcp-server/actions/workflows/build.yml)
|
|
8
7
|
[](https://www.npmjs.com/package/@softeria/ms-365-mcp-server)
|
|
9
8
|
|
|
10
|
-
## Quick Start Example
|
|
11
|
-
|
|
12
|
-
Login and test authentication in Claude Desktop:
|
|
13
|
-
|
|
14
|
-

|
|
15
|
-
|
|
16
9
|
## Features
|
|
17
10
|
|
|
18
11
|
- Authentication using Microsoft Authentication Library (MSAL)
|
|
19
|
-
- Excel file operations
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Create tables
|
|
25
|
-
- Read cell values
|
|
26
|
-
- List worksheets
|
|
12
|
+
- Excel file operations
|
|
13
|
+
- Calendar event management
|
|
14
|
+
- Mail operations
|
|
15
|
+
- OneDrive file management
|
|
16
|
+
- Dynamic tools powered by Microsoft Graph OpenAPI specification
|
|
27
17
|
- Built on the Model Context Protocol
|
|
28
18
|
|
|
29
19
|
## Installation
|
|
@@ -32,6 +22,17 @@ Login and test authentication in Claude Desktop:
|
|
|
32
22
|
npx @softeria/ms-365-mcp-server
|
|
33
23
|
```
|
|
34
24
|
|
|
25
|
+
## Quick Start Example
|
|
26
|
+
|
|
27
|
+
Login and test authentication in Claude Desktop:
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
|
|
35
36
|
## Integration with Claude
|
|
36
37
|
|
|
37
38
|
### Claude Desktop
|
|
@@ -42,9 +43,9 @@ To add this MCP server to Claude Desktop:
|
|
|
42
43
|
2. Go to Settings > MCPs
|
|
43
44
|
3. Click "Add MCP"
|
|
44
45
|
4. Set the following configuration:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
- Name: `ms365` (or any name you prefer)
|
|
47
|
+
- Command: `npx @softeria/ms-365-mcp-server`
|
|
48
|
+
- Click "Add"
|
|
48
49
|
|
|
49
50
|
Alternatively, you can edit Claude Desktop's configuration file directly. The location varies by platform, but you can
|
|
50
51
|
find it by going to Settings > Developer > Edit Config. Add this to your configuration file:
|
|
@@ -52,12 +53,9 @@ find it by going to Settings > Developer > Edit Config. Add this to your configu
|
|
|
52
53
|
```json
|
|
53
54
|
{
|
|
54
55
|
"mcpServers": {
|
|
55
|
-
"
|
|
56
|
+
"ms365": {
|
|
56
57
|
"command": "npx",
|
|
57
|
-
"args": [
|
|
58
|
-
"-y",
|
|
59
|
-
"@softeria/ms-365-mcp-server"
|
|
60
|
-
]
|
|
58
|
+
"args": ["-y", "@softeria/ms-365-mcp-server"]
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
}
|
|
@@ -65,60 +63,14 @@ find it by going to Settings > Developer > Edit Config. Add this to your configu
|
|
|
65
63
|
|
|
66
64
|
### Using Claude Code CLI
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
to the [official Claude Code documentation](https://github.com/anthropics/claude-code) for the most up-to-date
|
|
70
|
-
instructions on adding MCP servers.
|
|
71
|
-
|
|
72
|
-
For other Claude interfaces that support MCPs, please refer to their respective documentation for the correct
|
|
73
|
-
integration method.
|
|
74
|
-
|
|
75
|
-
## Development
|
|
76
|
-
|
|
77
|
-
### Setup
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Clone the repository
|
|
81
|
-
git clone https://github.com/softeria-eu/ms-365-mcp-server.git
|
|
82
|
-
cd ms-365-mcp-server
|
|
83
|
-
|
|
84
|
-
# Install dependencies
|
|
85
|
-
npm install
|
|
86
|
-
|
|
87
|
-
# Run tests
|
|
88
|
-
npm test
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### GitHub Actions
|
|
92
|
-
|
|
93
|
-
This repository uses GitHub Actions for continuous integration and deployment:
|
|
94
|
-
|
|
95
|
-
- **Build Workflow**: Runs on all pushes to main and pull requests. Verifies the project builds successfully and passes
|
|
96
|
-
all tests.
|
|
97
|
-
- **Publish Workflow**: Automatically publishes to npm when a new GitHub release is created.
|
|
98
|
-
|
|
99
|
-
### Release Process
|
|
100
|
-
|
|
101
|
-
To create a new release:
|
|
66
|
+
You can add the server to Claude Code CLI using this command:
|
|
102
67
|
|
|
103
68
|
```bash
|
|
104
|
-
|
|
105
|
-
npm run release
|
|
106
|
-
|
|
107
|
-
# Minor version: 0.1.11 -> 0.2.0
|
|
108
|
-
npm run release minor
|
|
109
|
-
|
|
110
|
-
# Major version: 0.1.11 -> 1.0.0
|
|
111
|
-
npm run release major
|
|
69
|
+
claude mcp add ms365 -- npx -y @softeria/ms-365-mcp-server
|
|
112
70
|
```
|
|
113
71
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
1. Run tests to verify everything works
|
|
117
|
-
2. Bump the version number according to the specified type (patch by default)
|
|
118
|
-
3. Commit the version changes
|
|
119
|
-
4. Push to GitHub
|
|
120
|
-
5. Create a GitHub release
|
|
121
|
-
6. Trigger the publishing workflow to publish to npm
|
|
72
|
+
For other Claude interfaces that support MCPs, please refer to their respective documentation for the correct
|
|
73
|
+
integration method.
|
|
122
74
|
|
|
123
75
|
## Usage
|
|
124
76
|
|
|
@@ -132,7 +84,7 @@ Options:
|
|
|
132
84
|
|
|
133
85
|
- `--login`: Force login using device code flow and verify Graph API access
|
|
134
86
|
- `--logout`: Log out and clear saved credentials
|
|
135
|
-
- `--
|
|
87
|
+
- `--verify-login`: Test current authentication and verify Graph API access without starting the server
|
|
136
88
|
- `-v`: Enable verbose logging
|
|
137
89
|
|
|
138
90
|
### Authentication
|
|
@@ -140,29 +92,33 @@ Options:
|
|
|
140
92
|
**Important:** You must authenticate before using the MCP server. There are two ways to authenticate:
|
|
141
93
|
|
|
142
94
|
1. Running the server with the `--login` flag:
|
|
95
|
+
|
|
143
96
|
```bash
|
|
144
97
|
npx @softeria/ms-365-mcp-server --login
|
|
145
98
|
```
|
|
99
|
+
|
|
146
100
|
This will display the login URL and code in the terminal.
|
|
147
101
|
|
|
148
102
|
2. When using Claude Code or other MCP clients, use the login tools:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
103
|
+
- First use the `login` tool, which will automatically check if you're already logged in
|
|
104
|
+
- If not already logged in, it will return the login URL and code
|
|
105
|
+
- Visit the URL and enter the code in your browser
|
|
106
|
+
- Then use the `verify-login` tool to check if the login was successful
|
|
107
|
+
- To force a new login even if already authenticated, use the `login` tool with `force: true`
|
|
152
108
|
|
|
153
109
|
Both methods trigger the device code flow authentication, but they handle the UI interaction differently:
|
|
154
110
|
|
|
155
111
|
- CLI version displays the instructions directly in the terminal
|
|
156
112
|
- MCP tool version returns the instructions as data that can be shown in the client UI
|
|
157
113
|
|
|
158
|
-
You can verify your authentication status with the `--
|
|
114
|
+
You can verify your authentication status with the `--verify-login` flag, which will check if your token can successfully
|
|
159
115
|
fetch user data from Microsoft Graph API:
|
|
160
116
|
|
|
161
117
|
```bash
|
|
162
|
-
npx @softeria/ms-365-mcp-server --
|
|
118
|
+
npx @softeria/ms-365-mcp-server --verify-login
|
|
163
119
|
```
|
|
164
120
|
|
|
165
|
-
Both `--login` and `--
|
|
121
|
+
Both `--login` and `--verify-login` will return a JSON response that includes your basic user information from Microsoft
|
|
166
122
|
Graph API if authentication is successful:
|
|
167
123
|
|
|
168
124
|
```json
|
|
@@ -180,78 +136,78 @@ Authentication tokens are cached securely in your system's credential store with
|
|
|
180
136
|
|
|
181
137
|
### MCP Tools
|
|
182
138
|
|
|
183
|
-
This server provides several MCP tools for interacting with Microsoft 365 services:
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
190
|
-
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
139
|
+
This server provides several MCP tools for interacting with Microsoft 365 services, including:
|
|
140
|
+
|
|
141
|
+
- Authentication (login, logout)
|
|
142
|
+
- Files/OneDrive management
|
|
143
|
+
- Excel operations:
|
|
144
|
+
- List worksheets
|
|
145
|
+
- Get cell range values
|
|
146
|
+
- Format cell ranges
|
|
147
|
+
- Sort data
|
|
148
|
+
- Create charts
|
|
149
|
+
- Calendar management
|
|
150
|
+
- Mail operations
|
|
151
|
+
|
|
152
|
+
For a complete list of available tools and their parameters, use an MCP-enabled Claude interface and explore the available tools.
|
|
153
|
+
|
|
154
|
+
## For Developers
|
|
155
|
+
|
|
156
|
+
### Setup
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Clone the repository
|
|
160
|
+
git clone https://github.com/softeria-eu/ms-365-mcp-server.git
|
|
161
|
+
cd ms-365-mcp-server
|
|
162
|
+
|
|
163
|
+
# Install dependencies
|
|
164
|
+
npm install
|
|
165
|
+
|
|
166
|
+
# Run tests
|
|
167
|
+
npm test
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### OpenAPI Integration
|
|
171
|
+
|
|
172
|
+
This project uses the Microsoft Graph OpenAPI specification to dynamically generate MCP tools. During installation, the OpenAPI specification is automatically downloaded from Microsoft Graph's GitHub repository.
|
|
173
|
+
|
|
174
|
+
To manually download the latest OpenAPI spec:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Download the latest OpenAPI spec from Microsoft Graph
|
|
178
|
+
npm run download-openapi
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### GitHub Actions
|
|
182
|
+
|
|
183
|
+
This repository uses GitHub Actions for continuous integration and deployment:
|
|
184
|
+
|
|
185
|
+
- **Build Workflow**: Runs on all pushes to main and pull requests. Verifies the project builds successfully and passes
|
|
186
|
+
all tests.
|
|
187
|
+
- **Publish Workflow**: Automatically publishes to npm when a new GitHub release is created.
|
|
188
|
+
|
|
189
|
+
[](https://github.com/softeria-eu/ms-365-mcp-server/actions/workflows/build.yml)
|
|
190
|
+
|
|
191
|
+
### Release Process
|
|
192
|
+
|
|
193
|
+
To create a new release:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Default (patch version): 0.1.11 -> 0.1.12
|
|
197
|
+
npm run release
|
|
198
|
+
|
|
199
|
+
# Minor version: 0.1.11 -> 0.2.0
|
|
200
|
+
npm run release minor
|
|
201
|
+
|
|
202
|
+
# Major version: 0.1.11 -> 1.0.0
|
|
203
|
+
npm run release major
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
This script will:
|
|
207
|
+
|
|
208
|
+
1. Run tests to verify everything works
|
|
209
|
+
2. Bump the version number according to the specified type (patch by default)
|
|
210
|
+
3. Commit the version changes
|
|
211
|
+
4. Push to GitHub
|
|
212
|
+
5. Create a GitHub release
|
|
213
|
+
6. Trigger the publishing workflow to publish to npm
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const forceDownload = args.includes('--force');
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const targetDir = path.resolve(__dirname, '..', 'openapi');
|
|
14
|
+
const targetFile = path.join(targetDir, 'openapi.yaml');
|
|
15
|
+
|
|
16
|
+
const openapiUrl =
|
|
17
|
+
'https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/refs/heads/master/openapi/v1.0/openapi.yaml';
|
|
18
|
+
|
|
19
|
+
async function downloadOpenApi() {
|
|
20
|
+
if (!fs.existsSync(targetDir)) {
|
|
21
|
+
console.log(`Creating directory: ${targetDir}`);
|
|
22
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (fs.existsSync(targetFile) && !forceDownload) {
|
|
26
|
+
console.log(`OpenAPI specification already exists at ${targetFile}`);
|
|
27
|
+
console.log('Use --force to download again');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`Downloading OpenAPI specification from ${openapiUrl}`);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const response = await fetch(openapiUrl);
|
|
35
|
+
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`Failed to download: ${response.status} ${response.statusText}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const content = await response.text();
|
|
41
|
+
fs.writeFileSync(targetFile, content);
|
|
42
|
+
console.log(`OpenAPI specification downloaded to ${targetFile}`);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('Error downloading OpenAPI specification:', error.message);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
downloadOpenApi();
|
package/bin/release.mjs
CHANGED
package/index.mjs
CHANGED
|
@@ -21,8 +21,8 @@ async function main() {
|
|
|
21
21
|
process.exit(0);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
if (args.
|
|
25
|
-
logger.info('
|
|
24
|
+
if (args.verifyLogin) {
|
|
25
|
+
logger.info('Verifying login...');
|
|
26
26
|
const result = await authManager.testLogin();
|
|
27
27
|
console.log(JSON.stringify(result));
|
|
28
28
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softeria/ms-365-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Microsoft 365 MCP Server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.mjs",
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"test:watch": "vitest",
|
|
13
13
|
"start": "node index.mjs",
|
|
14
14
|
"format": "prettier --write \"**/*.{js,mjs,json,md}\"",
|
|
15
|
-
"release": "node bin/release.mjs"
|
|
15
|
+
"release": "node bin/release.mjs",
|
|
16
|
+
"download-openapi": "node bin/download-openapi.mjs",
|
|
17
|
+
"inspect": "npx @modelcontextprotocol/inspector node index.mjs",
|
|
18
|
+
"postinstall": "npm run download-openapi"
|
|
16
19
|
},
|
|
17
20
|
"keywords": [
|
|
18
21
|
"microsoft",
|
|
@@ -29,6 +32,7 @@
|
|
|
29
32
|
"@azure/msal-node": "^2.1.0",
|
|
30
33
|
"@modelcontextprotocol/sdk": "^1.8.0",
|
|
31
34
|
"commander": "^11.1.0",
|
|
35
|
+
"js-yaml": "^4.1.0",
|
|
32
36
|
"keytar": "^7.9.0",
|
|
33
37
|
"winston": "^3.17.0",
|
|
34
38
|
"zod": "^3.24.2"
|
package/src/auth-tools.mjs
CHANGED
|
@@ -1,28 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
export function registerAuthTools(server, authManager) {
|
|
2
|
-
server.tool(
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
4
|
+
server.tool(
|
|
5
|
+
'login',
|
|
6
|
+
{
|
|
7
|
+
force: z.boolean().default(false).describe('Force a new login even if already logged in'),
|
|
8
|
+
},
|
|
9
|
+
async ({ force }) => {
|
|
10
|
+
try {
|
|
11
|
+
if (!force) {
|
|
12
|
+
const loginStatus = await authManager.testLogin();
|
|
13
|
+
if (loginStatus.success) {
|
|
14
|
+
return {
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: 'text',
|
|
18
|
+
text: JSON.stringify({
|
|
19
|
+
message: 'Already logged in',
|
|
20
|
+
...loginStatus,
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const text = await new Promise((r) => {
|
|
29
|
+
authManager.acquireTokenByDeviceCode(r);
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
content: [
|
|
33
|
+
{
|
|
34
|
+
type: 'text',
|
|
35
|
+
text,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: 'text',
|
|
44
|
+
text: JSON.stringify({ error: `Authentication failed: ${error.message}` }),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
24
49
|
}
|
|
25
|
-
|
|
50
|
+
);
|
|
26
51
|
|
|
27
52
|
server.tool('logout', {}, async () => {
|
|
28
53
|
try {
|
|
@@ -47,18 +72,6 @@ export function registerAuthTools(server, authManager) {
|
|
|
47
72
|
}
|
|
48
73
|
});
|
|
49
74
|
|
|
50
|
-
server.tool('test-login', {}, async () => {
|
|
51
|
-
const result = await authManager.testLogin();
|
|
52
|
-
return {
|
|
53
|
-
content: [
|
|
54
|
-
{
|
|
55
|
-
type: 'text',
|
|
56
|
-
text: JSON.stringify(result),
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
|
|
62
75
|
server.tool('verify-login', {}, async () => {
|
|
63
76
|
const testResult = await authManager.testLogin();
|
|
64
77
|
|
package/src/auth.mjs
CHANGED
|
@@ -108,7 +108,7 @@ class AuthManager {
|
|
|
108
108
|
deviceCodeCallback: (response) => {
|
|
109
109
|
const text = ['\n', response.message, '\n'].join('');
|
|
110
110
|
if (hack) {
|
|
111
|
-
hack(text + 'After login run the "
|
|
111
|
+
hack(text + 'After login run the "verify login" command');
|
|
112
112
|
} else {
|
|
113
113
|
console.log(text);
|
|
114
114
|
}
|
package/src/cli.mjs
CHANGED
|
@@ -17,8 +17,7 @@ program
|
|
|
17
17
|
.option('-v', 'Enable verbose logging')
|
|
18
18
|
.option('--login', 'Login using device code flow')
|
|
19
19
|
.option('--logout', 'Log out and clear saved credentials')
|
|
20
|
-
.option('--
|
|
21
|
-
.option('--file <path>', 'Specify Excel file path');
|
|
20
|
+
.option('--verify-login', 'Verify login without starting the server');
|
|
22
21
|
|
|
23
22
|
export function parseArgs() {
|
|
24
23
|
program.parse();
|