@softeria/ms-365-mcp-server 0.79.6 → 0.80.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/cli.js +8 -3
- package/dist/server.js +14 -12
- package/docs/deployment.md +7 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
1
|
+
import { Command, Option } from "commander";
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
@@ -33,8 +33,13 @@ program.name("ms-365-mcp-server").description("Microsoft 365 MCP Server").versio
|
|
|
33
33
|
"--auth-browser",
|
|
34
34
|
"Use browser-based interactive OAuth flow instead of device code for stdio mode. Opens system browser with localhost callback for seamless sign-in."
|
|
35
35
|
).option(
|
|
36
|
-
"--
|
|
37
|
-
"Public base URL
|
|
36
|
+
"--public-url <url>",
|
|
37
|
+
"Public base URL (e.g. https://mcp.example.com) used in browser-facing OAuth redirects when running behind a reverse proxy. Server-to-server endpoints (token, register) stay on the request host."
|
|
38
|
+
).addOption(
|
|
39
|
+
// DEPRECATED: kept only so existing deployments that set --base-url or
|
|
40
|
+
// MS365_MCP_BASE_URL do not crash at startup. Use --public-url /
|
|
41
|
+
// MS365_MCP_PUBLIC_URL instead. Hidden from --help; undocumented.
|
|
42
|
+
new Option("--base-url <url>", "deprecated: use --public-url").hideHelp()
|
|
38
43
|
);
|
|
39
44
|
function parseArgs() {
|
|
40
45
|
program.parse();
|
package/dist/server.js
CHANGED
|
@@ -147,14 +147,17 @@ class MicrosoftGraphServer {
|
|
|
147
147
|
next();
|
|
148
148
|
});
|
|
149
149
|
const oauthProvider = new MicrosoftOAuthProvider(this.authManager, this.secrets);
|
|
150
|
+
const publicUrlRaw = this.options.publicUrl || process.env.MS365_MCP_PUBLIC_URL || this.options.baseUrl || process.env.MS365_MCP_BASE_URL || null;
|
|
151
|
+
const publicBase = publicUrlRaw ? new URL(publicUrlRaw).href.replace(/\/$/, "") : null;
|
|
150
152
|
app.get("/.well-known/oauth-authorization-server", async (req, res) => {
|
|
151
153
|
const protocol = req.secure ? "https" : "http";
|
|
152
|
-
const
|
|
154
|
+
const requestOrigin = `${protocol}://${req.get("host")}`;
|
|
155
|
+
const browserBase = publicBase ?? requestOrigin;
|
|
153
156
|
const scopes = buildScopesFromEndpoints(this.options.orgMode, this.options.enabledTools);
|
|
154
157
|
const metadata = {
|
|
155
|
-
issuer:
|
|
156
|
-
authorization_endpoint: `${
|
|
157
|
-
token_endpoint: `${
|
|
158
|
+
issuer: browserBase,
|
|
159
|
+
authorization_endpoint: `${browserBase}/authorize`,
|
|
160
|
+
token_endpoint: `${requestOrigin}/token`,
|
|
158
161
|
response_types_supported: ["code"],
|
|
159
162
|
response_modes_supported: ["query"],
|
|
160
163
|
grant_types_supported: ["authorization_code", "refresh_token"],
|
|
@@ -163,20 +166,21 @@ class MicrosoftGraphServer {
|
|
|
163
166
|
scopes_supported: scopes
|
|
164
167
|
};
|
|
165
168
|
if (this.options.enableDynamicRegistration) {
|
|
166
|
-
metadata.registration_endpoint = `${
|
|
169
|
+
metadata.registration_endpoint = `${requestOrigin}/register`;
|
|
167
170
|
}
|
|
168
171
|
res.json(metadata);
|
|
169
172
|
});
|
|
170
173
|
app.get("/.well-known/oauth-protected-resource", async (req, res) => {
|
|
171
174
|
const protocol = req.secure ? "https" : "http";
|
|
172
|
-
const
|
|
175
|
+
const requestOrigin = `${protocol}://${req.get("host")}`;
|
|
176
|
+
const browserBase = publicBase ?? requestOrigin;
|
|
173
177
|
const scopes = buildScopesFromEndpoints(this.options.orgMode, this.options.enabledTools);
|
|
174
178
|
res.json({
|
|
175
|
-
resource: `${
|
|
176
|
-
authorization_servers: [
|
|
179
|
+
resource: `${requestOrigin}/mcp`,
|
|
180
|
+
authorization_servers: [browserBase],
|
|
177
181
|
scopes_supported: scopes,
|
|
178
182
|
bearer_methods_supported: ["header"],
|
|
179
|
-
resource_documentation:
|
|
183
|
+
resource_documentation: browserBase
|
|
180
184
|
});
|
|
181
185
|
});
|
|
182
186
|
if (this.options.enableDynamicRegistration) {
|
|
@@ -362,9 +366,7 @@ class MicrosoftGraphServer {
|
|
|
362
366
|
app.use(
|
|
363
367
|
mcpAuthRouter({
|
|
364
368
|
provider: oauthProvider,
|
|
365
|
-
issuerUrl: new URL(
|
|
366
|
-
this.options.baseUrl || process.env.MS365_MCP_BASE_URL || `http://localhost:${port}`
|
|
367
|
-
)
|
|
369
|
+
issuerUrl: new URL(publicBase ?? `http://localhost:${port}`)
|
|
368
370
|
})
|
|
369
371
|
);
|
|
370
372
|
app.get(
|
package/docs/deployment.md
CHANGED
|
@@ -42,7 +42,7 @@ For production, use Azure Key Vault instead of environment variables for secrets
|
|
|
42
42
|
docker run -p 3000:3000 \
|
|
43
43
|
-e MS365_MCP_KEYVAULT_URL=https://your-keyvault.vault.azure.net \
|
|
44
44
|
-e MS365_MCP_ORG_MODE=true \
|
|
45
|
-
-e
|
|
45
|
+
-e MS365_MCP_PUBLIC_URL=https://mcp.example.com \
|
|
46
46
|
ms-365-mcp-server \
|
|
47
47
|
--http 3000 --org-mode
|
|
48
48
|
```
|
|
@@ -72,7 +72,7 @@ docker run -p 3000:3000 \
|
|
|
72
72
|
--env-vars \
|
|
73
73
|
"MS365_MCP_KEYVAULT_URL=https://your-keyvault.vault.azure.net" \
|
|
74
74
|
"MS365_MCP_ORG_MODE=true" \
|
|
75
|
-
"
|
|
75
|
+
"MS365_MCP_PUBLIC_URL=https://mcp.example.com" \
|
|
76
76
|
--command "node" "dist/index.js" "--http" "3000" "--org-mode"
|
|
77
77
|
```
|
|
78
78
|
|
|
@@ -99,7 +99,7 @@ az webapp config appsettings set --name mcp-server --resource-group your-rg \
|
|
|
99
99
|
--settings \
|
|
100
100
|
MS365_MCP_KEYVAULT_URL="https://your-keyvault.vault.azure.net" \
|
|
101
101
|
MS365_MCP_ORG_MODE="true" \
|
|
102
|
-
|
|
102
|
+
MS365_MCP_PUBLIC_URL="https://mcp-server.azurewebsites.net" \
|
|
103
103
|
WEBSITES_PORT="3000"
|
|
104
104
|
|
|
105
105
|
az webapp config set --name mcp-server --resource-group your-rg \
|
|
@@ -130,17 +130,17 @@ When deploying for an organization, create a dedicated app registration instead
|
|
|
130
130
|
|
|
131
131
|
## Reverse Proxy / Custom Domain
|
|
132
132
|
|
|
133
|
-
When running behind a reverse proxy
|
|
133
|
+
When running behind a reverse proxy, set `MS365_MCP_PUBLIC_URL` so that the OAuth authorize URL handed back to the user's browser is resolvable from outside the server's network:
|
|
134
134
|
|
|
135
135
|
```bash
|
|
136
136
|
# Via environment variable
|
|
137
|
-
|
|
137
|
+
MS365_MCP_PUBLIC_URL=https://mcp.example.com
|
|
138
138
|
|
|
139
139
|
# Or via CLI flag
|
|
140
|
-
--
|
|
140
|
+
--public-url https://mcp.example.com
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
Only browser-facing fields (`issuer`, `authorization_endpoint`, `authorization_servers`) are pinned to this URL. Server-to-server endpoints (`token_endpoint`, `registration_endpoint`, `resource`) stay on the request origin, so clients that reach the server over an internal network (e.g. another container on the same Docker network) don't have to round-trip back through the public URL.
|
|
144
144
|
|
|
145
145
|
## Client Configuration
|
|
146
146
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softeria/ms-365-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|