@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 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
- [![Build Status](https://github.com/softeria-eu/ms-365-mcp-server/actions/workflows/build.yml/badge.svg)](https://github.com/softeria-eu/ms-365-mcp-server/actions/workflows/build.yml)
8
7
  [![npm version](https://img.shields.io/npm/v/@softeria/ms-365-mcp-server.svg)](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
- ![MS 365 MCP Server login example in Claude Desktop](https://github.com/user-attachments/assets/936d16bc-b3e1-437b-b3f1-03c54874a816)
15
-
16
9
  ## Features
17
10
 
18
11
  - Authentication using Microsoft Authentication Library (MSAL)
19
- - Excel file operations:
20
- - Update cell values
21
- - Create and manage charts
22
- - Format cells
23
- - Sort data
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
+ ![MS 365 MCP Server login example in Claude Desktop](https://github.com/user-attachments/assets/936d16bc-b3e1-437b-b3f1-03c54874a816)
30
+
31
+ ## Examples
32
+
33
+ ![Image](https://github.com/user-attachments/assets/1a296afb-48ed-42b0-9e7c-e685d5d1784c)
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
- - Name: `ms` (or any name you prefer)
46
- - Command: `npx @softeria/ms-365-mcp-server`
47
- - Click "Add"
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
- "ms": {
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
- Claude Code CLI integration is available but configuration methods may vary based on the current version. Please refer
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
- # Default (patch version): 0.1.11 -> 0.1.12
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
- This script will:
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
- - `--test-login`: Test current authentication and verify Graph API access without starting the server
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
- - First use the `login` tool, which will return the login URL and code
150
- - Visit the URL and enter the code in your browser
151
- - Then use the `verify-login` tool to check if the login was successful
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 `--test-login` flag, which will check if your token can successfully
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 --test-login
118
+ npx @softeria/ms-365-mcp-server --verify-login
163
119
  ```
164
120
 
165
- Both `--login` and `--test-login` will return a JSON response that includes your basic user information from Microsoft
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
- #### Authentication Tools
186
-
187
- - `login`: Start a new login process with Microsoft (returns login URL and code)
188
- - `verify-login`: Check if login was completed successfully and verify Graph API access
189
- - `logout`: Log out of Microsoft and clear credentials
190
- - `test-login`: Test current authentication status and verify Graph API access
191
-
192
- #### Files/OneDrive Tools
193
-
194
- - `list-files`: List files and folders in a specified path
195
- - `get-file`: Get details of a specific file
196
- - `create-folder`: Create a new folder
197
- - `delete-item`: Delete a file or folder
198
- - `copy-item`: Copy a file or folder to a new location
199
- - `move-item`: Move a file or folder to a new location
200
- - `rename-item`: Rename a file or folder
201
- - `search-files`: Search for files matching a query
202
- - `get-shared-items`: Get a list of items shared with you
203
- - `create-sharing-link`: Create a sharing link for a file or folder
204
- - `get-file-content`: Get the content of a file
205
-
206
- #### Excel Tools
207
-
208
- All Excel tools require a `filePath` parameter to specify which Excel file to operate on. You can use the Files tools to
209
- find and manage your Excel files.
210
-
211
- - `update-excel`: Update cell values in an Excel worksheet
212
- - `create-chart`: Create a chart in an Excel worksheet
213
- - `format-range`: Apply formatting to a range of cells
214
- - `sort-range`: Sort a range of cells
215
- - `create-table`: Create a table from a range of cells
216
- - `get-range`: Get values from a range of cells
217
- - `list-worksheets`: List all worksheets in the workbook
218
- - `close-session`: Close the session for a specific Excel file
219
- - `close-all-sessions`: Close all active Excel sessions
220
- - `delete-chart`: Delete a chart from a worksheet
221
- - `get-charts`: Get all charts in a worksheet
222
-
223
- Example workflow:
224
-
225
- 1. Use `list-files` to find Excel files in your OneDrive
226
- 2. Use `list-worksheets` with the file path to see available worksheets
227
- 3. Use `get-range` to retrieve data from the Excel file
228
- 4. Use other Excel tools to manipulate the file as needed
229
-
230
- #### Calendar Tools
231
-
232
- Tools for working with Outlook calendars.
233
-
234
- - `list-calendars`: List all calendars
235
- - `get-default-calendar`: Get information about the default calendar
236
- - `list-events`: List events from a calendar with optional filtering, sorting, and date ranges
237
- - `get-detailed-events`: Get events with expanded properties and options to include body, attendees, extensions, etc.
238
- - `get-event`: Get detailed information about a specific calendar event
239
- - `create-event`: Create a new calendar event with comprehensive options (sensitivity, importance, free/busy status,
240
- optional attendees, reminders, online meetings, categories)
241
- - `create-recurring-event`: Create recurring events (daily, weekly, monthly, yearly) with the same comprehensive options
242
- and flexible recurrence patterns
243
- - `update-event`: Update an existing calendar event
244
- - `delete-event`: Delete a calendar event
245
- - `accept-event`: Accept a calendar meeting invitation
246
- - `decline-event`: Decline a calendar meeting invitation
247
- - `tentatively-accept-event`: Tentatively accept a calendar meeting invitation
248
- - `find-meeting-times`: Find available meeting times for a set of attendees
249
- - `get-schedules`: Get availability information for multiple users or resource rooms
250
-
251
- #### Mail Tools
252
-
253
- Tools for working with Outlook email.
254
-
255
- - `list-messages`: List emails from any mail folder with powerful filtering, searching, and sorting options
256
- - `get-message`: Get detailed information about a specific email message with options to include attachments and other
257
- metadata
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
+ [![Build Status](https://github.com/softeria-eu/ms-365-mcp-server/actions/workflows/build.yml/badge.svg)](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
@@ -67,4 +67,3 @@ execSync(`gh release create v${version} --title 'v${version}' --notes 'Version $
67
67
  });
68
68
 
69
69
  console.log(`Release v${version} created successfully!`);
70
- // GitHub Actions workflow will handle the npm publish automatically
package/index.mjs CHANGED
@@ -21,8 +21,8 @@ async function main() {
21
21
  process.exit(0);
22
22
  }
23
23
 
24
- if (args.testLogin) {
25
- logger.info('Testing login...');
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.2.2",
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"
@@ -1,28 +1,53 @@
1
+ import { z } from 'zod';
2
+
1
3
  export function registerAuthTools(server, authManager) {
2
- server.tool('login', {}, async () => {
3
- try {
4
- const text = await new Promise((r) => {
5
- authManager.acquireTokenByDeviceCode(r);
6
- });
7
- return {
8
- content: [
9
- {
10
- type: 'text',
11
- text,
12
- },
13
- ],
14
- };
15
- } catch (error) {
16
- return {
17
- content: [
18
- {
19
- type: 'text',
20
- text: JSON.stringify({ error: `Authentication failed: ${error.message}` }),
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 "test login" command');
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('--test-login', 'Test login without starting the server')
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();