@visionpoint/avps-mcp 1.0.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/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +89 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +160 -0
- package/dist/index.js.map +1 -0
- package/dist/tokenCache.d.ts +8 -0
- package/dist/tokenCache.d.ts.map +1 -0
- package/dist/tokenCache.js +97 -0
- package/dist/tokenCache.js.map +1 -0
- package/package.json +37 -0
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure AD Authentication
|
|
3
|
+
* Device code flow for Claude Desktop users
|
|
4
|
+
*/
|
|
5
|
+
export interface AuthResult {
|
|
6
|
+
accessToken: string;
|
|
7
|
+
userName: string;
|
|
8
|
+
userEmail: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function authenticate(): Promise<AuthResult>;
|
|
11
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoCH,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAsDD,wBAAsB,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,CAsBxD"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Azure AD Authentication
|
|
4
|
+
* Device code flow for Claude Desktop users
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.authenticate = authenticate;
|
|
8
|
+
const msal_node_1 = require("@azure/msal-node");
|
|
9
|
+
const tokenCache_1 = require("./tokenCache");
|
|
10
|
+
// Azure AD configuration - VisionPoint tenant
|
|
11
|
+
const TENANT_ID = 'ebc2c961-da30-4f4c-8851-2caa5121086b';
|
|
12
|
+
const CLIENT_ID = '12e7db65-93ce-4a7b-93d1-77ad4e8af5fc';
|
|
13
|
+
// Scopes for authentication
|
|
14
|
+
const SCOPES = ['User.Read', 'openid', 'profile', 'offline_access'];
|
|
15
|
+
const msalConfig = {
|
|
16
|
+
auth: {
|
|
17
|
+
clientId: CLIENT_ID,
|
|
18
|
+
authority: `https://login.microsoftonline.com/${TENANT_ID}`,
|
|
19
|
+
},
|
|
20
|
+
cache: {
|
|
21
|
+
cachePlugin: tokenCache_1.tokenCachePlugin,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
let msalInstance = null;
|
|
25
|
+
async function getMsalInstance() {
|
|
26
|
+
if (!msalInstance) {
|
|
27
|
+
msalInstance = new msal_node_1.PublicClientApplication(msalConfig);
|
|
28
|
+
}
|
|
29
|
+
return msalInstance;
|
|
30
|
+
}
|
|
31
|
+
async function acquireTokenSilent(pca) {
|
|
32
|
+
const accounts = await pca.getTokenCache().getAllAccounts();
|
|
33
|
+
if (accounts.length === 0) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
return await pca.acquireTokenSilent({
|
|
38
|
+
account: accounts[0],
|
|
39
|
+
scopes: SCOPES,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function acquireTokenDeviceCode(pca) {
|
|
47
|
+
const deviceCodeRequest = {
|
|
48
|
+
scopes: SCOPES,
|
|
49
|
+
deviceCodeCallback: (response) => {
|
|
50
|
+
// Print to stderr - shows in Claude Desktop logs
|
|
51
|
+
console.error('\n========================================');
|
|
52
|
+
console.error('AVPS MCP - Authentication Required');
|
|
53
|
+
console.error('========================================');
|
|
54
|
+
console.error(response.message);
|
|
55
|
+
console.error('========================================\n');
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const result = await pca.acquireTokenByDeviceCode(deviceCodeRequest);
|
|
59
|
+
if (!result) {
|
|
60
|
+
throw new Error('Authentication failed');
|
|
61
|
+
}
|
|
62
|
+
console.error('[AVPS MCP] Authentication successful!');
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
function decodeJwtPayload(token) {
|
|
66
|
+
const parts = token.split('.');
|
|
67
|
+
if (parts.length !== 3) {
|
|
68
|
+
throw new Error('Invalid JWT');
|
|
69
|
+
}
|
|
70
|
+
return JSON.parse(Buffer.from(parts[1], 'base64').toString('utf-8'));
|
|
71
|
+
}
|
|
72
|
+
async function authenticate() {
|
|
73
|
+
const pca = await getMsalInstance();
|
|
74
|
+
let authResult = await acquireTokenSilent(pca);
|
|
75
|
+
if (!authResult) {
|
|
76
|
+
authResult = await acquireTokenDeviceCode(pca);
|
|
77
|
+
}
|
|
78
|
+
if (!authResult?.accessToken) {
|
|
79
|
+
throw new Error('Failed to acquire access token');
|
|
80
|
+
}
|
|
81
|
+
const tokenToDecode = authResult.idToken || authResult.accessToken;
|
|
82
|
+
const decoded = decodeJwtPayload(tokenToDecode);
|
|
83
|
+
return {
|
|
84
|
+
accessToken: authResult.accessToken,
|
|
85
|
+
userName: decoded.name || '',
|
|
86
|
+
userEmail: decoded.email || decoded.preferred_username || decoded.upn || '',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AVPS MCP Bridge
|
|
4
|
+
* Connects Claude Desktop (stdio) to AVPS API (HTTP)
|
|
5
|
+
*
|
|
6
|
+
* Usage via npx:
|
|
7
|
+
* npx @visionpoint/avps-mcp
|
|
8
|
+
*
|
|
9
|
+
* Claude Desktop config:
|
|
10
|
+
* {
|
|
11
|
+
* "mcpServers": {
|
|
12
|
+
* "avps": {
|
|
13
|
+
* "command": "npx",
|
|
14
|
+
* "args": ["@visionpoint/avps-mcp"]
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* Environment variables:
|
|
20
|
+
* MCP_SERVER_URL - Override API endpoint (default: production)
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* AVPS MCP Bridge
|
|
5
|
+
* Connects Claude Desktop (stdio) to AVPS API (HTTP)
|
|
6
|
+
*
|
|
7
|
+
* Usage via npx:
|
|
8
|
+
* npx @visionpoint/avps-mcp
|
|
9
|
+
*
|
|
10
|
+
* Claude Desktop config:
|
|
11
|
+
* {
|
|
12
|
+
* "mcpServers": {
|
|
13
|
+
* "avps": {
|
|
14
|
+
* "command": "npx",
|
|
15
|
+
* "args": ["@visionpoint/avps-mcp"]
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* Environment variables:
|
|
21
|
+
* MCP_SERVER_URL - Override API endpoint (default: production)
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
const readline = __importStar(require("readline"));
|
|
58
|
+
const auth_1 = require("./auth");
|
|
59
|
+
// Production API URL - override with MCP_SERVER_URL env var for local dev
|
|
60
|
+
const DEFAULT_API_URL = 'https://av-professional-services.gentleground-65cfe420.eastus2.azurecontainerapps.io';
|
|
61
|
+
const API_URL = process.env.MCP_SERVER_URL || DEFAULT_API_URL;
|
|
62
|
+
const RPC_ENDPOINT = `${API_URL}/mcp/rpc`;
|
|
63
|
+
// Authenticated user
|
|
64
|
+
let auth = null;
|
|
65
|
+
/**
|
|
66
|
+
* Log to stderr (safe for stdio transport)
|
|
67
|
+
*/
|
|
68
|
+
function log(message) {
|
|
69
|
+
console.error(`[AVPS MCP] ${message}`);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Send JSON-RPC request to the API
|
|
73
|
+
*/
|
|
74
|
+
async function sendToApi(request) {
|
|
75
|
+
if (!auth) {
|
|
76
|
+
throw new Error('Not authenticated');
|
|
77
|
+
}
|
|
78
|
+
const response = await fetch(RPC_ENDPOINT, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json',
|
|
82
|
+
Authorization: `Bearer ${auth.accessToken}`,
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify(request),
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const errorText = await response.text();
|
|
88
|
+
throw new Error(`API error ${response.status}: ${errorText}`);
|
|
89
|
+
}
|
|
90
|
+
return response.json();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Handle incoming JSON-RPC message from stdin
|
|
94
|
+
*/
|
|
95
|
+
async function handleMessage(line) {
|
|
96
|
+
let request;
|
|
97
|
+
try {
|
|
98
|
+
request = JSON.parse(line);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Invalid JSON - ignore
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const response = await sendToApi(request);
|
|
106
|
+
// Write response to stdout
|
|
107
|
+
console.log(JSON.stringify(response));
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Send error response
|
|
111
|
+
const errorResponse = {
|
|
112
|
+
jsonrpc: '2.0',
|
|
113
|
+
id: request.id,
|
|
114
|
+
error: {
|
|
115
|
+
code: -32603,
|
|
116
|
+
message: error.message,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
console.log(JSON.stringify(errorResponse));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Main entry point
|
|
124
|
+
*/
|
|
125
|
+
async function main() {
|
|
126
|
+
log('Starting AVPS MCP Bridge...');
|
|
127
|
+
log(`API: ${API_URL}`);
|
|
128
|
+
// Authenticate user
|
|
129
|
+
try {
|
|
130
|
+
auth = await (0, auth_1.authenticate)();
|
|
131
|
+
log(`Authenticated as: ${auth.userName} (${auth.userEmail})`);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
log(`Authentication failed: ${error.message}`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
// Set up stdin reader
|
|
138
|
+
const rl = readline.createInterface({
|
|
139
|
+
input: process.stdin,
|
|
140
|
+
output: process.stdout,
|
|
141
|
+
terminal: false,
|
|
142
|
+
});
|
|
143
|
+
// Process each line from stdin
|
|
144
|
+
rl.on('line', (line) => {
|
|
145
|
+
handleMessage(line).catch((error) => {
|
|
146
|
+
log(`Error handling message: ${error.message}`);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
rl.on('close', () => {
|
|
150
|
+
log('Connection closed');
|
|
151
|
+
process.exit(0);
|
|
152
|
+
});
|
|
153
|
+
log('Bridge ready - listening for MCP messages');
|
|
154
|
+
}
|
|
155
|
+
// Run
|
|
156
|
+
main().catch((error) => {
|
|
157
|
+
console.error('Fatal error:', error);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
});
|
|
160
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Cache for MSAL
|
|
3
|
+
* Persists tokens to ~/.avps-mcp/tokens.json
|
|
4
|
+
*/
|
|
5
|
+
import { ICachePlugin } from '@azure/msal-node';
|
|
6
|
+
export declare const tokenCachePlugin: ICachePlugin;
|
|
7
|
+
export declare function clearTokenCache(): void;
|
|
8
|
+
//# sourceMappingURL=tokenCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenCache.d.ts","sourceRoot":"","sources":["../src/tokenCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,YAAY,EAAqB,MAAM,kBAAkB,CAAC;AAgCnE,eAAO,MAAM,gBAAgB,EAAE,YAc9B,CAAC;AAEF,wBAAgB,eAAe,IAAI,IAAI,CAQtC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Token Cache for MSAL
|
|
4
|
+
* Persists tokens to ~/.avps-mcp/tokens.json
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.tokenCachePlugin = void 0;
|
|
41
|
+
exports.clearTokenCache = clearTokenCache;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const CACHE_DIR = path.join(os.homedir(), '.avps-mcp');
|
|
46
|
+
const CACHE_FILE = path.join(CACHE_DIR, 'tokens.json');
|
|
47
|
+
function ensureCacheDir() {
|
|
48
|
+
if (!fs.existsSync(CACHE_DIR)) {
|
|
49
|
+
fs.mkdirSync(CACHE_DIR, { mode: 0o700, recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function readCache() {
|
|
53
|
+
try {
|
|
54
|
+
ensureCacheDir();
|
|
55
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
56
|
+
return fs.readFileSync(CACHE_FILE, 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// Ignore read errors
|
|
61
|
+
}
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
function writeCache(data) {
|
|
65
|
+
try {
|
|
66
|
+
ensureCacheDir();
|
|
67
|
+
fs.writeFileSync(CACHE_FILE, data, { mode: 0o600 });
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Ignore write errors
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.tokenCachePlugin = {
|
|
74
|
+
async beforeCacheAccess(cacheContext) {
|
|
75
|
+
const cachedData = readCache();
|
|
76
|
+
if (cachedData) {
|
|
77
|
+
cacheContext.tokenCache.deserialize(cachedData);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
async afterCacheAccess(cacheContext) {
|
|
81
|
+
if (cacheContext.cacheHasChanged) {
|
|
82
|
+
const serializedCache = cacheContext.tokenCache.serialize();
|
|
83
|
+
writeCache(serializedCache);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
function clearTokenCache() {
|
|
88
|
+
try {
|
|
89
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
90
|
+
fs.unlinkSync(CACHE_FILE);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Ignore
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=tokenCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenCache.js","sourceRoot":"","sources":["../src/tokenCache.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDH,0CAQC;AA3DD,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAEvD,SAAS,cAAc;IACtB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;AACF,CAAC;AAED,SAAS,SAAS;IACjB,IAAI,CAAC;QACJ,cAAc,EAAE,CAAC;QACjB,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,qBAAqB;IACtB,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC/B,IAAI,CAAC;QACJ,cAAc,EAAE,CAAC;QACjB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,sBAAsB;IACvB,CAAC;AACF,CAAC;AAEY,QAAA,gBAAgB,GAAiB;IAC7C,KAAK,CAAC,iBAAiB,CAAC,YAA+B;QACtD,MAAM,UAAU,GAAG,SAAS,EAAE,CAAC;QAC/B,IAAI,UAAU,EAAE,CAAC;YAChB,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,YAA+B;QACrD,IAAI,YAAY,CAAC,eAAe,EAAE,CAAC;YAClC,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC5D,UAAU,CAAC,eAAe,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;CACD,CAAC;AAEF,SAAgB,eAAe;IAC9B,IAAI,CAAC;QACJ,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,SAAS;IACV,CAAC;AACF,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@visionpoint/avps-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP bridge for AV Professional Services - connects Claude Desktop to AVPS API",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"avps-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"claude",
|
|
16
|
+
"anthropic",
|
|
17
|
+
"av-professional-services"
|
|
18
|
+
],
|
|
19
|
+
"author": "VisionPoint LLC",
|
|
20
|
+
"license": "UNLICENSED",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@azure/msal-node": "^2.6.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^20.0.0",
|
|
26
|
+
"typescript": "^5.0.0"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist/**/*"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|