mcp-dataverse 0.1.7 → 0.1.9
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 +12 -4
- package/dist/auth/pac-auth-provider.d.ts +3 -4
- package/dist/auth/pac-auth-provider.d.ts.map +1 -1
- package/dist/auth/pac-auth-provider.js +60 -67
- package/dist/auth/pac-auth-provider.js.map +1 -1
- package/dist/config/config.loader.d.ts.map +1 -1
- package/dist/config/config.loader.js +27 -25
- package/dist/config/config.loader.js.map +1 -1
- package/dist/setup-auth.d.ts +1 -0
- package/dist/setup-auth.js +28 -11
- package/dist/setup-auth.js.map +1 -1
- package/package.json +3 -4
- package/server.json +4 -4
- package/.env.example +0 -15
- package/config.example.json +0 -10
package/README.md
CHANGED
|
@@ -10,18 +10,22 @@ MCP server that exposes the Microsoft Dataverse Web API as **50 AI-callable tool
|
|
|
10
10
|
|
|
11
11
|
### One-click (VS Code)
|
|
12
12
|
|
|
13
|
-
[](https://vscode.dev/redirect?
|
|
13
|
+
[](https://vscode.dev/redirect/mcp/install?name=mcp-dataverse&config=%7B%22args%22%3A%5B%22-y%22%2C%22mcp-dataverse%22%5D%2C%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22env%22%3A%7B%22DATAVERSE_ENV_URL%22%3A%22%24%7Binput%3Adataverse_env_url%7D%22%2C%22AUTH_MODE%22%3A%22%24%7Binput%3Adataverse_auth_mode%7D%22%2C%22PAC_PROFILE_NAME%22%3A%22%24%7Binput%3Adataverse_pac_profile%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22dataverse_env_url%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Dataverse%20URL%20%28e.g.%20https%3A%2F%2Fyourorg.crm.dynamics.com%29%22%7D%2C%7B%22default%22%3A%22pac%22%2C%22id%22%3A%22dataverse_auth_mode%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Auth%20mode%3A%20pac%20%28default%29%20or%20msal%22%7D%2C%7B%22default%22%3A%22default%22%2C%22id%22%3A%22dataverse_pac_profile%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22PAC%20CLI%20profile%20name%20%28default%3A%20default%29%22%7D%5D) [](https://insiders.vscode.dev/redirect/mcp/install?name=mcp-dataverse&config=%7B%22args%22%3A%5B%22-y%22%2C%22mcp-dataverse%22%5D%2C%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22env%22%3A%7B%22DATAVERSE_ENV_URL%22%3A%22%24%7Binput%3Adataverse_env_url%7D%22%2C%22AUTH_MODE%22%3A%22%24%7Binput%3Adataverse_auth_mode%7D%22%2C%22PAC_PROFILE_NAME%22%3A%22%24%7Binput%3Adataverse_pac_profile%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22dataverse_env_url%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Dataverse%20URL%20%28e.g.%20https%3A%2F%2Fyourorg.crm.dynamics.com%29%22%7D%2C%7B%22default%22%3A%22pac%22%2C%22id%22%3A%22dataverse_auth_mode%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Auth%20mode%3A%20pac%20%28default%29%20or%20msal%22%7D%2C%7B%22default%22%3A%22default%22%2C%22id%22%3A%22dataverse_pac_profile%22%2C%22password%22%3Afalse%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22PAC%20CLI%20profile%20name%20%28default%3A%20default%29%22%7D%5D)
|
|
14
|
+
|
|
15
|
+
> VS Code will prompt for your Dataverse URL, auth mode, and PAC profile during installation.
|
|
14
16
|
|
|
15
17
|
### Command line
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
20
|
# VS Code
|
|
19
|
-
code --add-mcp '{"name":"
|
|
21
|
+
code --add-mcp '{"name":"dataverse","type":"stdio","command":"npx","args":["-y","mcp-dataverse"],"env":{"DATAVERSE_ENV_URL":"https://yourorg.crm.dynamics.com","AUTH_MODE":"pac"}}'
|
|
20
22
|
|
|
21
23
|
# VS Code Insiders
|
|
22
|
-
code-insiders --add-mcp '{"name":"
|
|
24
|
+
code-insiders --add-mcp '{"name":"dataverse","type":"stdio","command":"npx","args":["-y","mcp-dataverse"],"env":{"DATAVERSE_ENV_URL":"https://yourorg.crm.dynamics.com","AUTH_MODE":"pac"}}'
|
|
23
25
|
```
|
|
24
26
|
|
|
27
|
+
> Replace `https://yourorg.crm.dynamics.com` with your actual Dataverse environment URL.
|
|
28
|
+
|
|
25
29
|
### Manual (mcp.json)
|
|
26
30
|
|
|
27
31
|
Add to your `.vscode/mcp.json` (or user settings):
|
|
@@ -32,7 +36,11 @@ Add to your `.vscode/mcp.json` (or user settings):
|
|
|
32
36
|
"dataverse": {
|
|
33
37
|
"type": "stdio",
|
|
34
38
|
"command": "npx",
|
|
35
|
-
"args": ["-y", "mcp-dataverse"]
|
|
39
|
+
"args": ["-y", "mcp-dataverse"],
|
|
40
|
+
"env": {
|
|
41
|
+
"DATAVERSE_ENV_URL": "https://yourorg.crm.dynamics.com",
|
|
42
|
+
"AUTH_MODE": "pac"
|
|
43
|
+
}
|
|
36
44
|
}
|
|
37
45
|
}
|
|
38
46
|
}
|
|
@@ -4,16 +4,15 @@ export declare class PacAuthProvider implements AuthProvider {
|
|
|
4
4
|
private readonly pca;
|
|
5
5
|
private cachedToken;
|
|
6
6
|
private tokenExpiresAt;
|
|
7
|
+
private pendingAuth;
|
|
7
8
|
constructor(environmentUrl: string);
|
|
8
9
|
getToken(): Promise<string>;
|
|
9
10
|
invalidateToken(): void;
|
|
10
11
|
isAuthenticated(): Promise<boolean>;
|
|
11
|
-
/**
|
|
12
|
-
* Interactive device code flow — call once via `npm run auth:setup`.
|
|
13
|
-
* Writes to stderr so it doesn't disturb the stdio MCP transport.
|
|
14
|
-
*/
|
|
15
12
|
setupViaDeviceCode(): Promise<void>;
|
|
16
13
|
private refreshToken;
|
|
14
|
+
private acquireSilently;
|
|
15
|
+
private runDeviceCodeFlow;
|
|
17
16
|
private cacheResult;
|
|
18
17
|
}
|
|
19
18
|
//# sourceMappingURL=pac-auth-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pac-auth-provider.d.ts","sourceRoot":"","sources":["../../src/auth/pac-auth-provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pac-auth-provider.d.ts","sourceRoot":"","sources":["../../src/auth/pac-auth-provider.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAwDjE,qBAAa,eAAgB,YAAW,YAAY;IAClD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0B;IAC9C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,WAAW,CAAgC;gBAEvC,cAAc,EAAE,MAAM;IAQ5B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAQjC,eAAe,IAAI,IAAI;IAEjB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAInC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;YAE3B,YAAY;YAsBZ,eAAe;YASf,iBAAiB;IAW/B,OAAO,CAAC,WAAW;CAIpB"}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { PublicClientApplication, } from "@azure/msal-node";
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
+
import { homedir } from "os";
|
|
3
4
|
import { join } from "path";
|
|
4
5
|
import { createCipheriv, createDecipheriv, createHash, randomBytes, } from "crypto";
|
|
5
|
-
// Microsoft Power Platform CLI App ID — public client, no app registration needed
|
|
6
6
|
const PLATFORM_CLIENT_ID = "1950a258-227b-4e31-a9cf-717495945fc2";
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Not a substitute for OS-level credential storage (DPAPI/keytar), but prevents
|
|
11
|
-
* the cache file from being directly readable as plaintext by other processes.
|
|
12
|
-
*/
|
|
7
|
+
const CACHE_DIR = join(homedir(), ".mcp-dataverse");
|
|
8
|
+
const TOKEN_CACHE_FILE = join(CACHE_DIR, "msal-cache.json");
|
|
9
|
+
const DEVICE_CODE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
13
10
|
function getDerivedKey() {
|
|
14
11
|
const seed = [
|
|
15
12
|
process.env["COMPUTERNAME"] ?? process.env["HOSTNAME"] ?? "",
|
|
@@ -22,16 +19,8 @@ function encryptForDisk(plaintext) {
|
|
|
22
19
|
const key = getDerivedKey();
|
|
23
20
|
const iv = randomBytes(16);
|
|
24
21
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
25
|
-
const encrypted = Buffer.concat([
|
|
26
|
-
|
|
27
|
-
cipher.final(),
|
|
28
|
-
]);
|
|
29
|
-
return JSON.stringify({
|
|
30
|
-
v: 1,
|
|
31
|
-
iv: iv.toString("hex"),
|
|
32
|
-
tag: cipher.getAuthTag().toString("hex"),
|
|
33
|
-
d: encrypted.toString("hex"),
|
|
34
|
-
});
|
|
22
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
23
|
+
return JSON.stringify({ v: 1, iv: iv.toString("hex"), tag: cipher.getAuthTag().toString("hex"), d: encrypted.toString("hex") });
|
|
35
24
|
}
|
|
36
25
|
function decryptFromDisk(raw) {
|
|
37
26
|
const parsed = JSON.parse(raw);
|
|
@@ -50,24 +39,21 @@ function createCachePlugin() {
|
|
|
50
39
|
if (existsSync(TOKEN_CACHE_FILE)) {
|
|
51
40
|
try {
|
|
52
41
|
const raw = readFileSync(TOKEN_CACHE_FILE, "utf-8");
|
|
53
|
-
// Support both encrypted (v1) and legacy plaintext caches
|
|
54
42
|
let serialized;
|
|
55
43
|
try {
|
|
56
44
|
serialized = decryptFromDisk(raw);
|
|
57
45
|
}
|
|
58
46
|
catch {
|
|
59
|
-
// Legacy plaintext — accept for migration, will be re-written encrypted
|
|
60
47
|
serialized = raw;
|
|
61
48
|
}
|
|
62
49
|
cacheContext.tokenCache.deserialize(serialized);
|
|
63
50
|
}
|
|
64
|
-
catch {
|
|
65
|
-
// Corrupt cache — ignore, user will need to re-authenticate
|
|
66
|
-
}
|
|
51
|
+
catch { /* corrupt cache — re-auth automatically */ }
|
|
67
52
|
}
|
|
68
53
|
},
|
|
69
54
|
afterCacheAccess: async (cacheContext) => {
|
|
70
55
|
if (cacheContext.cacheHasChanged) {
|
|
56
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
71
57
|
writeFileSync(TOKEN_CACHE_FILE, encryptForDisk(cacheContext.tokenCache.serialize()), { encoding: "utf-8", mode: 0o600 });
|
|
72
58
|
}
|
|
73
59
|
},
|
|
@@ -78,27 +64,24 @@ export class PacAuthProvider {
|
|
|
78
64
|
pca;
|
|
79
65
|
cachedToken = null;
|
|
80
66
|
tokenExpiresAt = 0;
|
|
67
|
+
pendingAuth = null;
|
|
81
68
|
constructor(environmentUrl) {
|
|
82
69
|
this.environmentUrl = environmentUrl.replace(/\/$/, "");
|
|
83
70
|
this.pca = new PublicClientApplication({
|
|
84
|
-
auth: {
|
|
85
|
-
clientId: PLATFORM_CLIENT_ID,
|
|
86
|
-
authority: "https://login.microsoftonline.com/common",
|
|
87
|
-
},
|
|
71
|
+
auth: { clientId: PLATFORM_CLIENT_ID, authority: "https://login.microsoftonline.com/common" },
|
|
88
72
|
cache: { cachePlugin: createCachePlugin() },
|
|
89
73
|
});
|
|
90
74
|
}
|
|
91
75
|
async getToken() {
|
|
92
76
|
const now = Date.now();
|
|
93
|
-
if (this.cachedToken !== null && this.tokenExpiresAt > now + 60_000)
|
|
77
|
+
if (this.cachedToken !== null && this.tokenExpiresAt > now + 60_000)
|
|
94
78
|
return this.cachedToken;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.cachedToken = null;
|
|
100
|
-
this.tokenExpiresAt = 0;
|
|
79
|
+
if (this.pendingAuth !== null)
|
|
80
|
+
return this.pendingAuth;
|
|
81
|
+
this.pendingAuth = this.refreshToken().finally(() => { this.pendingAuth = null; });
|
|
82
|
+
return this.pendingAuth;
|
|
101
83
|
}
|
|
84
|
+
invalidateToken() { this.cachedToken = null; this.tokenExpiresAt = 0; }
|
|
102
85
|
async isAuthenticated() {
|
|
103
86
|
try {
|
|
104
87
|
await this.getToken();
|
|
@@ -108,50 +91,60 @@ export class PacAuthProvider {
|
|
|
108
91
|
return false;
|
|
109
92
|
}
|
|
110
93
|
}
|
|
111
|
-
|
|
112
|
-
* Interactive device code flow — call once via `npm run auth:setup`.
|
|
113
|
-
* Writes to stderr so it doesn't disturb the stdio MCP transport.
|
|
114
|
-
*/
|
|
115
|
-
async setupViaDeviceCode() {
|
|
116
|
-
const result = await this.pca.acquireTokenByDeviceCode({
|
|
117
|
-
scopes: [`${this.environmentUrl}/.default`],
|
|
118
|
-
deviceCodeCallback: (response) => {
|
|
119
|
-
process.stderr.write(`\n${response.message}\n`);
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
if (result) {
|
|
123
|
-
this.cacheResult(result);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
94
|
+
async setupViaDeviceCode() { await this.runDeviceCodeFlow(); }
|
|
126
95
|
async refreshToken() {
|
|
127
96
|
const accounts = await this.pca.getAllAccounts();
|
|
128
97
|
if (accounts.length === 0) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
98
|
+
process.stderr.write("\n[mcp-dataverse] First-time authentication required.\n" + `Environment: ${this.environmentUrl}\n` + "Open the URL below in your browser to sign in.\n\n");
|
|
99
|
+
try {
|
|
100
|
+
await this.runDeviceCodeFlow();
|
|
101
|
+
return await this.acquireSilently();
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
105
|
+
throw new Error(`Authentication setup failed: ${detail}\n\nYou can also authenticate manually:\n npx mcp-dataverse-auth ${this.environmentUrl}\nThen restart the MCP server in VS Code.`);
|
|
106
|
+
}
|
|
132
107
|
}
|
|
133
108
|
try {
|
|
134
|
-
|
|
135
|
-
scopes: [`${this.environmentUrl}/.default`],
|
|
136
|
-
account: accounts[0],
|
|
137
|
-
});
|
|
138
|
-
if (!result?.accessToken) {
|
|
139
|
-
throw new Error("Silent token acquisition returned empty token");
|
|
140
|
-
}
|
|
141
|
-
this.cacheResult(result);
|
|
142
|
-
return result.accessToken;
|
|
109
|
+
return await this.acquireSilently();
|
|
143
110
|
}
|
|
144
111
|
catch {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
112
|
+
process.stderr.write("\n[mcp-dataverse] Session expired — re-authenticating.\nOpen the URL below in your browser to sign in again.\n\n");
|
|
113
|
+
try {
|
|
114
|
+
await this.runDeviceCodeFlow();
|
|
115
|
+
return await this.acquireSilently();
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
this.cachedToken = null;
|
|
119
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
120
|
+
throw new Error(`Re-authentication failed: ${detail}\n\nTo authenticate manually:\n npx mcp-dataverse-auth ${this.environmentUrl}\nThen restart the MCP server in VS Code.`);
|
|
121
|
+
}
|
|
149
122
|
}
|
|
150
123
|
}
|
|
124
|
+
async acquireSilently() {
|
|
125
|
+
const accounts = await this.pca.getAllAccounts();
|
|
126
|
+
if (accounts.length === 0)
|
|
127
|
+
throw new Error("No account found in cache after authentication.");
|
|
128
|
+
const result = await this.pca.acquireTokenSilent({ scopes: [`${this.environmentUrl}/.default`], account: accounts[0] });
|
|
129
|
+
if (!result?.accessToken)
|
|
130
|
+
throw new Error("Token acquisition returned an empty access token.");
|
|
131
|
+
this.cacheResult(result);
|
|
132
|
+
return result.accessToken;
|
|
133
|
+
}
|
|
134
|
+
async runDeviceCodeFlow() {
|
|
135
|
+
const result = await Promise.race([
|
|
136
|
+
this.pca.acquireTokenByDeviceCode({
|
|
137
|
+
scopes: [`${this.environmentUrl}/.default`],
|
|
138
|
+
deviceCodeCallback: (response) => { process.stderr.write(`${response.message}\n\n`); },
|
|
139
|
+
}),
|
|
140
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Authentication timed out after 5 minutes. Please try again.")), DEVICE_CODE_TIMEOUT_MS)),
|
|
141
|
+
]);
|
|
142
|
+
if (result)
|
|
143
|
+
this.cacheResult(result);
|
|
144
|
+
}
|
|
151
145
|
cacheResult(result) {
|
|
152
146
|
this.cachedToken = result.accessToken;
|
|
153
|
-
this.tokenExpiresAt =
|
|
154
|
-
result.expiresOn?.getTime() ?? Date.now() + 55 * 60 * 1000;
|
|
147
|
+
this.tokenExpiresAt = result.expiresOn?.getTime() ?? Date.now() + 55 * 60 * 1000;
|
|
155
148
|
}
|
|
156
149
|
}
|
|
157
150
|
//# sourceMappingURL=pac-auth-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pac-auth-provider.js","sourceRoot":"","sources":["../../src/auth/pac-auth-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"pac-auth-provider.js","sourceRoot":"","sources":["../../src/auth/pac-auth-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,MAAM,QAAQ,CAAC;AAGhB,MAAM,kBAAkB,GAAG,sCAAsC,CAAC;AAClE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAC5D,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7C,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG;QACX,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;QAC5D,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;QACpD,wBAAwB;KACzB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACvC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAClI,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;IAC1D,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACvE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAW,EAAE,KAAK,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAW,EAAE,KAAK,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAW,EAAE,KAAK,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;IACtE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO;QACL,iBAAiB,EAAE,KAAK,EAAE,YAA+B,EAAE,EAAE;YAC3D,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;oBACpD,IAAI,UAAkB,CAAC;oBACvB,IAAI,CAAC;wBAAC,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC;wBAAC,UAAU,GAAG,GAAG,CAAC;oBAAC,CAAC;oBACtE,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;gBAClD,CAAC;gBAAC,MAAM,CAAC,CAAC,2CAA2C,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,gBAAgB,EAAE,KAAK,EAAE,YAA+B,EAAE,EAAE;YAC1D,IAAI,YAAY,CAAC,eAAe,EAAE,CAAC;gBACjC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC1C,aAAa,CAAC,gBAAgB,EAAE,cAAc,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3H,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,eAAe;IACjB,cAAc,CAAS;IACf,GAAG,CAA0B;IACtC,WAAW,GAAkB,IAAI,CAAC;IAClC,cAAc,GAAW,CAAC,CAAC;IAC3B,WAAW,GAA2B,IAAI,CAAC;IAEnD,YAAY,cAAsB;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,GAAG,IAAI,uBAAuB,CAAC;YACrC,IAAI,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,EAAE,0CAA0C,EAAE;YAC7F,KAAK,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,IAAI,IAAI,CAAC,cAAc,GAAG,GAAG,GAAG,MAAM;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QAC7F,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,eAAe,KAAW,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;IAE7E,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC;YAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,KAAK,CAAC;QAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,kBAAkB,KAAoB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAErE,KAAK,CAAC,YAAY;QACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yDAAyD,GAAG,gBAAgB,IAAI,CAAC,cAAc,IAAI,GAAG,oDAAoD,CAAC,CAAC;YACjL,IAAI,CAAC;gBAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAAC,OAAO,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAAC,CAAC;YAC5E,OAAO,GAAG,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,qEAAqE,IAAI,CAAC,cAAc,2CAA2C,CAAC,CAAC;YAC7L,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YAAC,OAAO,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAAC,CAAC;QAC5C,MAAM,CAAC;YACL,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kHAAkH,CAAC,CAAC;YACzI,IAAI,CAAC;gBAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAAC,OAAO,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAAC,CAAC;YAC5E,OAAO,GAAG,EAAE,CAAC;gBACX,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChE,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,2DAA2D,IAAI,CAAC,cAAc,2CAA2C,CAAC,CAAC;YAChL,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;QACzH,IAAI,CAAC,MAAM,EAAE,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC/F,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC;gBAChC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,WAAW,CAAC;gBAC3C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;aACvF,CAAC;YACF,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;SAC9J,CAAC,CAAC;QACH,IAAI,MAAM;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,WAAW,CAAC,MAA4B;QAC9C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACnF,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.loader.d.ts","sourceRoot":"","sources":["../../src/config/config.loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI/D,wBAAgB,UAAU,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"config.loader.d.ts","sourceRoot":"","sources":["../../src/config/config.loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI/D,wBAAgB,UAAU,IAAI,MAAM,CAuDnC"}
|
|
@@ -15,31 +15,33 @@ export function loadConfig() {
|
|
|
15
15
|
throw new Error(`Invalid JSON in ${configPath}. Check for syntax errors (trailing commas, missing quotes).`);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
// Override with env vars if present
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
rawConfig["
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
rawConfig["
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
rawConfig["
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
rawConfig["
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
rawConfig["
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
rawConfig["
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
rawConfig["
|
|
42
|
-
|
|
18
|
+
// Override with env vars if present.
|
|
19
|
+
// Accepts both SCREAMING_SNAKE_CASE (documented, server.json) and camelCase
|
|
20
|
+
// (generated by VS Code when it reads config.example.json from the npm package).
|
|
21
|
+
const envUrl = process.env["DATAVERSE_ENV_URL"] ?? process.env["environmentUrl"];
|
|
22
|
+
if (envUrl)
|
|
23
|
+
rawConfig["environmentUrl"] = envUrl;
|
|
24
|
+
const authMode = process.env["AUTH_MODE"] ?? process.env["authMode"];
|
|
25
|
+
if (authMode)
|
|
26
|
+
rawConfig["authMode"] = authMode;
|
|
27
|
+
const pacProfile = process.env["PAC_PROFILE_NAME"] ?? process.env["pacProfileName"];
|
|
28
|
+
if (pacProfile)
|
|
29
|
+
rawConfig["pacProfileName"] = pacProfile;
|
|
30
|
+
const tenantId = process.env["TENANT_ID"] ?? process.env["tenantId"];
|
|
31
|
+
if (tenantId)
|
|
32
|
+
rawConfig["tenantId"] = tenantId;
|
|
33
|
+
const clientId = process.env["CLIENT_ID"] ?? process.env["clientId"];
|
|
34
|
+
if (clientId)
|
|
35
|
+
rawConfig["clientId"] = clientId;
|
|
36
|
+
const clientSecret = process.env["CLIENT_SECRET"] ?? process.env["clientSecret"];
|
|
37
|
+
if (clientSecret)
|
|
38
|
+
rawConfig["clientSecret"] = clientSecret;
|
|
39
|
+
const timeoutMs = process.env["REQUEST_TIMEOUT_MS"] ?? process.env["requestTimeoutMs"];
|
|
40
|
+
if (timeoutMs)
|
|
41
|
+
rawConfig["requestTimeoutMs"] = Number(timeoutMs);
|
|
42
|
+
const maxRetries = process.env["MAX_RETRIES"] ?? process.env["maxRetries"];
|
|
43
|
+
if (maxRetries)
|
|
44
|
+
rawConfig["maxRetries"] = Number(maxRetries);
|
|
43
45
|
const result = ConfigSchema.safeParse(rawConfig);
|
|
44
46
|
if (!result.success) {
|
|
45
47
|
throw new Error(`Invalid configuration:\n${result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n")}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.loader.js","sourceRoot":"","sources":["../../src/config/config.loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAE/D,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAEvC,MAAM,UAAU,UAAU;IACxB,yEAAyE;IACzE,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAE1E,IAAI,SAAS,GAA4B,EAAE,CAAC;IAE5C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA4B,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,mBAAmB,UAAU,8DAA8D,CAC5F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"config.loader.js","sourceRoot":"","sources":["../../src/config/config.loader.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-auth.d.ts
CHANGED
package/dist/setup-auth.js
CHANGED
|
@@ -1,29 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
/**
|
|
2
|
-
* Authentication setup entry point.
|
|
3
|
-
* Run once:
|
|
3
|
+
* Authentication setup entry point for production installs.
|
|
4
|
+
* Run once: npx mcp-dataverse-auth [environment-url]
|
|
4
5
|
*
|
|
5
6
|
* Uses MSAL device code flow — a browser tab will open for you to authenticate.
|
|
6
|
-
* The token is cached
|
|
7
|
+
* The token is cached in ~/.mcp-dataverse/msal-cache.json and reused silently.
|
|
7
8
|
*/
|
|
8
9
|
import { loadConfig } from "./config/config.loader.js";
|
|
9
10
|
import { PacAuthProvider } from "./auth/pac-auth-provider.js";
|
|
10
11
|
async function main() {
|
|
11
|
-
process.stderr.write("MCP Dataverse — Authentication Setup\n");
|
|
12
|
-
process.stderr.write("
|
|
13
|
-
|
|
12
|
+
process.stderr.write("MCP Dataverse — One-time Authentication Setup\n");
|
|
13
|
+
process.stderr.write("──────────────────────────────────────────────\n");
|
|
14
|
+
// Allow passing the env URL as a CLI arg: npx mcp-dataverse-auth https://org.crm.dynamics.com
|
|
15
|
+
const cliEnvUrl = process.argv[2];
|
|
16
|
+
if (cliEnvUrl) {
|
|
17
|
+
process.env["DATAVERSE_ENV_URL"] = cliEnvUrl;
|
|
18
|
+
}
|
|
19
|
+
let config;
|
|
20
|
+
try {
|
|
21
|
+
config = loadConfig();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
process.stderr.write("Environment URL is required.\n" +
|
|
25
|
+
"Usage: npx mcp-dataverse-auth https://yourorg.crm.dynamics.com\n" +
|
|
26
|
+
"Or set DATAVERSE_ENV_URL before running.\n");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
14
29
|
if (config.authMode !== "pac") {
|
|
15
30
|
process.stderr.write(`Auth mode is "${config.authMode}" — setup only needed for "pac" mode.\n`);
|
|
16
31
|
process.exit(0);
|
|
17
32
|
}
|
|
18
|
-
process.stderr.write(`Environment: ${config.environmentUrl}\n
|
|
19
|
-
process.stderr.write(
|
|
33
|
+
process.stderr.write(`Environment : ${config.environmentUrl}\n`);
|
|
34
|
+
process.stderr.write(`Token cache : ~/.mcp-dataverse/msal-cache.json\n\n`);
|
|
35
|
+
process.stderr.write("A browser window will open. Sign in with your Microsoft account.\n\n");
|
|
20
36
|
const provider = new PacAuthProvider(config.environmentUrl);
|
|
21
37
|
await provider.setupViaDeviceCode();
|
|
22
|
-
process.stderr.write("\n✓ Authentication successful
|
|
23
|
-
|
|
38
|
+
process.stderr.write("\n✓ Authentication successful!\n" +
|
|
39
|
+
" Token cached in ~/.mcp-dataverse/msal-cache.json\n\n" +
|
|
40
|
+
" Restart the MCP server in VS Code to apply.\n");
|
|
24
41
|
}
|
|
25
42
|
main().catch((error) => {
|
|
26
|
-
process.stderr.write(
|
|
43
|
+
process.stderr.write(`\nSetup failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
27
44
|
process.exit(1);
|
|
28
45
|
});
|
|
29
46
|
//# sourceMappingURL=setup-auth.js.map
|
package/dist/setup-auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-auth.js","sourceRoot":"","sources":["../src/setup-auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup-auth.js","sourceRoot":"","sources":["../src/setup-auth.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAEzE,8FAA8F;IAC9F,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,SAAS,CAAC;IAC/C,CAAC;IAED,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gCAAgC;YAC9B,kEAAkE;YAClE,4CAA4C,CAC/C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iBAAiB,MAAM,CAAC,QAAQ,yCAAyC,CAC1E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC;IACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oDAAoD,CACrD,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAE7F,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC5D,MAAM,QAAQ,CAAC,kBAAkB,EAAE,CAAC;IAEpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kCAAkC;QAChC,wDAAwD;QACxD,iDAAiD,CACpD,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC9E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-dataverse",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "MCP Server for Microsoft Dataverse Web API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"mcp-dataverse": "dist/server.js"
|
|
8
|
+
"mcp-dataverse": "dist/server.js",
|
|
9
|
+
"mcp-dataverse-auth": "dist/setup-auth.js"
|
|
9
10
|
},
|
|
10
11
|
"mcpName": "io.github.codeurali/dataverse",
|
|
11
12
|
"license": "MIT",
|
|
@@ -26,8 +27,6 @@
|
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"dist/**",
|
|
29
|
-
"config.example.json",
|
|
30
|
-
".env.example",
|
|
31
30
|
"README.md",
|
|
32
31
|
"LICENSE",
|
|
33
32
|
"CAPABILITIES.md",
|
package/server.json
CHANGED
|
@@ -15,14 +15,12 @@
|
|
|
15
15
|
"url": "https://github.com/codeurali/mcp-dataverse",
|
|
16
16
|
"source": "github"
|
|
17
17
|
},
|
|
18
|
-
"version": "0.1.
|
|
19
|
-
"packages": [
|
|
18
|
+
"version": "0.1.9",
|
|
20
19
|
{
|
|
21
20
|
"registryType": "npm",
|
|
22
21
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
23
22
|
"identifier": "mcp-dataverse",
|
|
24
|
-
"version": "0.1.
|
|
25
|
-
"transport": {
|
|
23
|
+
"version": "0.1.9", {
|
|
26
24
|
"type": "stdio"
|
|
27
25
|
},
|
|
28
26
|
"environmentVariables": [
|
|
@@ -83,3 +81,5 @@
|
|
|
83
81
|
}
|
|
84
82
|
]
|
|
85
83
|
}
|
|
84
|
+
|
|
85
|
+
|
package/.env.example
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# MCP Dataverse Configuration
|
|
2
|
-
# Set these environment variables (or use config.json for local dev)
|
|
3
|
-
|
|
4
|
-
DATAVERSE_ENV_URL=https://yourorg.crm.dynamics.com
|
|
5
|
-
AUTH_MODE=pac
|
|
6
|
-
PAC_PROFILE_NAME=default
|
|
7
|
-
|
|
8
|
-
# MSAL client credentials (required if AUTH_MODE=msal)
|
|
9
|
-
TENANT_ID=
|
|
10
|
-
CLIENT_ID=
|
|
11
|
-
CLIENT_SECRET=
|
|
12
|
-
|
|
13
|
-
# Tuning (optional)
|
|
14
|
-
# REQUEST_TIMEOUT_MS=30000
|
|
15
|
-
# MAX_RETRIES=3
|