@ai-support-agent/cli 0.0.4-beta.11 → 0.0.4-beta.12

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.
Files changed (65) hide show
  1. package/dist/api-client.d.ts +2 -1
  2. package/dist/api-client.d.ts.map +1 -1
  3. package/dist/api-client.js +7 -0
  4. package/dist/api-client.js.map +1 -1
  5. package/dist/commands/api-chat-executor.d.ts.map +1 -1
  6. package/dist/commands/api-chat-executor.js +11 -3
  7. package/dist/commands/api-chat-executor.js.map +1 -1
  8. package/dist/commands/chat-executor.d.ts +1 -1
  9. package/dist/commands/chat-executor.d.ts.map +1 -1
  10. package/dist/commands/chat-executor.js +8 -5
  11. package/dist/commands/chat-executor.js.map +1 -1
  12. package/dist/commands/claude-code-runner.d.ts +2 -1
  13. package/dist/commands/claude-code-runner.d.ts.map +1 -1
  14. package/dist/commands/claude-code-runner.js +5 -2
  15. package/dist/commands/claude-code-runner.js.map +1 -1
  16. package/dist/commands/index.d.ts +1 -0
  17. package/dist/commands/index.d.ts.map +1 -1
  18. package/dist/commands/index.js +1 -1
  19. package/dist/commands/index.js.map +1 -1
  20. package/dist/commands/shared-chat-utils.d.ts +9 -1
  21. package/dist/commands/shared-chat-utils.d.ts.map +1 -1
  22. package/dist/commands/shared-chat-utils.js +24 -0
  23. package/dist/commands/shared-chat-utils.js.map +1 -1
  24. package/dist/config-manager.d.ts +1 -0
  25. package/dist/config-manager.d.ts.map +1 -1
  26. package/dist/config-manager.js +1 -0
  27. package/dist/config-manager.js.map +1 -1
  28. package/dist/constants.d.ts +3 -0
  29. package/dist/constants.d.ts.map +1 -1
  30. package/dist/constants.js +4 -1
  31. package/dist/constants.js.map +1 -1
  32. package/dist/mcp/config-writer.d.ts +17 -0
  33. package/dist/mcp/config-writer.d.ts.map +1 -0
  34. package/dist/mcp/config-writer.js +63 -0
  35. package/dist/mcp/config-writer.js.map +1 -0
  36. package/dist/mcp/server.d.ts +11 -0
  37. package/dist/mcp/server.d.ts.map +1 -0
  38. package/dist/mcp/server.js +55 -0
  39. package/dist/mcp/server.js.map +1 -0
  40. package/dist/mcp/tools/credentials.d.ts +5 -0
  41. package/dist/mcp/tools/credentials.d.ts.map +1 -0
  42. package/dist/mcp/tools/credentials.js +49 -0
  43. package/dist/mcp/tools/credentials.js.map +1 -0
  44. package/dist/mcp/tools/db-query.d.ts +13 -0
  45. package/dist/mcp/tools/db-query.d.ts.map +1 -0
  46. package/dist/mcp/tools/db-query.js +138 -0
  47. package/dist/mcp/tools/db-query.js.map +1 -0
  48. package/dist/mcp/tools/db-schemas.d.ts +5 -0
  49. package/dist/mcp/tools/db-schemas.d.ts.map +1 -0
  50. package/dist/mcp/tools/db-schemas.js +67 -0
  51. package/dist/mcp/tools/db-schemas.js.map +1 -0
  52. package/dist/mcp/tools/project-info.d.ts +5 -0
  53. package/dist/mcp/tools/project-info.d.ts.map +1 -0
  54. package/dist/mcp/tools/project-info.js +51 -0
  55. package/dist/mcp/tools/project-info.js.map +1 -0
  56. package/dist/project-agent.d.ts +4 -0
  57. package/dist/project-agent.d.ts.map +1 -1
  58. package/dist/project-agent.js +38 -2
  59. package/dist/project-agent.js.map +1 -1
  60. package/dist/project-dir.d.ts.map +1 -1
  61. package/dist/project-dir.js +5 -2
  62. package/dist/project-dir.js.map +1 -1
  63. package/dist/types.d.ts +30 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/package.json +5 -1
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMcpConfigPath = getMcpConfigPath;
4
+ exports.buildMcpConfig = buildMcpConfig;
5
+ exports.writeMcpConfig = writeMcpConfig;
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ /**
9
+ * MCP 設定ファイルのパスを返す
10
+ */
11
+ function getMcpConfigPath(projectDir) {
12
+ return (0, path_1.join)(projectDir, '.ai-support-agent', 'mcp', 'config.json');
13
+ }
14
+ /**
15
+ * MCP 設定 JSON を構築する
16
+ *
17
+ * token はファイルに書かない。環境変数参照にする。
18
+ */
19
+ function buildMcpConfig(apiUrl, projectCode, mcpServerPath) {
20
+ return {
21
+ mcpServers: {
22
+ 'ai-support-agent': {
23
+ command: 'node',
24
+ args: [mcpServerPath],
25
+ env: {
26
+ AI_SUPPORT_AGENT_API_URL: apiUrl,
27
+ AI_SUPPORT_AGENT_TOKEN: '${AI_SUPPORT_AGENT_TOKEN}',
28
+ AI_SUPPORT_AGENT_PROJECT_CODE: projectCode,
29
+ },
30
+ },
31
+ },
32
+ };
33
+ }
34
+ /**
35
+ * MCP 設定ファイルを書き出す
36
+ *
37
+ * 0o600 権限で作成し、token は環境変数参照にする。
38
+ */
39
+ function writeMcpConfig(projectDir, apiUrl, token, projectCode, mcpServerPath) {
40
+ const configPath = getMcpConfigPath(projectDir);
41
+ const dir = (0, path_1.dirname)(configPath);
42
+ (0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
43
+ // 実際の設定: token を直接埋め込む(ファイルは 0o600 で保護)
44
+ const config = {
45
+ mcpServers: {
46
+ 'ai-support-agent': {
47
+ command: 'node',
48
+ args: [mcpServerPath],
49
+ env: {
50
+ AI_SUPPORT_AGENT_API_URL: apiUrl,
51
+ AI_SUPPORT_AGENT_TOKEN: token,
52
+ AI_SUPPORT_AGENT_PROJECT_CODE: projectCode,
53
+ },
54
+ },
55
+ },
56
+ };
57
+ (0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2), {
58
+ mode: 0o600,
59
+ encoding: 'utf-8',
60
+ });
61
+ return configPath;
62
+ }
63
+ //# sourceMappingURL=config-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/mcp/config-writer.ts"],"names":[],"mappings":";;AAMA,4CAEC;AAOD,wCAkBC;AAOD,wCAiCC;AAzED,2BAA6C;AAC7C,+BAAoC;AAEpC;;GAEG;AACH,SAAgB,gBAAgB,CAAC,UAAkB;IACjD,OAAO,IAAA,WAAI,EAAC,UAAU,EAAE,mBAAmB,EAAE,KAAK,EAAE,aAAa,CAAC,CAAA;AACpE,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAC5B,MAAc,EACd,WAAmB,EACnB,aAAqB;IAErB,OAAO;QACL,UAAU,EAAE;YACV,kBAAkB,EAAE;gBAClB,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,CAAC,aAAa,CAAC;gBACrB,GAAG,EAAE;oBACH,wBAAwB,EAAE,MAAM;oBAChC,sBAAsB,EAAE,2BAA2B;oBACnD,6BAA6B,EAAE,WAAW;iBAC3C;aACF;SACF;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAC5B,UAAkB,EAClB,MAAc,EACd,KAAa,EACb,WAAmB,EACnB,aAAqB;IAErB,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;IAC/C,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,UAAU,CAAC,CAAA;IAE/B,IAAA,cAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEhD,wCAAwC;IACxC,MAAM,MAAM,GAAG;QACb,UAAU,EAAE;YACV,kBAAkB,EAAE;gBAClB,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,CAAC,aAAa,CAAC;gBACrB,GAAG,EAAE;oBACH,wBAAwB,EAAE,MAAM;oBAChC,sBAAsB,EAAE,KAAK;oBAC7B,6BAA6B,EAAE,WAAW;iBAC3C;aACF;SACF;KACF,CAAA;IAED,IAAA,kBAAa,EAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACzD,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiClient } from '../api-client';
3
+ /**
4
+ * MCP サーバーを作成する
5
+ */
6
+ export declare function createMcpServer(apiClient: ApiClient, projectCode: string): McpServer;
7
+ /**
8
+ * MCP サーバーを stdio transport で起動する
9
+ */
10
+ export declare function startMcpServer(): Promise<void>;
11
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAMzC;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,CAYpF;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBpD"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMcpServer = createMcpServer;
4
+ exports.startMcpServer = startMcpServer;
5
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
6
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
7
+ const api_client_1 = require("../api-client");
8
+ const credentials_1 = require("./tools/credentials");
9
+ const db_query_1 = require("./tools/db-query");
10
+ const db_schemas_1 = require("./tools/db-schemas");
11
+ const project_info_1 = require("./tools/project-info");
12
+ /**
13
+ * MCP サーバーを作成する
14
+ */
15
+ function createMcpServer(apiClient, projectCode) {
16
+ const server = new mcp_js_1.McpServer({
17
+ name: 'ai-support-agent',
18
+ version: '1.0.0',
19
+ });
20
+ (0, db_query_1.registerDbQueryTool)(server, apiClient);
21
+ (0, db_schemas_1.registerDbSchemasTool)(server, apiClient);
22
+ (0, credentials_1.registerCredentialsTool)(server, apiClient);
23
+ (0, project_info_1.registerProjectInfoTool)(server, apiClient, projectCode);
24
+ return server;
25
+ }
26
+ /**
27
+ * MCP サーバーを stdio transport で起動する
28
+ */
29
+ async function startMcpServer() {
30
+ const apiUrl = process.env.AI_SUPPORT_AGENT_API_URL;
31
+ const token = process.env.AI_SUPPORT_AGENT_TOKEN;
32
+ const projectCode = process.env.AI_SUPPORT_AGENT_PROJECT_CODE;
33
+ if (!apiUrl || !token || !projectCode) {
34
+ const missing = [];
35
+ if (!apiUrl)
36
+ missing.push('AI_SUPPORT_AGENT_API_URL');
37
+ if (!token)
38
+ missing.push('AI_SUPPORT_AGENT_TOKEN');
39
+ if (!projectCode)
40
+ missing.push('AI_SUPPORT_AGENT_PROJECT_CODE');
41
+ throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
42
+ }
43
+ const apiClient = new api_client_1.ApiClient(apiUrl, token);
44
+ const server = createMcpServer(apiClient, projectCode);
45
+ const transport = new stdio_js_1.StdioServerTransport();
46
+ await server.connect(transport);
47
+ }
48
+ // When executed directly
49
+ if (require.main === module) {
50
+ startMcpServer().catch((error) => {
51
+ process.stderr.write(`MCP server error: ${error}\n`);
52
+ process.exit(1);
53
+ });
54
+ }
55
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";;AAYA,0CAYC;AAKD,wCAiBC;AA9CD,oEAAmE;AACnE,wEAAgF;AAEhF,8CAAyC;AACzC,qDAA6D;AAC7D,+CAAsD;AACtD,mDAA0D;AAC1D,uDAA8D;AAE9D;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAoB,EAAE,WAAmB;IACvE,MAAM,MAAM,GAAG,IAAI,kBAAS,CAAC;QAC3B,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,IAAA,8BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,IAAA,kCAAqB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACxC,IAAA,qCAAuB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,IAAA,sCAAuB,EAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAEvD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAA;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;IAChD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAA;IAE7D,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,EAAE,CAAA;QAClB,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;QACrD,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;QAClD,IAAI,CAAC,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;QAC/D,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IACtD,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC;AAED,yBAAyB;AACzB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,IAAI,CAAC,CAAA;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiClient } from '../../api-client';
3
+ /** get_credentials ツールを MCP サーバーに登録する */
4
+ export declare function registerCredentialsTool(server: McpServer, apiClient: ApiClient): void;
5
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,yCAAyC;AACzC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAgDrF"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerCredentialsTool = registerCredentialsTool;
4
+ const zod_1 = require("zod");
5
+ /** get_credentials ツールを MCP サーバーに登録する */
6
+ function registerCredentialsTool(server, apiClient) {
7
+ server.tool('get_credentials', 'Get credentials for a service (AWS or database).', {
8
+ type: zod_1.z.enum(['aws', 'db']).describe('Credential type'),
9
+ name: zod_1.z.string().describe('Identifier (AWS account ID or DB connection name)'),
10
+ }, async ({ type, name }) => {
11
+ try {
12
+ if (type === 'aws') {
13
+ const credentials = await apiClient.getAwsCredentials(name);
14
+ return {
15
+ content: [{
16
+ type: 'text',
17
+ text: JSON.stringify({
18
+ accessKeyId: credentials.accessKeyId,
19
+ secretAccessKey: credentials.secretAccessKey,
20
+ sessionToken: credentials.sessionToken,
21
+ region: credentials.region,
22
+ }, null, 2),
23
+ }],
24
+ };
25
+ }
26
+ if (type === 'db') {
27
+ const credentials = await apiClient.getDbCredentials(name);
28
+ return {
29
+ content: [{
30
+ type: 'text',
31
+ text: JSON.stringify(credentials, null, 2),
32
+ }],
33
+ };
34
+ }
35
+ return {
36
+ content: [{ type: 'text', text: `Error: Unknown credential type: ${type}` }],
37
+ isError: true,
38
+ };
39
+ }
40
+ catch (error) {
41
+ const message = error instanceof Error ? error.message : String(error);
42
+ return {
43
+ content: [{ type: 'text', text: `Error: ${message}` }],
44
+ isError: true,
45
+ };
46
+ }
47
+ });
48
+ }
49
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/mcp/tools/credentials.ts"],"names":[],"mappings":";;AAMA,0DAgDC;AArDD,6BAAuB;AAIvB,yCAAyC;AACzC,SAAgB,uBAAuB,CAAC,MAAiB,EAAE,SAAoB;IAC7E,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,kDAAkD,EAClD;QACE,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACvD,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;KAC/E,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;gBAC3D,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,WAAW,EAAE,WAAW,CAAC,WAAW;gCACpC,eAAe,EAAE,WAAW,CAAC,eAAe;gCAC5C,YAAY,EAAE,WAAW,CAAC,YAAY;gCACtC,MAAM,EAAE,WAAW,CAAC,MAAM;6BAC3B,EAAE,IAAI,EAAE,CAAC,CAAC;yBACZ,CAAC;iBACH,CAAA;YACH,CAAC;YAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;gBAC1D,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC3C,CAAC;iBACH,CAAA;YACH,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,mCAAmC,IAAI,EAAE,EAAE,CAAC;gBACrF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiClient } from '../../api-client';
3
+ import type { DbCredentials } from '../../types';
4
+ /** SQL文が SELECT のみかどうか検証する */
5
+ export declare function validateSelectOnly(sql: string): {
6
+ valid: boolean;
7
+ error?: string;
8
+ };
9
+ /** DB接続を作成してクエリを実行する */
10
+ export declare function executeQuery(credentials: DbCredentials, sql: string): Promise<unknown[]>;
11
+ /** db_query ツールを MCP サーバーに登録する */
12
+ export declare function registerDbQueryTool(server: McpServer, apiClient: ApiClient): void;
13
+ //# sourceMappingURL=db-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-query.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/db-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,8BAA8B;AAC9B,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAuBlF;AAED,wBAAwB;AACxB,wBAAsB,YAAY,CAChC,WAAW,EAAE,aAAa,EAC1B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,EAAE,CAAC,CAwCpB;AAED,kCAAkC;AAClC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAuCjF"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateSelectOnly = validateSelectOnly;
37
+ exports.executeQuery = executeQuery;
38
+ exports.registerDbQueryTool = registerDbQueryTool;
39
+ const zod_1 = require("zod");
40
+ /** SQL文が SELECT のみかどうか検証する */
41
+ function validateSelectOnly(sql) {
42
+ const trimmed = sql.trim();
43
+ if (!trimmed) {
44
+ return { valid: false, error: 'SQL query is empty' };
45
+ }
46
+ // 禁止キーワードをチェック(大文字小文字無視)
47
+ const forbidden = ['DROP', 'DELETE', 'UPDATE', 'INSERT', 'TRUNCATE', 'ALTER', 'CREATE', 'GRANT', 'REVOKE'];
48
+ const upper = trimmed.toUpperCase();
49
+ for (const keyword of forbidden) {
50
+ // 単語境界でマッチ(前後が非単語文字 or 文字列の先頭/末尾)
51
+ const regex = new RegExp(`(?<![A-Z_])${keyword}(?![A-Z_])`);
52
+ if (regex.test(upper)) {
53
+ return { valid: false, error: `Forbidden SQL operation: ${keyword}` };
54
+ }
55
+ }
56
+ // SELECT で始まることを確認(WITH ... SELECT も許可)
57
+ if (!upper.startsWith('SELECT') && !upper.startsWith('WITH') && !upper.startsWith('EXPLAIN')) {
58
+ return { valid: false, error: 'Only SELECT, WITH, and EXPLAIN statements are allowed' };
59
+ }
60
+ return { valid: true };
61
+ }
62
+ /** DB接続を作成してクエリを実行する */
63
+ async function executeQuery(credentials, sql) {
64
+ if (credentials.engine === 'mysql') {
65
+ const mysql2 = await Promise.resolve().then(() => __importStar(require('mysql2/promise')));
66
+ const connection = await mysql2.createConnection({
67
+ host: credentials.host,
68
+ port: credentials.port,
69
+ user: credentials.user,
70
+ password: credentials.password,
71
+ database: credentials.database,
72
+ connectTimeout: 10000,
73
+ });
74
+ try {
75
+ const [rows] = await connection.query(sql);
76
+ return rows;
77
+ }
78
+ finally {
79
+ await connection.end();
80
+ }
81
+ }
82
+ if (credentials.engine === 'postgresql') {
83
+ const { Client } = await Promise.resolve().then(() => __importStar(require('pg')));
84
+ const client = new Client({
85
+ host: credentials.host,
86
+ port: credentials.port,
87
+ user: credentials.user,
88
+ password: credentials.password,
89
+ database: credentials.database,
90
+ connectionTimeoutMillis: 10000,
91
+ ssl: false,
92
+ });
93
+ try {
94
+ await client.connect();
95
+ const result = await client.query(sql);
96
+ return result.rows;
97
+ }
98
+ finally {
99
+ await client.end();
100
+ }
101
+ }
102
+ throw new Error(`Unsupported database engine: ${credentials.engine}`);
103
+ }
104
+ /** db_query ツールを MCP サーバーに登録する */
105
+ function registerDbQueryTool(server, apiClient) {
106
+ server.tool('db_query', 'Execute a SELECT query on a project database. Only SELECT/WITH/EXPLAIN statements are allowed.', {
107
+ name: zod_1.z.string().describe('Database connection name (e.g. "MAIN", "READONLY")'),
108
+ sql: zod_1.z.string().describe('SQL query to execute (SELECT only)'),
109
+ }, async ({ name, sql }) => {
110
+ // Validate SQL
111
+ const validation = validateSelectOnly(sql);
112
+ if (!validation.valid) {
113
+ return {
114
+ content: [{ type: 'text', text: `Error: ${validation.error}` }],
115
+ isError: true,
116
+ };
117
+ }
118
+ try {
119
+ // Get credentials from API
120
+ const credentials = await apiClient.getDbCredentials(name);
121
+ // Execute query
122
+ const rows = await executeQuery(credentials, sql);
123
+ // Format result
124
+ const resultText = JSON.stringify(rows, null, 2);
125
+ return {
126
+ content: [{ type: 'text', text: resultText }],
127
+ };
128
+ }
129
+ catch (error) {
130
+ const message = error instanceof Error ? error.message : String(error);
131
+ return {
132
+ content: [{ type: 'text', text: `Error: ${message}` }],
133
+ isError: true,
134
+ };
135
+ }
136
+ });
137
+ }
138
+ //# sourceMappingURL=db-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-query.js","sourceRoot":"","sources":["../../../src/mcp/tools/db-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiClient } from '../../api-client';
3
+ /** get_db_schemas ツールを MCP サーバーに登録する */
4
+ export declare function registerDbSchemasTool(server: McpServer, apiClient: ApiClient): void;
5
+ //# sourceMappingURL=db-schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schemas.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/db-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAyC5C,wCAAwC;AACxC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CA8BnF"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerDbSchemasTool = registerDbSchemasTool;
4
+ const zod_1 = require("zod");
5
+ const db_query_1 = require("./db-query");
6
+ const MYSQL_SCHEMA_QUERY = `
7
+ SELECT
8
+ TABLE_NAME,
9
+ COLUMN_NAME,
10
+ DATA_TYPE,
11
+ IS_NULLABLE,
12
+ COLUMN_KEY,
13
+ COLUMN_DEFAULT,
14
+ EXTRA
15
+ FROM INFORMATION_SCHEMA.COLUMNS
16
+ WHERE TABLE_SCHEMA = DATABASE()
17
+ ORDER BY TABLE_NAME, ORDINAL_POSITION
18
+ `;
19
+ const PG_SCHEMA_QUERY = `
20
+ SELECT
21
+ c.table_name,
22
+ c.column_name,
23
+ c.data_type,
24
+ c.is_nullable,
25
+ CASE
26
+ WHEN tc.constraint_type = 'PRIMARY KEY' THEN 'PRI'
27
+ WHEN tc.constraint_type = 'UNIQUE' THEN 'UNI'
28
+ ELSE ''
29
+ END AS column_key,
30
+ c.column_default
31
+ FROM information_schema.columns c
32
+ LEFT JOIN information_schema.key_column_usage kcu
33
+ ON c.table_name = kcu.table_name
34
+ AND c.column_name = kcu.column_name
35
+ AND c.table_schema = kcu.table_schema
36
+ LEFT JOIN information_schema.table_constraints tc
37
+ ON kcu.constraint_name = tc.constraint_name
38
+ AND kcu.table_schema = tc.table_schema
39
+ WHERE c.table_schema = 'public'
40
+ ORDER BY c.table_name, c.ordinal_position
41
+ `;
42
+ /** get_db_schemas ツールを MCP サーバーに登録する */
43
+ function registerDbSchemasTool(server, apiClient) {
44
+ server.tool('get_db_schemas', 'Get the schema (tables and columns) of a project database.', {
45
+ name: zod_1.z.string().describe('Database connection name (e.g. "MAIN", "READONLY")'),
46
+ }, async ({ name }) => {
47
+ try {
48
+ const credentials = await apiClient.getDbCredentials(name);
49
+ const query = credentials.engine === 'mysql'
50
+ ? MYSQL_SCHEMA_QUERY
51
+ : PG_SCHEMA_QUERY;
52
+ const rows = await (0, db_query_1.executeQuery)(credentials, query);
53
+ const resultText = JSON.stringify(rows, null, 2);
54
+ return {
55
+ content: [{ type: 'text', text: resultText }],
56
+ };
57
+ }
58
+ catch (error) {
59
+ const message = error instanceof Error ? error.message : String(error);
60
+ return {
61
+ content: [{ type: 'text', text: `Error: ${message}` }],
62
+ isError: true,
63
+ };
64
+ }
65
+ });
66
+ }
67
+ //# sourceMappingURL=db-schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schemas.js","sourceRoot":"","sources":["../../../src/mcp/tools/db-schemas.ts"],"names":[],"mappings":";;AA6CA,sDA8BC;AA1ED,6BAAuB;AAGvB,yCAAyC;AAEzC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;CAY1B,CAAA;AAED,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBvB,CAAA;AAED,wCAAwC;AACxC,SAAgB,qBAAqB,CAAC,MAAiB,EAAE,SAAoB;IAC3E,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,4DAA4D,EAC5D;QACE,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;KAChF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;YAE1D,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,KAAK,OAAO;gBAC1C,CAAC,CAAC,kBAAkB;gBACpB,CAAC,CAAC,eAAe,CAAA;YAEnB,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiClient } from '../../api-client';
3
+ /** get_project_info ツールを MCP サーバーに登録する */
4
+ export declare function registerProjectInfoTool(server: McpServer, apiClient: ApiClient, projectCode: string): void;
5
+ //# sourceMappingURL=project-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-info.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/project-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,0CAA0C;AAC1C,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,GAClB,IAAI,CAuDN"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerProjectInfoTool = registerProjectInfoTool;
4
+ /** get_project_info ツールを MCP サーバーに登録する */
5
+ function registerProjectInfoTool(server, apiClient, projectCode) {
6
+ server.tool('get_project_info', 'Get project configuration information including databases, AWS accounts, and documentation sources.', {}, async () => {
7
+ try {
8
+ const config = await apiClient.getProjectConfig();
9
+ const info = {
10
+ project: config.project,
11
+ };
12
+ if (config.databases?.length) {
13
+ info.databases = config.databases.map((db) => ({
14
+ name: db.name,
15
+ engine: db.engine,
16
+ host: db.host,
17
+ port: db.port,
18
+ database: db.database,
19
+ writePermissions: db.writePermissions,
20
+ }));
21
+ }
22
+ if (config.aws?.accounts?.length) {
23
+ info.awsAccounts = config.aws.accounts.map((acc) => ({
24
+ id: acc.id,
25
+ name: acc.name,
26
+ region: acc.region,
27
+ accountId: acc.accountId,
28
+ isDefault: acc.isDefault,
29
+ }));
30
+ }
31
+ if (config.documentation?.sources?.length) {
32
+ info.documentation = config.documentation;
33
+ }
34
+ info.projectCode = projectCode;
35
+ return {
36
+ content: [{
37
+ type: 'text',
38
+ text: JSON.stringify(info, null, 2),
39
+ }],
40
+ };
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ return {
45
+ content: [{ type: 'text', text: `Error: ${message}` }],
46
+ isError: true,
47
+ };
48
+ }
49
+ });
50
+ }
51
+ //# sourceMappingURL=project-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-info.js","sourceRoot":"","sources":["../../../src/mcp/tools/project-info.ts"],"names":[],"mappings":";;AAKA,0DA2DC;AA5DD,0CAA0C;AAC1C,SAAgB,uBAAuB,CACrC,MAAiB,EACjB,SAAoB,EACpB,WAAmB;IAEnB,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,qGAAqG,EACrG,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,EAAE,CAAA;YAEjD,MAAM,IAAI,GAA4B;gBACpC,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAA;YAED,IAAI,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;gBAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC7C,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,MAAM,EAAE,EAAE,CAAC,MAAM;oBACjB,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,gBAAgB,EAAE,EAAE,CAAC,gBAAgB;iBACtC,CAAC,CAAC,CAAA;YACL,CAAC;YAED,IAAI,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;gBACjC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACnD,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,SAAS,EAAE,GAAG,CAAC,SAAS;iBACzB,CAAC,CAAC,CAAA;YACL,CAAC;YAED,IAAI,MAAM,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC1C,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAA;YAC3C,CAAC;YAED,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;YAE9B,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;qBACpC,CAAC;aACH,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -22,6 +22,10 @@ export declare class ProjectAgent {
22
22
  private currentConfigHash;
23
23
  private configSyncDebounceTimer;
24
24
  private projectConfig;
25
+ private mcpConfigPath;
26
+ private readonly apiUrl;
27
+ private readonly token;
28
+ private readonly projectCode;
25
29
  constructor(project: ProjectRegistration, agentId: string, options: ProjectAgentOptions, tenantCode?: string, localAgentChatMode?: AgentChatMode, defaultProjectDir?: string);
26
30
  start(): void;
27
31
  stop(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"project-agent.d.ts","sourceRoot":"","sources":["../src/project-agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAWxC,OAAO,KAAK,EAAE,aAAa,EAA4C,mBAAmB,EAAoB,MAAM,SAAS,CAAA;AAG7H,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED,qBAAa,YAAY;IAmBrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAnB1B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,kBAAkB,CAAsB;IAChD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,uBAAuB,CAA6C;IAC5E,OAAO,CAAC,aAAa,CAA+C;gBAGlE,OAAO,EAAE,mBAAmB,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,EAC7C,UAAU,CAAC,EAAE,MAAM,EACnB,kBAAkB,CAAC,EAAE,aAAa,EAClC,iBAAiB,CAAC,EAAE,MAAM;IAU5B,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAOZ,SAAS,IAAI,SAAS;YAIR,gBAAgB;YAoChB,qBAAqB;IAuBnC,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,cAAc;YAoCR,kBAAkB;YA2BlB,kBAAkB;IAQhC,OAAO,CAAC,kBAAkB;IASpB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYlC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAenC,OAAO,CAAC,kBAAkB;YA8BZ,cAAc;YAuCd,eAAe;YA8Bf,oBAAoB;CAkBnC"}
1
+ {"version":3,"file":"project-agent.d.ts","sourceRoot":"","sources":["../src/project-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAYxC,OAAO,KAAK,EAAE,aAAa,EAA4C,mBAAmB,EAAoB,MAAM,SAAS,CAAA;AAG7H,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED,qBAAa,YAAY;IAuBrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAvB1B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,kBAAkB,CAAsB;IAChD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,uBAAuB,CAA6C;IAC5E,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;gBAGlC,OAAO,EAAE,mBAAmB,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,EAC7C,UAAU,CAAC,EAAE,MAAM,EACnB,kBAAkB,CAAC,EAAE,aAAa,EAClC,iBAAiB,CAAC,EAAE,MAAM;IAa5B,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAOZ,SAAS,IAAI,SAAS;YAIR,gBAAgB;YA8ChB,qBAAqB;IAuBnC,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,cAAc;YAoCR,kBAAkB;YA2BlB,kBAAkB;IAQhC,OAAO,CAAC,kBAAkB;IASpB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYlC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAenC,OAAO,CAAC,kBAAkB;YAoDZ,cAAc;YAwCd,eAAe;YA8Bf,oBAAoB;CAkBnC"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ProjectAgent = void 0;
37
37
  const os = __importStar(require("os"));
38
+ const path_1 = require("path");
38
39
  const api_client_1 = require("./api-client");
39
40
  const appsync_subscriber_1 = require("./appsync-subscriber");
40
41
  const chat_mode_detector_1 = require("./chat-mode-detector");
@@ -43,6 +44,7 @@ const constants_1 = require("./constants");
43
44
  const i18n_1 = require("./i18n");
44
45
  const logger_1 = require("./logger");
45
46
  const aws_profile_1 = require("./aws-profile");
47
+ const config_writer_1 = require("./mcp/config-writer");
46
48
  const project_config_sync_1 = require("./project-config-sync");
47
49
  const project_dir_1 = require("./project-dir");
48
50
  const system_info_1 = require("./system-info");
@@ -65,6 +67,10 @@ class ProjectAgent {
65
67
  currentConfigHash = undefined;
66
68
  configSyncDebounceTimer = null;
67
69
  projectConfig = undefined;
70
+ mcpConfigPath = undefined;
71
+ apiUrl;
72
+ token;
73
+ projectCode;
68
74
  constructor(project, agentId, options, tenantCode, localAgentChatMode, defaultProjectDir) {
69
75
  this.agentId = agentId;
70
76
  this.options = options;
@@ -72,6 +78,9 @@ class ProjectAgent {
72
78
  this.prefix = `[${project.projectCode}]`;
73
79
  this.tenantCode = tenantCode ?? project.projectCode;
74
80
  this.localAgentChatMode = localAgentChatMode;
81
+ this.apiUrl = project.apiUrl;
82
+ this.token = project.token;
83
+ this.projectCode = project.projectCode;
75
84
  // Always resolve project directory (uses default template if neither is set)
76
85
  this.projectDir = (0, project_dir_1.initProjectDir)(project, defaultProjectDir);
77
86
  }
@@ -114,8 +123,19 @@ class ProjectAgent {
114
123
  logger_1.logger.error((0, i18n_1.t)('runner.registerFailed', { prefix: this.prefix, message: (0, utils_1.getErrorMessage)(error) }));
115
124
  return;
116
125
  }
117
- // Perform initial config sync
118
- await this.performConfigSync();
126
+ // Perform initial config sync with retries
127
+ for (let attempt = 1; attempt <= constants_1.INITIAL_CONFIG_SYNC_MAX_RETRIES; attempt++) {
128
+ await this.performConfigSync();
129
+ if (this.currentConfigHash)
130
+ break;
131
+ if (attempt < constants_1.INITIAL_CONFIG_SYNC_MAX_RETRIES) {
132
+ logger_1.logger.warn(`${this.prefix} Initial config sync attempt ${attempt} failed, retrying...`);
133
+ await new Promise(resolve => setTimeout(resolve, constants_1.INITIAL_CONFIG_SYNC_RETRY_DELAY_MS * attempt));
134
+ }
135
+ }
136
+ if (!this.currentConfigHash) {
137
+ logger_1.logger.warn(`${this.prefix} Initial config sync failed after all retries`);
138
+ }
119
139
  if (result.transportMode === 'realtime' && result.appsyncUrl && result.appsyncApiKey) {
120
140
  logger_1.logger.info(`${this.prefix} Starting subscription mode (realtime)`);
121
141
  await this.startSubscriptionMode(result);
@@ -275,6 +295,21 @@ class ProjectAgent {
275
295
  logger_1.logger.warn(`${this.prefix} Failed to write AWS config: ${(0, utils_1.getErrorMessage)(error)}`);
276
296
  }
277
297
  }
298
+ // Log database configuration
299
+ if (config.databases?.length) {
300
+ logger_1.logger.info(`${this.prefix} Databases configured: ${config.databases.map(db => `${db.name}(${db.engine})`).join(', ')}`);
301
+ }
302
+ // Write MCP config file if project directory and databases are configured
303
+ if (this.projectDir && config.databases?.length) {
304
+ try {
305
+ const mcpServerPath = (0, path_1.join)(__dirname, 'mcp', 'server.js');
306
+ this.mcpConfigPath = (0, config_writer_1.writeMcpConfig)(this.projectDir, this.apiUrl, this.token, this.projectCode, mcpServerPath);
307
+ logger_1.logger.info(`${this.prefix} MCP config written: ${this.mcpConfigPath}`);
308
+ }
309
+ catch (error) {
310
+ logger_1.logger.warn(`${this.prefix} Failed to write MCP config: ${(0, utils_1.getErrorMessage)(error)}`);
311
+ }
312
+ }
278
313
  logger_1.logger.info(`${this.prefix} Config applied (hash: ${config.configHash})`);
279
314
  }
280
315
  async processCommand(commandId) {
@@ -289,6 +324,7 @@ class ProjectAgent {
289
324
  agentId: this.agentId,
290
325
  projectDir: this.projectDir,
291
326
  projectConfig: this.projectConfig,
327
+ mcpConfigPath: this.mcpConfigPath,
292
328
  onSetup: () => this.performSetup(),
293
329
  onConfigSync: () => this.performConfigSync(),
294
330
  });