zion-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/LICENSE +21 -0
- package/bin/zion-mcp.js +6 -0
- package/dist/auth/credential-store.d.ts +30 -0
- package/dist/auth/credential-store.d.ts.map +1 -0
- package/dist/auth/credential-store.js +193 -0
- package/dist/auth/credential-store.js.map +1 -0
- package/dist/auth/jwt-auth.d.ts +10 -0
- package/dist/auth/jwt-auth.d.ts.map +1 -0
- package/dist/auth/jwt-auth.js +205 -0
- package/dist/auth/jwt-auth.js.map +1 -0
- package/dist/auth/token-manager.d.ts +8 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +15 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -0
- package/dist/const.d.ts +4 -0
- package/dist/const.d.ts.map +1 -0
- package/dist/const.js +4 -0
- package/dist/const.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +90 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +316 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 FunctorZ Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/bin/zion-mcp.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { StoredCredentials, OAuthTokens, ProjectContext, MCPConfig } from "../types.js";
|
|
2
|
+
export declare class CredentialStore {
|
|
3
|
+
private workspaceRoot;
|
|
4
|
+
private mcpConfigDir;
|
|
5
|
+
private credentialsPath;
|
|
6
|
+
private configPath;
|
|
7
|
+
private projectContextPath;
|
|
8
|
+
constructor(workspaceRoot: string);
|
|
9
|
+
initialize(): Promise<void>;
|
|
10
|
+
saveCredentials(credentials: OAuthTokens): Promise<void>;
|
|
11
|
+
loadCredentials(): Promise<StoredCredentials | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Validate credentials including JWT token expiration
|
|
14
|
+
*/
|
|
15
|
+
private validateCredentials;
|
|
16
|
+
deleteCredentials(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Check if current stored credentials are valid
|
|
19
|
+
* @returns true if credentials exist and are valid, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
areCredentialsValid(): Promise<boolean>;
|
|
22
|
+
saveConfig(config: MCPConfig): Promise<void>;
|
|
23
|
+
loadConfig(): Promise<MCPConfig | null>;
|
|
24
|
+
saveProjectContext(projectExId: string): Promise<void>;
|
|
25
|
+
loadProjectContext(): Promise<ProjectContext | null>;
|
|
26
|
+
deleteProjectContext(): Promise<void>;
|
|
27
|
+
getWorkspaceRoot(): string;
|
|
28
|
+
getMcpConfigDir(): string;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=credential-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,aAAa,EAAE,MAAM;IAW3B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BxD,eAAe,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAsB1D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmErB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWxC;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAKvC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,UAAU,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAYvC,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,kBAAkB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAYpD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3C,gBAAgB,IAAI,MAAM;IAI1B,eAAe,IAAI,MAAM;CAG1B"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// src/auth/credential-store.ts
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import jwt from "jsonwebtoken";
|
|
5
|
+
export class CredentialStore {
|
|
6
|
+
workspaceRoot;
|
|
7
|
+
mcpConfigDir;
|
|
8
|
+
credentialsPath;
|
|
9
|
+
configPath;
|
|
10
|
+
projectContextPath;
|
|
11
|
+
constructor(workspaceRoot) {
|
|
12
|
+
this.workspaceRoot = workspaceRoot;
|
|
13
|
+
this.mcpConfigDir = path.join(workspaceRoot, ".functorz");
|
|
14
|
+
this.credentialsPath = path.join(this.mcpConfigDir, "credentials.json");
|
|
15
|
+
this.configPath = path.join(this.mcpConfigDir, "config.json");
|
|
16
|
+
this.projectContextPath = path.join(this.mcpConfigDir, "project-context.json");
|
|
17
|
+
}
|
|
18
|
+
async initialize() {
|
|
19
|
+
await fs.mkdir(this.mcpConfigDir, { recursive: true });
|
|
20
|
+
const gitignorePath = path.join(this.mcpConfigDir, ".gitignore");
|
|
21
|
+
const gitignoreContent = "*";
|
|
22
|
+
try {
|
|
23
|
+
await fs.writeFile(gitignorePath, gitignoreContent, { flag: "wx" });
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
// Ignore if exists
|
|
27
|
+
if (error.code !== "EEXIST") {
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async saveCredentials(credentials) {
|
|
33
|
+
// Validate credentials before saving
|
|
34
|
+
if (!credentials.access_token || credentials.access_token.trim() === "") {
|
|
35
|
+
throw new Error("Invalid credentials: access_token is required");
|
|
36
|
+
}
|
|
37
|
+
const data = {
|
|
38
|
+
access_token: credentials.access_token,
|
|
39
|
+
token_type: credentials.token_type || "Bearer",
|
|
40
|
+
savedAt: new Date().toISOString(),
|
|
41
|
+
};
|
|
42
|
+
// Validate the credentials object
|
|
43
|
+
if (!this.validateCredentials(data)) {
|
|
44
|
+
throw new Error("Invalid credentials: JWT token validation failed");
|
|
45
|
+
}
|
|
46
|
+
const tempPath = `${this.credentialsPath}.tmp`;
|
|
47
|
+
await fs.writeFile(tempPath, JSON.stringify(data, null, 2), { mode: 0o600 } // Owner read/write only
|
|
48
|
+
);
|
|
49
|
+
await fs.rename(tempPath, this.credentialsPath);
|
|
50
|
+
console.error("[CredentialStore] Credentials saved successfully");
|
|
51
|
+
}
|
|
52
|
+
async loadCredentials() {
|
|
53
|
+
try {
|
|
54
|
+
const data = await fs.readFile(this.credentialsPath, "utf8");
|
|
55
|
+
const credentials = JSON.parse(data);
|
|
56
|
+
// Validate credentials before returning
|
|
57
|
+
if (!this.validateCredentials(credentials)) {
|
|
58
|
+
console.error("[CredentialStore] Stored credentials are invalid or expired");
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return credentials;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error.code === "ENOENT") {
|
|
65
|
+
return null; // No credentials file
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate credentials including JWT token expiration
|
|
72
|
+
*/
|
|
73
|
+
validateCredentials(credentials) {
|
|
74
|
+
// Check if credentials object is valid
|
|
75
|
+
if (!credentials || !credentials.access_token) {
|
|
76
|
+
console.error("[CredentialStore] Missing access token");
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
// Check token type
|
|
80
|
+
if (credentials.token_type !== "Bearer") {
|
|
81
|
+
console.error("[CredentialStore] Invalid token type:", credentials.token_type);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// Decode and validate JWT token
|
|
85
|
+
try {
|
|
86
|
+
const decoded = jwt.decode(credentials.access_token, { complete: true });
|
|
87
|
+
if (!decoded || typeof decoded === "string") {
|
|
88
|
+
console.error("[CredentialStore] Failed to decode JWT token");
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
// Check if token has expired
|
|
92
|
+
const payload = decoded.payload;
|
|
93
|
+
if (payload.exp) {
|
|
94
|
+
const expirationTime = payload.exp * 1000; // Convert to milliseconds
|
|
95
|
+
const currentTime = Date.now();
|
|
96
|
+
if (currentTime >= expirationTime) {
|
|
97
|
+
console.error("[CredentialStore] JWT token has expired");
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
// Log time until expiration for debugging
|
|
101
|
+
const timeUntilExpiry = Math.floor((expirationTime - currentTime) / 1000 / 60); // minutes
|
|
102
|
+
console.error(`[CredentialStore] Token valid for ${timeUntilExpiry} more minutes`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.warn("[CredentialStore] JWT token does not have expiration field");
|
|
106
|
+
}
|
|
107
|
+
// Optionally validate other JWT claims
|
|
108
|
+
if (payload.iss) {
|
|
109
|
+
console.error(`[CredentialStore] Token issued by: ${payload.iss}`);
|
|
110
|
+
}
|
|
111
|
+
if (payload.sub) {
|
|
112
|
+
console.error(`[CredentialStore] Token subject: ${payload.sub}`);
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error("[CredentialStore] Error validating JWT token:", error.message);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async deleteCredentials() {
|
|
122
|
+
try {
|
|
123
|
+
await fs.unlink(this.credentialsPath);
|
|
124
|
+
console.error("[CredentialStore] Credentials deleted");
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (error.code !== "ENOENT") {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if current stored credentials are valid
|
|
134
|
+
* @returns true if credentials exist and are valid, false otherwise
|
|
135
|
+
*/
|
|
136
|
+
async areCredentialsValid() {
|
|
137
|
+
const credentials = await this.loadCredentials();
|
|
138
|
+
return credentials !== null;
|
|
139
|
+
}
|
|
140
|
+
async saveConfig(config) {
|
|
141
|
+
await fs.writeFile(this.configPath, JSON.stringify(config, null, 2));
|
|
142
|
+
}
|
|
143
|
+
async loadConfig() {
|
|
144
|
+
try {
|
|
145
|
+
const data = await fs.readFile(this.configPath, "utf8");
|
|
146
|
+
return JSON.parse(data);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
if (error.code === "ENOENT") {
|
|
150
|
+
return null; // No config file
|
|
151
|
+
}
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async saveProjectContext(projectExId) {
|
|
156
|
+
const context = {
|
|
157
|
+
projectExId,
|
|
158
|
+
lastUsed: new Date().toISOString(),
|
|
159
|
+
};
|
|
160
|
+
const tempPath = `${this.projectContextPath}.tmp`;
|
|
161
|
+
await fs.writeFile(tempPath, JSON.stringify(context, null, 2));
|
|
162
|
+
await fs.rename(tempPath, this.projectContextPath);
|
|
163
|
+
}
|
|
164
|
+
async loadProjectContext() {
|
|
165
|
+
try {
|
|
166
|
+
const data = await fs.readFile(this.projectContextPath, "utf8");
|
|
167
|
+
return JSON.parse(data);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error.code === "ENOENT") {
|
|
171
|
+
return null; // No project context file
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async deleteProjectContext() {
|
|
177
|
+
try {
|
|
178
|
+
await fs.unlink(this.projectContextPath);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (error.code !== "ENOENT") {
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
getWorkspaceRoot() {
|
|
187
|
+
return this.workspaceRoot;
|
|
188
|
+
}
|
|
189
|
+
getMcpConfigDir() {
|
|
190
|
+
return this.mcpConfigDir;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MCPConfig, OAuthTokens } from "../types.js";
|
|
2
|
+
export declare class JwtAuth {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: MCPConfig);
|
|
5
|
+
findAvailablePort(startPort?: number): Promise<number>;
|
|
6
|
+
authenticate(): Promise<OAuthTokens>;
|
|
7
|
+
successPage(): string;
|
|
8
|
+
errorPage(message: string): string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=jwt-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IAIvB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBtD,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC;IAkG1C,WAAW,IAAI,MAAM;IAyDrB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAmDnC"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// src/auth/jwt-auth.ts
|
|
2
|
+
import { createServer } from "http";
|
|
3
|
+
import open from "open";
|
|
4
|
+
export class JwtAuth {
|
|
5
|
+
config;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
async findAvailablePort(startPort) {
|
|
10
|
+
const port = startPort || this.config.callbackPort || 8088;
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const server = createServer();
|
|
13
|
+
server.on("error", (err) => {
|
|
14
|
+
if (err.code === "EADDRINUSE") {
|
|
15
|
+
// Try next port
|
|
16
|
+
resolve(this.findAvailablePort(port + 1));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
reject(err);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
server.listen(port, () => {
|
|
23
|
+
const address = server.address();
|
|
24
|
+
const resolvedPort = typeof address === "object" && address !== null ? address.port : port;
|
|
25
|
+
server.close(() => resolve(resolvedPort));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async authenticate() {
|
|
30
|
+
// Find available port
|
|
31
|
+
const callbackPort = await this.findAvailablePort();
|
|
32
|
+
const redirectUri = `http://localhost:${callbackPort}/callback`;
|
|
33
|
+
console.error(`[JwtAuth] Using callback URL: ${redirectUri}`);
|
|
34
|
+
console.error(`[JwtAuth] Opening browser for authentication...`);
|
|
35
|
+
// Start callback server and wait for JWT token
|
|
36
|
+
const jwtToken = await new Promise((resolve, reject) => {
|
|
37
|
+
const server = createServer(async (req, res) => {
|
|
38
|
+
if (!req.url) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const url = new URL(req.url, `http://localhost:${callbackPort}`);
|
|
42
|
+
if (url.pathname === "/callback") {
|
|
43
|
+
// Log the full callback URL for debugging
|
|
44
|
+
console.error(`[JwtAuth] Callback received: ${req.url}`);
|
|
45
|
+
// Extract token parameter (the JWT token)
|
|
46
|
+
const token = url.searchParams.get("token");
|
|
47
|
+
if (!token || token.trim() === "") {
|
|
48
|
+
console.error("[JwtAuth] No token parameter found in callback URL");
|
|
49
|
+
console.error("[JwtAuth] Available parameters:", Array.from(url.searchParams.keys()).join(", "));
|
|
50
|
+
const errorHtml = this.errorPage("No authentication token received");
|
|
51
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
52
|
+
res.end(errorHtml);
|
|
53
|
+
server.close();
|
|
54
|
+
reject(new Error("No token parameter in callback"));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.error(`[JwtAuth] Token received (length: ${token.length} chars)`);
|
|
58
|
+
const html = this.successPage();
|
|
59
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
60
|
+
res.end(html);
|
|
61
|
+
// Close server after short delay to ensure response is sent
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
server.close();
|
|
64
|
+
resolve(token);
|
|
65
|
+
}, 1000);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
server.on("error", reject);
|
|
69
|
+
server.listen(callbackPort, async () => {
|
|
70
|
+
// Build authentication URL with redirect_uri parameter
|
|
71
|
+
const authUrl = new URL(this.config.authEndpoint);
|
|
72
|
+
authUrl.searchParams.set("redirect_uri", redirectUri);
|
|
73
|
+
console.error(`[JwtAuth] Opening: ${authUrl.toString()}`);
|
|
74
|
+
// Open browser
|
|
75
|
+
try {
|
|
76
|
+
await open(authUrl.toString());
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error("[JwtAuth] Could not open browser automatically");
|
|
80
|
+
console.error("[JwtAuth] Please open this URL manually:");
|
|
81
|
+
console.error(authUrl.toString());
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Timeout after 5 minutes
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
server.close();
|
|
87
|
+
reject(new Error("Authentication timeout - no response after 5 minutes"));
|
|
88
|
+
}, 300000);
|
|
89
|
+
});
|
|
90
|
+
console.error("[JwtAuth] JWT token received successfully");
|
|
91
|
+
// Return the JWT token directly as the access token
|
|
92
|
+
return {
|
|
93
|
+
access_token: jwtToken,
|
|
94
|
+
token_type: "Bearer",
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
successPage() {
|
|
98
|
+
return `
|
|
99
|
+
<!DOCTYPE html>
|
|
100
|
+
<html>
|
|
101
|
+
<head>
|
|
102
|
+
<meta charset="utf-8">
|
|
103
|
+
<title>Token Received</title>
|
|
104
|
+
<style>
|
|
105
|
+
body {
|
|
106
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
107
|
+
display: flex;
|
|
108
|
+
justify-content: center;
|
|
109
|
+
align-items: center;
|
|
110
|
+
height: 100vh;
|
|
111
|
+
margin: 0;
|
|
112
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
113
|
+
}
|
|
114
|
+
.container {
|
|
115
|
+
background: white;
|
|
116
|
+
padding: 2.5rem;
|
|
117
|
+
border-radius: 1rem;
|
|
118
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
119
|
+
text-align: center;
|
|
120
|
+
max-width: 400px;
|
|
121
|
+
}
|
|
122
|
+
h1 {
|
|
123
|
+
margin: 0 0 1rem;
|
|
124
|
+
color: #333;
|
|
125
|
+
font-size: 1.5rem;
|
|
126
|
+
}
|
|
127
|
+
p {
|
|
128
|
+
color: #666;
|
|
129
|
+
margin: 0;
|
|
130
|
+
line-height: 1.6;
|
|
131
|
+
}
|
|
132
|
+
.check {
|
|
133
|
+
font-size: 3rem;
|
|
134
|
+
margin-bottom: 1rem;
|
|
135
|
+
}
|
|
136
|
+
</style>
|
|
137
|
+
</head>
|
|
138
|
+
<body>
|
|
139
|
+
<div class="container">
|
|
140
|
+
<div class="check">✓</div>
|
|
141
|
+
<h1>Token Received</h1>
|
|
142
|
+
<p>MCP server authenticated successfully.</p>
|
|
143
|
+
<p style="margin-top: 1rem; font-size: 0.9em; opacity: 0.8;">You can close this window.</p>
|
|
144
|
+
</div>
|
|
145
|
+
<script>
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
window.close();
|
|
148
|
+
}, 2000);
|
|
149
|
+
</script>
|
|
150
|
+
</body>
|
|
151
|
+
</html>`;
|
|
152
|
+
}
|
|
153
|
+
errorPage(message) {
|
|
154
|
+
return `
|
|
155
|
+
<!DOCTYPE html>
|
|
156
|
+
<html>
|
|
157
|
+
<head>
|
|
158
|
+
<meta charset="utf-8">
|
|
159
|
+
<title>Authentication Error</title>
|
|
160
|
+
<style>
|
|
161
|
+
body {
|
|
162
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
163
|
+
display: flex;
|
|
164
|
+
justify-content: center;
|
|
165
|
+
align-items: center;
|
|
166
|
+
height: 100vh;
|
|
167
|
+
margin: 0;
|
|
168
|
+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
169
|
+
}
|
|
170
|
+
.container {
|
|
171
|
+
background: white;
|
|
172
|
+
padding: 2.5rem;
|
|
173
|
+
border-radius: 1rem;
|
|
174
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
175
|
+
text-align: center;
|
|
176
|
+
max-width: 400px;
|
|
177
|
+
}
|
|
178
|
+
h1 {
|
|
179
|
+
margin: 0 0 1rem;
|
|
180
|
+
color: #d93025;
|
|
181
|
+
font-size: 1.5rem;
|
|
182
|
+
}
|
|
183
|
+
p {
|
|
184
|
+
color: #666;
|
|
185
|
+
margin: 0;
|
|
186
|
+
line-height: 1.6;
|
|
187
|
+
}
|
|
188
|
+
.error-icon {
|
|
189
|
+
font-size: 3rem;
|
|
190
|
+
margin-bottom: 1rem;
|
|
191
|
+
}
|
|
192
|
+
</style>
|
|
193
|
+
</head>
|
|
194
|
+
<body>
|
|
195
|
+
<div class="container">
|
|
196
|
+
<div class="error-icon">⚠️</div>
|
|
197
|
+
<h1>Authentication Error</h1>
|
|
198
|
+
<p>${message}</p>
|
|
199
|
+
<p style="margin-top: 1rem; font-size: 0.9em; opacity: 0.8;">Please try again.</p>
|
|
200
|
+
</div>
|
|
201
|
+
</body>
|
|
202
|
+
</html>`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=jwt-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.js","sourceRoot":"","sources":["../../src/auth/jwt-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CredentialStore } from "./credential-store.js";
|
|
2
|
+
import type { MCPConfig } from "../types.js";
|
|
3
|
+
export declare class TokenManager {
|
|
4
|
+
private store;
|
|
5
|
+
constructor(credentialStore: CredentialStore, _config: MCPConfig);
|
|
6
|
+
getValidToken(): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=token-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../src/auth/token-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAkB;gBAEnB,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS;IAI1D,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;CAUvC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class TokenManager {
|
|
2
|
+
store;
|
|
3
|
+
constructor(credentialStore, _config) {
|
|
4
|
+
this.store = credentialStore;
|
|
5
|
+
}
|
|
6
|
+
async getValidToken() {
|
|
7
|
+
const credentials = await this.store.loadCredentials();
|
|
8
|
+
if (!credentials) {
|
|
9
|
+
throw new Error("Not authenticated");
|
|
10
|
+
}
|
|
11
|
+
// Return the JWT token directly (no refresh needed)
|
|
12
|
+
return credentials.access_token;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=token-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../src/auth/token-manager.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,YAAY;IACf,KAAK,CAAkB;IAE/B,YAAY,eAAgC,EAAE,OAAkB;QAC9D,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAEvD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,oDAAoD;QACpD,OAAO,WAAW,CAAC,YAAY,CAAC;IAClC,CAAC;CACF"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAS5C,wBAAsB,SAAS,CAC7B,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,SAAS,CAAC,CAoBpB"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import { config as dotenvConfig } from "dotenv";
|
|
3
|
+
import { BACKEND_API_BASE_DEFAULT, BACKEND_AUTH_ENDPOINT_DEFAULT, } from "./const.js";
|
|
4
|
+
// Load .env file
|
|
5
|
+
dotenvConfig();
|
|
6
|
+
export async function getConfig(credentialStore) {
|
|
7
|
+
// Try to load workspace-specific config
|
|
8
|
+
let config = await credentialStore.loadConfig();
|
|
9
|
+
if (!config) {
|
|
10
|
+
// Use environment variables with fallback to defaults
|
|
11
|
+
config = {
|
|
12
|
+
authEndpoint: process.env.BACKEND_AUTH_ENDPOINT || BACKEND_AUTH_ENDPOINT_DEFAULT,
|
|
13
|
+
apiBaseUrl: process.env.BACKEND_API_BASE || BACKEND_API_BASE_DEFAULT,
|
|
14
|
+
callbackPort: process.env.LOCAL_CALLBACK_PORT
|
|
15
|
+
? parseInt(process.env.LOCAL_CALLBACK_PORT, 10)
|
|
16
|
+
: 8088,
|
|
17
|
+
};
|
|
18
|
+
// Save default config for future use
|
|
19
|
+
await credentialStore.saveConfig(config);
|
|
20
|
+
}
|
|
21
|
+
return config;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,EACL,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,YAAY,CAAC;AAEpB,iBAAiB;AACjB,YAAY,EAAE,CAAC;AAEf,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,eAAgC;IAEhC,wCAAwC;IACxC,IAAI,MAAM,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,CAAC;IAEhD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,sDAAsD;QACtD,MAAM,GAAG;YACP,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,6BAA6B;YACpE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,wBAAwB;YACpE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;gBAC3C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC;gBAC/C,CAAC,CAAC,IAAI;SACT,CAAC;QAEF,qCAAqC;QACrC,MAAM,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/const.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../src/const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,aAAa,CAAC;AACtC,eAAO,MAAM,6BAA6B,oCAAoC,CAAC;AAC/E,eAAO,MAAM,wBAAwB,qCAAqC,CAAC"}
|
package/dist/const.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.js","sourceRoot":"","sources":["../src/const.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AACtC,MAAM,CAAC,MAAM,6BAA6B,GAAG,iCAAiC,CAAC;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,kCAAkC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAkDA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAyD1C"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CredentialStore } from "./auth/credential-store.js";
|
|
5
|
+
import { JwtAuth } from "./auth/jwt-auth.js";
|
|
6
|
+
import { TokenManager } from "./auth/token-manager.js";
|
|
7
|
+
import { registerTools } from "./tools/index.js";
|
|
8
|
+
import { getConfig } from "./config.js";
|
|
9
|
+
import { SERVER_NAME } from "./const.js";
|
|
10
|
+
// Log to stderr (stdout is reserved for MCP protocol)
|
|
11
|
+
const log = (...args) => {
|
|
12
|
+
console.error(`[${SERVER_NAME}]`, ...args);
|
|
13
|
+
};
|
|
14
|
+
async function ensureAuthentication(credentialStore, config) {
|
|
15
|
+
const credentials = await credentialStore.loadCredentials();
|
|
16
|
+
if (credentials) {
|
|
17
|
+
log("Using existing JWT token");
|
|
18
|
+
return credentials;
|
|
19
|
+
}
|
|
20
|
+
// Need to authenticate
|
|
21
|
+
log("No valid credentials found - starting authentication flow...");
|
|
22
|
+
log("⚠️ Your browser will open for authentication");
|
|
23
|
+
const jwtAuth = new JwtAuth(config);
|
|
24
|
+
try {
|
|
25
|
+
const tokens = await jwtAuth.authenticate();
|
|
26
|
+
await credentialStore.saveCredentials(tokens);
|
|
27
|
+
log("✓ Authentication successful!");
|
|
28
|
+
// Return as StoredCredentials
|
|
29
|
+
const savedCredentials = await credentialStore.loadCredentials();
|
|
30
|
+
if (!savedCredentials) {
|
|
31
|
+
throw new Error("Failed to load saved credentials");
|
|
32
|
+
}
|
|
33
|
+
return savedCredentials;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
log("✗ Authentication failed:", error.message);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function main() {
|
|
41
|
+
try {
|
|
42
|
+
// Get workspace root from environment or CWD
|
|
43
|
+
const workspaceRoot = process.env.WORKSPACE_ROOT || process.cwd();
|
|
44
|
+
log(`Starting in workspace: ${workspaceRoot}`);
|
|
45
|
+
// Initialize credential store
|
|
46
|
+
const credentialStore = new CredentialStore(workspaceRoot);
|
|
47
|
+
await credentialStore.initialize();
|
|
48
|
+
// Load configuration
|
|
49
|
+
const config = await getConfig(credentialStore);
|
|
50
|
+
// Ensure authentication before starting MCP server
|
|
51
|
+
await ensureAuthentication(credentialStore, config);
|
|
52
|
+
// Initialize token manager
|
|
53
|
+
const tokenManager = new TokenManager(credentialStore, config);
|
|
54
|
+
// Create MCP server
|
|
55
|
+
const server = new McpServer({
|
|
56
|
+
name: SERVER_NAME,
|
|
57
|
+
version: "1.0.0",
|
|
58
|
+
}, {
|
|
59
|
+
capabilities: {
|
|
60
|
+
tools: {},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
// Register all tools with token manager
|
|
64
|
+
await registerTools(server, tokenManager, credentialStore, config);
|
|
65
|
+
// Start MCP server with stdio transport
|
|
66
|
+
const transport = new StdioServerTransport();
|
|
67
|
+
await server.connect(transport);
|
|
68
|
+
log("MCP server ready");
|
|
69
|
+
// Handle graceful shutdown
|
|
70
|
+
process.on("SIGINT", async () => {
|
|
71
|
+
log("Shutting down...");
|
|
72
|
+
await server.close();
|
|
73
|
+
process.exit(0);
|
|
74
|
+
});
|
|
75
|
+
process.on("SIGTERM", async () => {
|
|
76
|
+
log("Shutting down...");
|
|
77
|
+
await server.close();
|
|
78
|
+
process.exit(0);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
log("Fatal error:", error.message);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Run if this is the main module
|
|
87
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
88
|
+
main();
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { TokenManager } from "../auth/token-manager.js";
|
|
3
|
+
import type { CredentialStore } from "../auth/credential-store.js";
|
|
4
|
+
import type { MCPConfig } from "../types.js";
|
|
5
|
+
export declare function registerTools(server: McpServer, tokenManager: TokenManager, credentialStore: CredentialStore, mcpConfig: MCPConfig): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA8I7C,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Rf"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { GraphQLClient, gql } from "graphql-request";
|
|
3
|
+
import { SERVER_NAME } from "../const.js";
|
|
4
|
+
// GraphQL queries
|
|
5
|
+
const SIMPLIFIED_CAUGHT_UP_SERVER_SCHEMA = gql `
|
|
6
|
+
query SimplifiedCaughtUpServerSchema($projectExId: String!) {
|
|
7
|
+
project(projectExId: $projectExId) {
|
|
8
|
+
simplifiedCaughtUpServerSchema {
|
|
9
|
+
dataModel
|
|
10
|
+
draftActionFlows
|
|
11
|
+
pendingActionFlows
|
|
12
|
+
apis
|
|
13
|
+
zAiConfigs
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
const FUZZY_SEARCH_PROJECT_NAME = gql `
|
|
19
|
+
query FuzzySearchProjectName(
|
|
20
|
+
$projectName: String!
|
|
21
|
+
$paginator: ConnectionPaginatorInput
|
|
22
|
+
) {
|
|
23
|
+
fuzzySearchProjectName(projectName: $projectName, paginator: $paginator) {
|
|
24
|
+
pageInfo {
|
|
25
|
+
hasNextPage
|
|
26
|
+
hasPreviousPage
|
|
27
|
+
startCursor {
|
|
28
|
+
value
|
|
29
|
+
}
|
|
30
|
+
endCursor {
|
|
31
|
+
value
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
edges {
|
|
35
|
+
cursor {
|
|
36
|
+
value
|
|
37
|
+
}
|
|
38
|
+
node {
|
|
39
|
+
exId
|
|
40
|
+
type
|
|
41
|
+
name
|
|
42
|
+
projectName
|
|
43
|
+
collaboratorType
|
|
44
|
+
collaboratorTypeByLevel
|
|
45
|
+
hasPublished
|
|
46
|
+
projectOwner
|
|
47
|
+
auditStatus
|
|
48
|
+
forBeginnerGuide
|
|
49
|
+
brandingRemoved
|
|
50
|
+
projectResourceSufficient
|
|
51
|
+
canMigrateToHigherComputingPowerZiroom
|
|
52
|
+
inActiveSingleTenantComputingPowerKit
|
|
53
|
+
schemaExId
|
|
54
|
+
devEnvironmentEnable
|
|
55
|
+
webProdDomain
|
|
56
|
+
hasCustomDomain
|
|
57
|
+
lastOpenedAt
|
|
58
|
+
isExpired
|
|
59
|
+
projectSpace {
|
|
60
|
+
organization {
|
|
61
|
+
exId
|
|
62
|
+
displayName
|
|
63
|
+
ownerName
|
|
64
|
+
planType
|
|
65
|
+
}
|
|
66
|
+
projectSpaceType
|
|
67
|
+
}
|
|
68
|
+
projectPlan {
|
|
69
|
+
expireAt
|
|
70
|
+
projectPlanType
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
export async function registerTools(server, tokenManager, credentialStore, mcpConfig) {
|
|
78
|
+
const backendEndpoint = `${mcpConfig.apiBaseUrl}/api/graphql`;
|
|
79
|
+
// Register get schema tool
|
|
80
|
+
server.registerTool("get_project_schema", {
|
|
81
|
+
description: "Get the simplified caught up server schema using GraphQL. If projectExId is not provided, uses the last used project.",
|
|
82
|
+
inputSchema: z.object({
|
|
83
|
+
projectExId: z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("Project external ID (optional if project context is set)"),
|
|
87
|
+
}),
|
|
88
|
+
}, async (args) => {
|
|
89
|
+
try {
|
|
90
|
+
// Get projectExId from arguments or stored context
|
|
91
|
+
let projectExId = args.projectExId;
|
|
92
|
+
if (!projectExId) {
|
|
93
|
+
const context = await credentialStore.loadProjectContext();
|
|
94
|
+
if (!context) {
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: "text",
|
|
99
|
+
text: "No project specified and no project context found. Please provide projectExId or use set_current_project first.",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
isError: true,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
projectExId = context.projectExId;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Save the project context for future use
|
|
109
|
+
await credentialStore.saveProjectContext(projectExId);
|
|
110
|
+
}
|
|
111
|
+
const token = await tokenManager.getValidToken();
|
|
112
|
+
// Create GraphQL client with authentication
|
|
113
|
+
const client = new GraphQLClient(backendEndpoint, {
|
|
114
|
+
headers: {
|
|
115
|
+
Authorization: `Bearer ${token}`,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
// Execute GraphQL query with typed variables
|
|
119
|
+
const data = await client.request(SIMPLIFIED_CAUGHT_UP_SERVER_SCHEMA, { projectExId });
|
|
120
|
+
return {
|
|
121
|
+
content: [
|
|
122
|
+
{
|
|
123
|
+
type: "text",
|
|
124
|
+
text: JSON.stringify(data.project.simplifiedCaughtUpServerSchema, null, 2),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: `Error fetching schema: ${error.message}`,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
isError: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
// Register get projects tool
|
|
142
|
+
server.registerTool("get_projects", {
|
|
143
|
+
description: "Search and list projects with optional name filter and pagination support",
|
|
144
|
+
inputSchema: z.object({
|
|
145
|
+
projectName: z
|
|
146
|
+
.string()
|
|
147
|
+
.optional()
|
|
148
|
+
.describe("Project name to search for (empty string returns all projects)"),
|
|
149
|
+
cursor: z
|
|
150
|
+
.string()
|
|
151
|
+
.optional()
|
|
152
|
+
.describe("Cursor for pagination (optional)"),
|
|
153
|
+
limit: z
|
|
154
|
+
.number()
|
|
155
|
+
.optional()
|
|
156
|
+
.describe("Number of projects to fetch (default: 20)"),
|
|
157
|
+
}),
|
|
158
|
+
}, async (args) => {
|
|
159
|
+
try {
|
|
160
|
+
const token = await tokenManager.getValidToken();
|
|
161
|
+
// Create GraphQL client with authentication
|
|
162
|
+
const client = new GraphQLClient(backendEndpoint, {
|
|
163
|
+
headers: {
|
|
164
|
+
Authorization: `Bearer ${token}`,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
// Prepare variables for GraphQL query
|
|
168
|
+
const variables = {
|
|
169
|
+
projectName: args.projectName || "", // Empty string returns all projects
|
|
170
|
+
paginator: {
|
|
171
|
+
after: args.cursor || null,
|
|
172
|
+
first: args.limit || 20,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
// Execute GraphQL query
|
|
176
|
+
const data = await client.request(FUZZY_SEARCH_PROJECT_NAME, variables);
|
|
177
|
+
// Format response with pagination info
|
|
178
|
+
const result = {
|
|
179
|
+
projects: data.fuzzySearchProjectName.edges.map((edge) => edge.node),
|
|
180
|
+
pagination: {
|
|
181
|
+
hasNextPage: data.fuzzySearchProjectName.pageInfo.hasNextPage,
|
|
182
|
+
hasPreviousPage: data.fuzzySearchProjectName.pageInfo.hasPreviousPage,
|
|
183
|
+
nextCursor: data.fuzzySearchProjectName.pageInfo.endCursor?.value,
|
|
184
|
+
startCursor: data.fuzzySearchProjectName.pageInfo.startCursor?.value,
|
|
185
|
+
},
|
|
186
|
+
totalReturned: data.fuzzySearchProjectName.edges.length,
|
|
187
|
+
};
|
|
188
|
+
return {
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: "text",
|
|
192
|
+
text: JSON.stringify(result, null, 2),
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
content: [
|
|
200
|
+
{
|
|
201
|
+
type: "text",
|
|
202
|
+
text: `Error fetching projects: ${error.message}`,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
isError: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
// Register set project context tool
|
|
210
|
+
server.registerTool("set_current_project", {
|
|
211
|
+
description: "Set the current project context by exId",
|
|
212
|
+
inputSchema: z.object({
|
|
213
|
+
projectExId: z
|
|
214
|
+
.string()
|
|
215
|
+
.describe("Project external ID to set as current"),
|
|
216
|
+
}),
|
|
217
|
+
}, async (args) => {
|
|
218
|
+
try {
|
|
219
|
+
await credentialStore.saveProjectContext(args.projectExId);
|
|
220
|
+
return {
|
|
221
|
+
content: [
|
|
222
|
+
{
|
|
223
|
+
type: "text",
|
|
224
|
+
text: `✓ Project context set to: ${args.projectExId}`,
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
return {
|
|
231
|
+
content: [
|
|
232
|
+
{
|
|
233
|
+
type: "text",
|
|
234
|
+
text: `Error setting project context: ${error.message}`,
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
isError: true,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
// Register get current project tool
|
|
242
|
+
server.registerTool("get_current_project", {
|
|
243
|
+
description: "Get the current project context",
|
|
244
|
+
inputSchema: z.object({}),
|
|
245
|
+
}, async () => {
|
|
246
|
+
try {
|
|
247
|
+
const context = await credentialStore.loadProjectContext();
|
|
248
|
+
if (!context) {
|
|
249
|
+
return {
|
|
250
|
+
content: [
|
|
251
|
+
{
|
|
252
|
+
type: "text",
|
|
253
|
+
text: "No project context set. Use set_current_project or provide projectExId in tool calls.",
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
content: [
|
|
260
|
+
{
|
|
261
|
+
type: "text",
|
|
262
|
+
text: JSON.stringify(context, null, 2),
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
return {
|
|
269
|
+
content: [
|
|
270
|
+
{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: `Error getting project context: ${error.message}`,
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
isError: true,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// Register re-authentication tool
|
|
280
|
+
server.registerTool("reauth", {
|
|
281
|
+
description: "Trigger OAuth re-authentication flow",
|
|
282
|
+
inputSchema: z.object({}),
|
|
283
|
+
}, async () => {
|
|
284
|
+
try {
|
|
285
|
+
console.error(`[${SERVER_NAME}] Re-authentication requested...`);
|
|
286
|
+
await credentialStore.deleteCredentials();
|
|
287
|
+
// Need to import these for re-auth
|
|
288
|
+
const { getConfig } = await import("../config.js");
|
|
289
|
+
const { JwtAuth } = await import("../auth/jwt-auth.js");
|
|
290
|
+
const newConfig = await getConfig(credentialStore);
|
|
291
|
+
const jwtAuth = new JwtAuth(newConfig);
|
|
292
|
+
const tokens = await jwtAuth.authenticate();
|
|
293
|
+
await credentialStore.saveCredentials(tokens);
|
|
294
|
+
return {
|
|
295
|
+
content: [
|
|
296
|
+
{
|
|
297
|
+
type: "text",
|
|
298
|
+
text: "✓ Re-authentication successful",
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
return {
|
|
305
|
+
content: [
|
|
306
|
+
{
|
|
307
|
+
type: "text",
|
|
308
|
+
text: `✗ Re-authentication failed: ${error.message}`,
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
isError: true,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAqB1C,kBAAkB;AAClB,MAAM,kCAAkC,GAAG,GAAG,CAAA;;;;;;;;;;;;CAY7C,CAAC;AAEF,MAAM,yBAAyB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DpC,CAAC;AA+CF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAiB,EACjB,YAA0B,EAC1B,eAAgC,EAChC,SAAoB;IAEpB,MAAM,eAAe,GAAG,GAAG,SAAS,CAAC,UAAU,cAAc,CAAC;IAE9D,2BAA2B;IAC3B,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,uHAAuH;QACzH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,0DAA0D,CAAC;SACxE,CAAC;KACH,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,mDAAmD;YACnD,IAAI,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAEnC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,CAAC;gBAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,iHAAiH;6BACxH;yBACF;wBACD,OAAO,EAAE,IAAI;qBACd,CAAC;gBACJ,CAAC;gBACD,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,0CAA0C;gBAC1C,MAAM,eAAe,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACxD,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC;YAEjD,4CAA4C;YAC5C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,eAAe,EAAE;gBAChD,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,KAAK,EAAE;iBACjC;aACF,CAAC,CAAC;YAEH,6CAA6C;YAC7C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAG/B,kCAAkC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAEvD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,IAAI,CAAC,OAAO,CAAC,8BAA8B,EAC3C,IAAI,EACJ,CAAC,CACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,0BAA2B,KAAe,CAAC,OAAO,EAAE;qBAC3D;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,6BAA6B;IAC7B,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,2EAA2E;QAC7E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,gEAAgE,CACjE;YACH,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,2CAA2C,CAAC;SACzD,CAAC;KACH,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC;YAEjD,4CAA4C;YAC5C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,eAAe,EAAE;gBAChD,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,KAAK,EAAE;iBACjC;aACF,CAAC,CAAC;YAEH,sCAAsC;YACtC,MAAM,SAAS,GAA2B;gBACxC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,oCAAoC;gBACzE,SAAS,EAAE;oBACT,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;oBAC1B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;iBACxB;aACF,CAAC;YAEF,wBAAwB;YACxB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAG/B,yBAAyB,EAAE,SAAS,CAAC,CAAC;YAExC,uCAAuC;YACvC,MAAM,MAAM,GAAG;gBACb,QAAQ,EAAE,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBACpE,UAAU,EAAE;oBACV,WAAW,EAAE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,WAAW;oBAC7D,eAAe,EACb,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,eAAe;oBACtD,UAAU,EAAE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK;oBACjE,WAAW,EACT,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK;iBAC1D;gBACD,aAAa,EAAE,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,MAAM;aACxD,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,4BAA6B,KAAe,CAAC,OAAO,EAAE;qBAC7D;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oCAAoC;IACpC,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,CAAC,uCAAuC,CAAC;SACrD,CAAC;KACH,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3D,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,6BAA6B,IAAI,CAAC,WAAW,EAAE;qBACtD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAmC,KAAe,CAAC,OAAO,EAAE;qBACnE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oCAAoC;IACpC,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KAC1B,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,CAAC;YAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,uFAAuF;yBAC9F;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;qBACvC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAmC,KAAe,CAAC,OAAO,EAAE;qBACnE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,kCAAkC;IAClC,MAAM,CAAC,YAAY,CACjB,QAAQ,EACR;QACE,WAAW,EAAE,sCAAsC;QACnD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KAC1B,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW,kCAAkC,CAAC,CAAC;YACjE,MAAM,eAAe,CAAC,iBAAiB,EAAE,CAAC;YAE1C,mCAAmC;YACnC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YACnD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAExD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAE9C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,gCAAgC;qBACvC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,+BAAgC,KAAe,CAAC,OAAO,EAAE;qBAChE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface OAuthTokens {
|
|
2
|
+
access_token: string;
|
|
3
|
+
token_type: string;
|
|
4
|
+
}
|
|
5
|
+
export interface StoredCredentials extends OAuthTokens {
|
|
6
|
+
savedAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ProjectContext {
|
|
9
|
+
projectExId: string;
|
|
10
|
+
lastUsed: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MCPConfig {
|
|
13
|
+
authEndpoint: string;
|
|
14
|
+
apiBaseUrl: string;
|
|
15
|
+
callbackPort?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface PKCEChallenge {
|
|
18
|
+
codeVerifier: string;
|
|
19
|
+
codeChallenge: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ToolInput {
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface ToolResponse {
|
|
25
|
+
content: Array<{
|
|
26
|
+
type: string;
|
|
27
|
+
text: string;
|
|
28
|
+
}>;
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface GetSchemaInput {
|
|
32
|
+
projectExId?: string;
|
|
33
|
+
appExId?: string;
|
|
34
|
+
appVersionExId?: string;
|
|
35
|
+
refresh?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface GetProjectsInput {
|
|
38
|
+
cursor?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface Project {
|
|
41
|
+
exId: string;
|
|
42
|
+
name: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
createdAt: string;
|
|
45
|
+
updatedAt: string;
|
|
46
|
+
}
|
|
47
|
+
export interface ProjectsResponse {
|
|
48
|
+
projects: Project[];
|
|
49
|
+
cursor?: string;
|
|
50
|
+
hasMore: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface OAuthErrorResponse {
|
|
53
|
+
error: string;
|
|
54
|
+
error_description?: string;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zion-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for functorz.com",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"zion-mcp": "./bin/zion-mcp.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/server.js"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "npm run build && node bin/zion-mcp.js",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"zion",
|
|
22
|
+
"oauth",
|
|
23
|
+
"ai",
|
|
24
|
+
"model-context-protocol"
|
|
25
|
+
],
|
|
26
|
+
"author": "FunctorZ",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
30
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
31
|
+
"dotenv": "^17.2.3",
|
|
32
|
+
"graphql": "^16.12.0",
|
|
33
|
+
"graphql-request": "^7.3.4",
|
|
34
|
+
"jsonwebtoken": "^9.0.2",
|
|
35
|
+
"open": "^10.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^20.0.0",
|
|
39
|
+
"typescript": "^5.3.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"bin/",
|
|
46
|
+
"dist/",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
]
|
|
49
|
+
}
|