@itm-platform/mcp-server 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.
Files changed (259) hide show
  1. package/README.md +193 -0
  2. package/bin/mcp-server.js +2 -0
  3. package/dist/audit-config.d.ts +2 -0
  4. package/dist/audit-config.d.ts.map +1 -0
  5. package/dist/audit-config.js +4 -0
  6. package/dist/audit-config.js.map +1 -0
  7. package/dist/auth/api-key-auth.d.ts +3 -0
  8. package/dist/auth/api-key-auth.d.ts.map +1 -0
  9. package/dist/auth/api-key-auth.js +53 -0
  10. package/dist/auth/api-key-auth.js.map +1 -0
  11. package/dist/auth/effective-user-context.d.ts +16 -0
  12. package/dist/auth/effective-user-context.d.ts.map +1 -0
  13. package/dist/auth/effective-user-context.js +9 -0
  14. package/dist/auth/effective-user-context.js.map +1 -0
  15. package/dist/auth/license-resolver.d.ts +6 -0
  16. package/dist/auth/license-resolver.d.ts.map +1 -0
  17. package/dist/auth/license-resolver.js +12 -0
  18. package/dist/auth/license-resolver.js.map +1 -0
  19. package/dist/auth/oauth-auth.d.ts +22 -0
  20. package/dist/auth/oauth-auth.d.ts.map +1 -0
  21. package/dist/auth/oauth-auth.js +34 -0
  22. package/dist/auth/oauth-auth.js.map +1 -0
  23. package/dist/auth/oauth-metadata.d.ts +11 -0
  24. package/dist/auth/oauth-metadata.d.ts.map +1 -0
  25. package/dist/auth/oauth-metadata.js +14 -0
  26. package/dist/auth/oauth-metadata.js.map +1 -0
  27. package/dist/auth/token-extraction.d.ts +2 -0
  28. package/dist/auth/token-extraction.d.ts.map +1 -0
  29. package/dist/auth/token-extraction.js +7 -0
  30. package/dist/auth/token-extraction.js.map +1 -0
  31. package/dist/clients/audit-client.d.ts +25 -0
  32. package/dist/clients/audit-client.d.ts.map +1 -0
  33. package/dist/clients/audit-client.js +37 -0
  34. package/dist/clients/audit-client.js.map +1 -0
  35. package/dist/clients/datamart-client.d.ts +16 -0
  36. package/dist/clients/datamart-client.d.ts.map +1 -0
  37. package/dist/clients/datamart-client.js +32 -0
  38. package/dist/clients/datamart-client.js.map +1 -0
  39. package/dist/clients/index.d.ts +18 -0
  40. package/dist/clients/index.d.ts.map +1 -0
  41. package/dist/clients/index.js +11 -0
  42. package/dist/clients/index.js.map +1 -0
  43. package/dist/clients/rest-client.d.ts +14 -0
  44. package/dist/clients/rest-client.d.ts.map +1 -0
  45. package/dist/clients/rest-client.js +29 -0
  46. package/dist/clients/rest-client.js.map +1 -0
  47. package/dist/gateway.d.ts +2 -0
  48. package/dist/gateway.d.ts.map +1 -0
  49. package/dist/gateway.js +6 -0
  50. package/dist/gateway.js.map +1 -0
  51. package/dist/instrument-server.d.ts +11 -0
  52. package/dist/instrument-server.d.ts.map +1 -0
  53. package/dist/instrument-server.js +51 -0
  54. package/dist/instrument-server.js.map +1 -0
  55. package/dist/logger.d.ts +4 -0
  56. package/dist/logger.d.ts.map +1 -0
  57. package/dist/logger.js +39 -0
  58. package/dist/logger.js.map +1 -0
  59. package/dist/prompts/portfolio-overview.d.ts +3 -0
  60. package/dist/prompts/portfolio-overview.d.ts.map +1 -0
  61. package/dist/prompts/portfolio-overview.js +21 -0
  62. package/dist/prompts/portfolio-overview.js.map +1 -0
  63. package/dist/prompts/project-status.d.ts +3 -0
  64. package/dist/prompts/project-status.d.ts.map +1 -0
  65. package/dist/prompts/project-status.js +24 -0
  66. package/dist/prompts/project-status.js.map +1 -0
  67. package/dist/prompts/risk-analysis.d.ts +3 -0
  68. package/dist/prompts/risk-analysis.d.ts.map +1 -0
  69. package/dist/prompts/risk-analysis.js +23 -0
  70. package/dist/prompts/risk-analysis.js.map +1 -0
  71. package/dist/prompts/team-workload.d.ts +3 -0
  72. package/dist/prompts/team-workload.d.ts.map +1 -0
  73. package/dist/prompts/team-workload.js +29 -0
  74. package/dist/prompts/team-workload.js.map +1 -0
  75. package/dist/resources/calendars.d.ts +4 -0
  76. package/dist/resources/calendars.d.ts.map +1 -0
  77. package/dist/resources/calendars.js +18 -0
  78. package/dist/resources/calendars.js.map +1 -0
  79. package/dist/resources/schemas.d.ts +4 -0
  80. package/dist/resources/schemas.d.ts.map +1 -0
  81. package/dist/resources/schemas.js +34 -0
  82. package/dist/resources/schemas.js.map +1 -0
  83. package/dist/server.d.ts +2 -0
  84. package/dist/server.d.ts.map +1 -0
  85. package/dist/server.js +243 -0
  86. package/dist/server.js.map +1 -0
  87. package/dist/src/auth/api-key-auth.d.ts +3 -0
  88. package/dist/src/auth/api-key-auth.d.ts.map +1 -0
  89. package/dist/src/auth/api-key-auth.js +53 -0
  90. package/dist/src/auth/api-key-auth.js.map +1 -0
  91. package/dist/src/auth/effective-user-context.d.ts +16 -0
  92. package/dist/src/auth/effective-user-context.d.ts.map +1 -0
  93. package/dist/src/auth/effective-user-context.js +9 -0
  94. package/dist/src/auth/effective-user-context.js.map +1 -0
  95. package/dist/src/auth/license-resolver.d.ts +6 -0
  96. package/dist/src/auth/license-resolver.d.ts.map +1 -0
  97. package/dist/src/auth/license-resolver.js +12 -0
  98. package/dist/src/auth/license-resolver.js.map +1 -0
  99. package/dist/src/auth/oauth-auth.d.ts +22 -0
  100. package/dist/src/auth/oauth-auth.d.ts.map +1 -0
  101. package/dist/src/auth/oauth-auth.js +34 -0
  102. package/dist/src/auth/oauth-auth.js.map +1 -0
  103. package/dist/src/auth/oauth-metadata.d.ts +10 -0
  104. package/dist/src/auth/oauth-metadata.d.ts.map +1 -0
  105. package/dist/src/auth/oauth-metadata.js +8 -0
  106. package/dist/src/auth/oauth-metadata.js.map +1 -0
  107. package/dist/src/auth/token-extraction.d.ts +2 -0
  108. package/dist/src/auth/token-extraction.d.ts.map +1 -0
  109. package/dist/src/auth/token-extraction.js +7 -0
  110. package/dist/src/auth/token-extraction.js.map +1 -0
  111. package/dist/src/clients/audit-client.d.ts +25 -0
  112. package/dist/src/clients/audit-client.d.ts.map +1 -0
  113. package/dist/src/clients/audit-client.js +37 -0
  114. package/dist/src/clients/audit-client.js.map +1 -0
  115. package/dist/src/clients/datamart-client.d.ts +16 -0
  116. package/dist/src/clients/datamart-client.d.ts.map +1 -0
  117. package/dist/src/clients/datamart-client.js +32 -0
  118. package/dist/src/clients/datamart-client.js.map +1 -0
  119. package/dist/src/clients/index.d.ts +18 -0
  120. package/dist/src/clients/index.d.ts.map +1 -0
  121. package/dist/src/clients/index.js +11 -0
  122. package/dist/src/clients/index.js.map +1 -0
  123. package/dist/src/clients/rest-client.d.ts +14 -0
  124. package/dist/src/clients/rest-client.d.ts.map +1 -0
  125. package/dist/src/clients/rest-client.js +29 -0
  126. package/dist/src/clients/rest-client.js.map +1 -0
  127. package/dist/src/logger.d.ts +3 -0
  128. package/dist/src/logger.d.ts.map +1 -0
  129. package/dist/src/logger.js +37 -0
  130. package/dist/src/logger.js.map +1 -0
  131. package/dist/src/prompts/portfolio-overview.d.ts +3 -0
  132. package/dist/src/prompts/portfolio-overview.d.ts.map +1 -0
  133. package/dist/src/prompts/portfolio-overview.js +21 -0
  134. package/dist/src/prompts/portfolio-overview.js.map +1 -0
  135. package/dist/src/prompts/project-status.d.ts +3 -0
  136. package/dist/src/prompts/project-status.d.ts.map +1 -0
  137. package/dist/src/prompts/project-status.js +24 -0
  138. package/dist/src/prompts/project-status.js.map +1 -0
  139. package/dist/src/prompts/risk-analysis.d.ts +3 -0
  140. package/dist/src/prompts/risk-analysis.d.ts.map +1 -0
  141. package/dist/src/prompts/risk-analysis.js +23 -0
  142. package/dist/src/prompts/risk-analysis.js.map +1 -0
  143. package/dist/src/prompts/team-workload.d.ts +3 -0
  144. package/dist/src/prompts/team-workload.d.ts.map +1 -0
  145. package/dist/src/prompts/team-workload.js +29 -0
  146. package/dist/src/prompts/team-workload.js.map +1 -0
  147. package/dist/src/resources/calendars.d.ts +4 -0
  148. package/dist/src/resources/calendars.d.ts.map +1 -0
  149. package/dist/src/resources/calendars.js +18 -0
  150. package/dist/src/resources/calendars.js.map +1 -0
  151. package/dist/src/resources/schemas.d.ts +4 -0
  152. package/dist/src/resources/schemas.d.ts.map +1 -0
  153. package/dist/src/resources/schemas.js +34 -0
  154. package/dist/src/resources/schemas.js.map +1 -0
  155. package/dist/src/server.d.ts +2 -0
  156. package/dist/src/server.d.ts.map +1 -0
  157. package/dist/src/server.js +213 -0
  158. package/dist/src/server.js.map +1 -0
  159. package/dist/src/tools/datamart.d.ts +17 -0
  160. package/dist/src/tools/datamart.d.ts.map +1 -0
  161. package/dist/src/tools/datamart.js +68 -0
  162. package/dist/src/tools/datamart.js.map +1 -0
  163. package/dist/src/tools/financials.d.ts +4 -0
  164. package/dist/src/tools/financials.d.ts.map +1 -0
  165. package/dist/src/tools/financials.js +50 -0
  166. package/dist/src/tools/financials.js.map +1 -0
  167. package/dist/src/tools/graphql-queries.d.ts +22 -0
  168. package/dist/src/tools/graphql-queries.d.ts.map +1 -0
  169. package/dist/src/tools/graphql-queries.js +26 -0
  170. package/dist/src/tools/graphql-queries.js.map +1 -0
  171. package/dist/src/tools/portfolio.d.ts +10 -0
  172. package/dist/src/tools/portfolio.d.ts.map +1 -0
  173. package/dist/src/tools/portfolio.js +54 -0
  174. package/dist/src/tools/portfolio.js.map +1 -0
  175. package/dist/src/tools/projects.d.ts +42 -0
  176. package/dist/src/tools/projects.d.ts.map +1 -0
  177. package/dist/src/tools/projects.js +73 -0
  178. package/dist/src/tools/projects.js.map +1 -0
  179. package/dist/src/tools/reference-data.d.ts +4 -0
  180. package/dist/src/tools/reference-data.d.ts.map +1 -0
  181. package/dist/src/tools/reference-data.js +19 -0
  182. package/dist/src/tools/reference-data.js.map +1 -0
  183. package/dist/src/tools/risks-issues.d.ts +4 -0
  184. package/dist/src/tools/risks-issues.d.ts.map +1 -0
  185. package/dist/src/tools/risks-issues.js +33 -0
  186. package/dist/src/tools/risks-issues.js.map +1 -0
  187. package/dist/src/tools/services.d.ts +41 -0
  188. package/dist/src/tools/services.d.ts.map +1 -0
  189. package/dist/src/tools/services.js +67 -0
  190. package/dist/src/tools/services.js.map +1 -0
  191. package/dist/src/tools/tasks.d.ts +4 -0
  192. package/dist/src/tools/tasks.d.ts.map +1 -0
  193. package/dist/src/tools/tasks.js +17 -0
  194. package/dist/src/tools/tasks.js.map +1 -0
  195. package/dist/src/tools/users.d.ts +4 -0
  196. package/dist/src/tools/users.d.ts.map +1 -0
  197. package/dist/src/tools/users.js +30 -0
  198. package/dist/src/tools/users.js.map +1 -0
  199. package/dist/src/tools/write-tools.d.ts +75 -0
  200. package/dist/src/tools/write-tools.d.ts.map +1 -0
  201. package/dist/src/tools/write-tools.js +193 -0
  202. package/dist/src/tools/write-tools.js.map +1 -0
  203. package/dist/src/validation/query-validator.d.ts +15 -0
  204. package/dist/src/validation/query-validator.d.ts.map +1 -0
  205. package/dist/src/validation/query-validator.js +141 -0
  206. package/dist/src/validation/query-validator.js.map +1 -0
  207. package/dist/startup-mode.d.ts +13 -0
  208. package/dist/startup-mode.d.ts.map +1 -0
  209. package/dist/startup-mode.js +17 -0
  210. package/dist/startup-mode.js.map +1 -0
  211. package/dist/tools/datamart.d.ts +17 -0
  212. package/dist/tools/datamart.d.ts.map +1 -0
  213. package/dist/tools/datamart.js +68 -0
  214. package/dist/tools/datamart.js.map +1 -0
  215. package/dist/tools/financials.d.ts +4 -0
  216. package/dist/tools/financials.d.ts.map +1 -0
  217. package/dist/tools/financials.js +50 -0
  218. package/dist/tools/financials.js.map +1 -0
  219. package/dist/tools/graphql-queries.d.ts +22 -0
  220. package/dist/tools/graphql-queries.d.ts.map +1 -0
  221. package/dist/tools/graphql-queries.js +26 -0
  222. package/dist/tools/graphql-queries.js.map +1 -0
  223. package/dist/tools/portfolio.d.ts +10 -0
  224. package/dist/tools/portfolio.d.ts.map +1 -0
  225. package/dist/tools/portfolio.js +54 -0
  226. package/dist/tools/portfolio.js.map +1 -0
  227. package/dist/tools/projects.d.ts +42 -0
  228. package/dist/tools/projects.d.ts.map +1 -0
  229. package/dist/tools/projects.js +73 -0
  230. package/dist/tools/projects.js.map +1 -0
  231. package/dist/tools/reference-data.d.ts +4 -0
  232. package/dist/tools/reference-data.d.ts.map +1 -0
  233. package/dist/tools/reference-data.js +20 -0
  234. package/dist/tools/reference-data.js.map +1 -0
  235. package/dist/tools/risks-issues.d.ts +4 -0
  236. package/dist/tools/risks-issues.d.ts.map +1 -0
  237. package/dist/tools/risks-issues.js +33 -0
  238. package/dist/tools/risks-issues.js.map +1 -0
  239. package/dist/tools/services.d.ts +41 -0
  240. package/dist/tools/services.d.ts.map +1 -0
  241. package/dist/tools/services.js +67 -0
  242. package/dist/tools/services.js.map +1 -0
  243. package/dist/tools/tasks.d.ts +4 -0
  244. package/dist/tools/tasks.d.ts.map +1 -0
  245. package/dist/tools/tasks.js +17 -0
  246. package/dist/tools/tasks.js.map +1 -0
  247. package/dist/tools/users.d.ts +4 -0
  248. package/dist/tools/users.d.ts.map +1 -0
  249. package/dist/tools/users.js +30 -0
  250. package/dist/tools/users.js.map +1 -0
  251. package/dist/tools/write-tools.d.ts +74 -0
  252. package/dist/tools/write-tools.d.ts.map +1 -0
  253. package/dist/tools/write-tools.js +342 -0
  254. package/dist/tools/write-tools.js.map +1 -0
  255. package/dist/validation/query-validator.d.ts +15 -0
  256. package/dist/validation/query-validator.d.ts.map +1 -0
  257. package/dist/validation/query-validator.js +141 -0
  258. package/dist/validation/query-validator.js.map +1 -0
  259. package/package.json +45 -0
package/dist/server.js ADDED
@@ -0,0 +1,243 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
+ import { createServer } from 'node:http';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { createLogger } from './logger.js';
7
+ import { resolveIdentity } from './auth/api-key-auth.js';
8
+ import { createClients } from './clients/index.js';
9
+ import { registerProjectTools } from './tools/projects.js';
10
+ import { registerServiceTools } from './tools/services.js';
11
+ import { registerTaskTools } from './tools/tasks.js';
12
+ import { registerFinancialTools } from './tools/financials.js';
13
+ import { registerRisksIssuesTools } from './tools/risks-issues.js';
14
+ import { registerPortfolioTools } from './tools/portfolio.js';
15
+ import { registerDataMartTool } from './tools/datamart.js';
16
+ import { registerUserTools } from './tools/users.js';
17
+ import { registerReferenceDataTools } from './tools/reference-data.js';
18
+ import { registerWriteTools } from './tools/write-tools.js';
19
+ import { registerSchemaResources } from './resources/schemas.js';
20
+ import { registerCalendarResources } from './resources/calendars.js';
21
+ import { registerProjectStatusPrompt } from './prompts/project-status.js';
22
+ import { registerPortfolioOverviewPrompt } from './prompts/portfolio-overview.js';
23
+ import { registerTeamWorkloadPrompt } from './prompts/team-workload.js';
24
+ import { registerRiskAnalysisPrompt } from './prompts/risk-analysis.js';
25
+ import { buildProtectedResourceMetadata, buildResourceMetadataUrl } from './auth/oauth-metadata.js';
26
+ import { resolveRoute } from './gateway.js';
27
+ import { extractBearerToken } from './auth/token-extraction.js';
28
+ import { exchangeToken, buildEffectiveUserContextFromExchange } from './auth/oauth-auth.js';
29
+ import { createAuditClient } from './clients/audit-client.js';
30
+ import { hasScope } from './auth/effective-user-context.js';
31
+ import { isAuditEnabled } from './audit-config.js';
32
+ import { instrumentServer } from './instrument-server.js';
33
+ import { resolveStartupMode } from './startup-mode.js';
34
+ const log = createLogger('mcp');
35
+ function createMcpServer(clients, writeCtx, userContext) {
36
+ const server = new McpServer({ name: 'itm-platform', version: '1.0.0' }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
37
+ instrumentServer(server, log, writeCtx, clients.audit);
38
+ registerProjectTools(server, clients);
39
+ registerServiceTools(server, clients);
40
+ registerTaskTools(server, clients);
41
+ registerFinancialTools(server, clients);
42
+ registerRisksIssuesTools(server, clients);
43
+ registerPortfolioTools(server, clients);
44
+ registerDataMartTool(server, clients);
45
+ registerUserTools(server, clients);
46
+ registerReferenceDataTools(server, clients);
47
+ if (hasScope(userContext, 'mcp:write')) {
48
+ registerWriteTools(server, clients, userContext);
49
+ }
50
+ registerSchemaResources(server, clients);
51
+ registerCalendarResources(server, clients);
52
+ registerProjectStatusPrompt(server);
53
+ registerPortfolioOverviewPrompt(server);
54
+ registerTeamWorkloadPrompt(server);
55
+ registerRiskAnalysisPrompt(server);
56
+ return server;
57
+ }
58
+ function buildClientsForUser(userContext) {
59
+ const auditEnabled = isAuditEnabled();
60
+ const audit = auditEnabled
61
+ ? createAuditClient({
62
+ apiUrl: process.env.ITM_API_URL,
63
+ company: userContext.company,
64
+ authHeaders: userContext.authHeaders,
65
+ log,
66
+ })
67
+ : undefined;
68
+ return createClients({
69
+ apiUrl: process.env.ITM_API_URL,
70
+ company: userContext.company,
71
+ authHeaders: userContext.authHeaders,
72
+ log,
73
+ }, audit);
74
+ }
75
+ async function main() {
76
+ log.info('ITM Platform MCP server starting...');
77
+ const startupMode = resolveStartupMode(process.env, process.argv);
78
+ if (startupMode.mode === 'stdio') {
79
+ let userContext;
80
+ try {
81
+ userContext = await resolveIdentity();
82
+ log.info({ userId: userContext.userId, email: userContext.email, access: userContext.dataMartAccess }, 'Identity resolved');
83
+ }
84
+ catch (err) {
85
+ log.fatal({ err }, 'Failed to resolve identity');
86
+ process.exit(1);
87
+ }
88
+ const clients = buildClientsForUser(userContext);
89
+ const writeCtx = {
90
+ userId: userContext.userId,
91
+ accountId: userContext.accountId,
92
+ aiClientId: 'stdio',
93
+ };
94
+ const server = createMcpServer(clients, writeCtx, userContext);
95
+ const transport = new StdioServerTransport();
96
+ await server.connect(transport);
97
+ log.info({ transport: 'stdio' }, 'MCP server connected via stdio');
98
+ return;
99
+ }
100
+ // HTTP modes: http-dev or http-oauth
101
+ const { port } = startupMode;
102
+ let fallbackContext;
103
+ let fallbackClients;
104
+ if (startupMode.mode === 'http-dev') {
105
+ log.warn('HTTP mode without OAuth -- all sessions use startup identity (dev only)');
106
+ try {
107
+ fallbackContext = await resolveIdentity();
108
+ fallbackClients = buildClientsForUser(fallbackContext);
109
+ log.info({ userId: fallbackContext.userId, email: fallbackContext.email, access: fallbackContext.dataMartAccess }, 'Identity resolved');
110
+ }
111
+ catch (err) {
112
+ log.fatal({ err }, 'Failed to resolve identity');
113
+ process.exit(1);
114
+ }
115
+ }
116
+ const oauthConfig = startupMode.mode === 'http-oauth' ? startupMode.oauthConfig : undefined;
117
+ const sessions = new Map();
118
+ if (oauthConfig) {
119
+ log.info('OAuth configured -- per-session auth enabled');
120
+ }
121
+ const httpServer = createServer(async (req, res) => {
122
+ try {
123
+ const route = resolveRoute(req.url ?? '/');
124
+ if (req.method === 'GET' && route === '/.well-known/oauth-protected-resource') {
125
+ if (!oauthConfig) {
126
+ res.writeHead(404, { 'Content-Type': 'application/json' });
127
+ res.end(JSON.stringify({ error: 'OAuth not configured' }));
128
+ return;
129
+ }
130
+ const metadata = buildProtectedResourceMetadata({
131
+ mcpServerUrl: process.env.MCP_SERVER_URL,
132
+ authorizationServerUrl: process.env.ITM_AUTH_PUBLIC_URL || process.env.ITM_AUTH_URL,
133
+ });
134
+ res.writeHead(200, { 'Content-Type': 'application/json' });
135
+ res.end(JSON.stringify(metadata));
136
+ return;
137
+ }
138
+ if (req.method === 'POST' && route === '/') {
139
+ const body = await new Promise((resolve) => {
140
+ let data = '';
141
+ req.on('data', (chunk) => { data += chunk.toString(); });
142
+ req.on('end', () => resolve(data));
143
+ });
144
+ const parsed = JSON.parse(body);
145
+ const sessionId = req.headers['mcp-session-id'];
146
+ let transport;
147
+ if (sessionId && sessions.has(sessionId)) {
148
+ transport = sessions.get(sessionId).transport;
149
+ }
150
+ else if (!sessionId && parsed.method === 'initialize') {
151
+ let sessionUserContext;
152
+ let sessionClients;
153
+ const aiClientId = parsed.params?.clientInfo?.name ?? 'unknown';
154
+ if (oauthConfig) {
155
+ const oauthToken = extractBearerToken(req.headers);
156
+ if (!oauthToken) {
157
+ const resourceMetadataUrl = buildResourceMetadataUrl(process.env.MCP_SERVER_URL);
158
+ res.writeHead(401, {
159
+ 'Content-Type': 'application/json',
160
+ 'WWW-Authenticate': `Bearer resource_metadata="${resourceMetadataUrl}"`,
161
+ });
162
+ res.end(JSON.stringify({ error: 'Authentication required' }));
163
+ return;
164
+ }
165
+ try {
166
+ const exchangeResult = await exchangeToken(oauthToken, oauthConfig, log);
167
+ sessionUserContext = buildEffectiveUserContextFromExchange(exchangeResult);
168
+ sessionClients = buildClientsForUser(sessionUserContext);
169
+ log.info({ userId: sessionUserContext.userId, email: sessionUserContext.email }, 'Per-session auth resolved');
170
+ }
171
+ catch (err) {
172
+ log.error({ err }, 'OAuth token exchange failed');
173
+ const resourceMetadataUrl = buildResourceMetadataUrl(process.env.MCP_SERVER_URL);
174
+ res.writeHead(401, {
175
+ 'Content-Type': 'application/json',
176
+ 'WWW-Authenticate': `Bearer resource_metadata="${resourceMetadataUrl}"`,
177
+ });
178
+ res.end(JSON.stringify({ error: 'Authentication failed' }));
179
+ return;
180
+ }
181
+ }
182
+ else {
183
+ sessionUserContext = fallbackContext;
184
+ sessionClients = fallbackClients;
185
+ }
186
+ const writeCtx = {
187
+ userId: sessionUserContext.userId,
188
+ accountId: sessionUserContext.accountId,
189
+ aiClientId,
190
+ };
191
+ const server = createMcpServer(sessionClients, writeCtx, sessionUserContext);
192
+ transport = new StreamableHTTPServerTransport({
193
+ sessionIdGenerator: () => randomUUID(),
194
+ enableJsonResponse: true,
195
+ });
196
+ transport.onclose = () => {
197
+ if (transport.sessionId)
198
+ sessions.delete(transport.sessionId);
199
+ };
200
+ await server.connect(transport);
201
+ await transport.handleRequest(req, res, parsed);
202
+ if (transport.sessionId) {
203
+ sessions.set(transport.sessionId, { server, transport });
204
+ log.debug({ sessionId: transport.sessionId, aiClientId }, 'Session created');
205
+ }
206
+ return;
207
+ }
208
+ else {
209
+ res.writeHead(400, { 'Content-Type': 'application/json' });
210
+ res.end(JSON.stringify({ error: 'Missing or invalid session' }));
211
+ return;
212
+ }
213
+ await transport.handleRequest(req, res, parsed);
214
+ }
215
+ else if (req.method === 'GET' && route === '/health') {
216
+ const health = { status: 'ok' };
217
+ if (fallbackContext)
218
+ health.user = fallbackContext.email;
219
+ res.writeHead(200, { 'Content-Type': 'application/json' });
220
+ res.end(JSON.stringify(health));
221
+ }
222
+ else {
223
+ res.writeHead(404);
224
+ res.end();
225
+ }
226
+ }
227
+ catch (err) {
228
+ log.error({ err }, 'HTTP request error');
229
+ if (!res.headersSent) {
230
+ res.writeHead(500, { 'Content-Type': 'application/json' });
231
+ res.end(JSON.stringify({ error: 'Internal server error' }));
232
+ }
233
+ }
234
+ });
235
+ httpServer.listen(port, () => {
236
+ log.info({ port, transport: 'http' }, `MCP server listening on http://localhost:${port}/`);
237
+ });
238
+ }
239
+ main().catch((err) => {
240
+ log.fatal({ err }, 'Unhandled error');
241
+ process.exit(1);
242
+ });
243
+ //# 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,3 @@
1
+ import { EffectiveUserContext } from './effective-user-context.js';
2
+ export declare function resolveIdentity(): Promise<EffectiveUserContext>;
3
+ //# sourceMappingURL=api-key-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-auth.d.ts","sourceRoot":"","sources":["../../../src/auth/api-key-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AA0BnE,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA6CrE"}
@@ -0,0 +1,53 @@
1
+ import { resolveLicenseAccess } from './license-resolver.js';
2
+ function resolveAuthHeaders() {
3
+ const apiKey = process.env.ITM_API_KEY;
4
+ const token = process.env.ITM_TOKEN;
5
+ if (apiKey) {
6
+ return { source: 'api-key', headers: { 'Authorization': `Bearer ${apiKey}` } };
7
+ }
8
+ if (token) {
9
+ return { source: 'token', headers: { 'Token': token } };
10
+ }
11
+ throw new Error('Missing required environment variable: ITM_API_KEY or ITM_TOKEN');
12
+ }
13
+ export async function resolveIdentity() {
14
+ const apiUrl = process.env.ITM_API_URL;
15
+ const company = process.env.ITM_COMPANY;
16
+ if (!apiUrl)
17
+ throw new Error('Missing required environment variable: ITM_API_URL');
18
+ if (!company)
19
+ throw new Error('Missing required environment variable: ITM_COMPANY');
20
+ const { source, headers: authHeaders } = resolveAuthHeaders();
21
+ const url = `${apiUrl}/v2/${company}/resolve/identity`;
22
+ const response = await fetch(url, {
23
+ method: 'POST',
24
+ headers: {
25
+ ...authHeaders,
26
+ 'Content-Type': 'application/json',
27
+ },
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`Identity resolution failed: ${response.status} ${response.statusText}`);
31
+ }
32
+ const identity = await response.json();
33
+ const { dataMartAccess, pmScopeUserId } = resolveLicenseAccess(identity.licenseTypeIds, identity.userId);
34
+ if (dataMartAccess === 'pm-scoped') {
35
+ throw new Error('PM-only access is not yet available for MCP. It will arrive with hosted MCP (Phase 2) or gateway scope injection.');
36
+ }
37
+ if (dataMartAccess === 'none') {
38
+ throw new Error('Team Member access is not available for MCP.');
39
+ }
40
+ return {
41
+ source,
42
+ company,
43
+ accountId: identity.accountId,
44
+ userId: identity.userId,
45
+ languageId: identity.languageId,
46
+ email: identity.email,
47
+ licenseTypeIds: identity.licenseTypeIds,
48
+ dataMartAccess,
49
+ pmScopeUserId,
50
+ authHeaders,
51
+ };
52
+ }
53
+ //# sourceMappingURL=api-key-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-auth.js","sourceRoot":"","sources":["../../../src/auth/api-key-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAY7D,SAAS,kBAAkB;IACzB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;IAEpC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,MAAM,EAAE,EAAE,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;IAC1D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACnF,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAEpF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAE9D,MAAM,GAAG,GAAG,GAAG,MAAM,OAAO,OAAO,mBAAmB,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,GAAG,WAAW;YACd,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,QAAQ,GAAqB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEzG,IAAI,cAAc,KAAK,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO;QACL,MAAM;QACN,OAAO;QACP,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,cAAc;QACd,aAAa;QACb,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface EffectiveUserContext {
2
+ source: 'api-key' | 'token';
3
+ company: string;
4
+ accountId: number;
5
+ userId: number;
6
+ languageId: number;
7
+ email: string;
8
+ licenseTypeIds: number[];
9
+ dataMartAccess: 'full' | 'pm-scoped' | 'none';
10
+ pmScopeUserId?: number;
11
+ authHeaders: Record<string, string>;
12
+ grantedScopes?: string[];
13
+ }
14
+ export declare const WRITE_TOOL_NAMES: Set<string>;
15
+ export declare function hasScope(ctx: EffectiveUserContext, scope: string): boolean;
16
+ //# sourceMappingURL=effective-user-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effective-user-context.d.ts","sourceRoot":"","sources":["../../../src/auth/effective-user-context.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,aAE3B,CAAC;AAEH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1E"}
@@ -0,0 +1,9 @@
1
+ export const WRITE_TOOL_NAMES = new Set([
2
+ 'create_task', 'update_task', 'create_risk', 'create_issue', 'update_project',
3
+ ]);
4
+ export function hasScope(ctx, scope) {
5
+ if (!ctx.grantedScopes)
6
+ return true;
7
+ return ctx.grantedScopes.includes(scope);
8
+ }
9
+ //# sourceMappingURL=effective-user-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effective-user-context.js","sourceRoot":"","sources":["../../../src/auth/effective-user-context.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACtC,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB;CAC9E,CAAC,CAAC;AAEH,MAAM,UAAU,QAAQ,CAAC,GAAyB,EAAE,KAAa;IAC/D,IAAI,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface LicenseAccessResult {
2
+ dataMartAccess: 'full' | 'pm-scoped' | 'none';
3
+ pmScopeUserId?: number;
4
+ }
5
+ export declare function resolveLicenseAccess(licenseTypeIds: number[], userId: number): LicenseAccessResult;
6
+ //# sourceMappingURL=license-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-resolver.d.ts","sourceRoot":"","sources":["../../../src/auth/license-resolver.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAQlG"}
@@ -0,0 +1,12 @@
1
+ const FULL_ACCESS_TYPES = new Set([0, 1]);
2
+ const PM_TYPE = 2;
3
+ export function resolveLicenseAccess(licenseTypeIds, userId) {
4
+ if (licenseTypeIds.some(id => FULL_ACCESS_TYPES.has(id))) {
5
+ return { dataMartAccess: 'full' };
6
+ }
7
+ if (licenseTypeIds.includes(PM_TYPE)) {
8
+ return { dataMartAccess: 'pm-scoped', pmScopeUserId: userId };
9
+ }
10
+ return { dataMartAccess: 'none' };
11
+ }
12
+ //# sourceMappingURL=license-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-resolver.js","sourceRoot":"","sources":["../../../src/auth/license-resolver.ts"],"names":[],"mappings":"AAKA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1C,MAAM,OAAO,GAAG,CAAC,CAAC;AAElB,MAAM,UAAU,oBAAoB,CAAC,cAAwB,EAAE,MAAc;IAC3E,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Logger } from 'pino';
2
+ import type { EffectiveUserContext } from './effective-user-context.js';
3
+ export interface TokenExchangeResult {
4
+ sessionToken: string;
5
+ userId: number;
6
+ accountId: number;
7
+ company: string;
8
+ email: string;
9
+ languageId: number;
10
+ licenseTypeIds: number[];
11
+ dataMartAccess: 'full' | 'pm-scoped' | 'none';
12
+ pmScopeUserId?: number;
13
+ expiresAt: string;
14
+ scope: string;
15
+ }
16
+ export interface OAuthConfig {
17
+ tokenExchangeUrl: string;
18
+ audience: string;
19
+ }
20
+ export declare function exchangeToken(oauthToken: string, config: OAuthConfig, log?: Logger): Promise<TokenExchangeResult>;
21
+ export declare function buildEffectiveUserContextFromExchange(result: TokenExchangeResult): EffectiveUserContext;
22
+ //# sourceMappingURL=oauth-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-auth.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,EACnB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,CAAC,CAoB9B;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CAcvG"}
@@ -0,0 +1,34 @@
1
+ export async function exchangeToken(oauthToken, config, log) {
2
+ log?.debug({ url: config.tokenExchangeUrl }, 'Token exchange request');
3
+ const response = await fetch(config.tokenExchangeUrl, {
4
+ method: 'POST',
5
+ headers: {
6
+ 'Content-Type': 'application/json',
7
+ 'Authorization': `Bearer ${oauthToken}`,
8
+ },
9
+ body: JSON.stringify({ audience: config.audience }),
10
+ });
11
+ if (!response.ok) {
12
+ log?.error({ status: response.status }, 'Token exchange failed');
13
+ throw new Error(`Token exchange failed: ${response.status} ${response.statusText}`);
14
+ }
15
+ const result = await response.json();
16
+ log?.info({ userId: result.userId, company: result.company }, 'Token exchange succeeded');
17
+ return result;
18
+ }
19
+ export function buildEffectiveUserContextFromExchange(result) {
20
+ return {
21
+ source: 'token',
22
+ company: result.company,
23
+ accountId: result.accountId,
24
+ userId: result.userId,
25
+ languageId: result.languageId,
26
+ email: result.email,
27
+ licenseTypeIds: result.licenseTypeIds,
28
+ dataMartAccess: result.dataMartAccess,
29
+ pmScopeUserId: result.pmScopeUserId,
30
+ grantedScopes: result.scope.split(' ').filter(Boolean),
31
+ authHeaders: { 'Token': result.sessionToken },
32
+ };
33
+ }
34
+ //# sourceMappingURL=oauth-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-auth.js","sourceRoot":"","sources":["../../../src/auth/oauth-auth.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAkB,EAClB,MAAmB,EACnB,GAAY;IAEZ,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,wBAAwB,CAAC,CAAC;IAEvE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE;QACpD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,eAAe,EAAE,UAAU,UAAU,EAAE;SACxC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;KACpD,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,CAAC;IAC5D,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,0BAA0B,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,MAA2B;IAC/E,OAAO;QACL,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACtD,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE;KAC9C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface ProtectedResourceMetadata {
2
+ resource: string;
3
+ authorization_servers: string[];
4
+ scopes_supported: string[];
5
+ }
6
+ export declare function buildProtectedResourceMetadata(config: {
7
+ mcpServerUrl: string;
8
+ authorizationServerUrl: string;
9
+ }): ProtectedResourceMetadata;
10
+ //# sourceMappingURL=oauth-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-metadata.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth-metadata.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,MAAM,CAAC;CAChC,GAAG,yBAAyB,CAM5B"}
@@ -0,0 +1,8 @@
1
+ export function buildProtectedResourceMetadata(config) {
2
+ return {
3
+ resource: config.mcpServerUrl,
4
+ authorization_servers: [config.authorizationServerUrl],
5
+ scopes_supported: ['mcp:read', 'mcp:write'],
6
+ };
7
+ }
8
+ //# sourceMappingURL=oauth-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-metadata.js","sourceRoot":"","sources":["../../../src/auth/oauth-metadata.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,8BAA8B,CAAC,MAG9C;IACC,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,YAAY;QAC7B,qBAAqB,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC;QACtD,gBAAgB,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function extractBearerToken(headers: Record<string, string | undefined>): string | undefined;
2
+ //# sourceMappingURL=token-extraction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-extraction.d.ts","sourceRoot":"","sources":["../../../src/auth/token-extraction.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAIlG"}
@@ -0,0 +1,7 @@
1
+ export function extractBearerToken(headers) {
2
+ const auth = headers.authorization;
3
+ if (auth?.startsWith('Bearer '))
4
+ return auth.slice(7);
5
+ return undefined;
6
+ }
7
+ //# sourceMappingURL=token-extraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-extraction.js","sourceRoot":"","sources":["../../../src/auth/token-extraction.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,OAA2C;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IACnC,IAAI,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { Logger } from 'pino';
2
+ export interface AuditClientConfig {
3
+ apiUrl: string;
4
+ company: string;
5
+ authHeaders: Record<string, string>;
6
+ log?: Logger;
7
+ }
8
+ export interface AuditEntry {
9
+ timestamp: string;
10
+ userId: number;
11
+ accountId: number;
12
+ toolName: string;
13
+ parametersHash: string;
14
+ success: boolean;
15
+ error?: string;
16
+ aiClientId: string;
17
+ durationMs: number;
18
+ }
19
+ export interface AuditClient {
20
+ log(entry: AuditEntry): Promise<void>;
21
+ }
22
+ export declare function hashParameters(params: unknown): string;
23
+ export declare function createAuditClient(config: AuditClientConfig): AuditClient;
24
+ export declare function createNoOpAuditClient(): AuditClient;
25
+ //# sourceMappingURL=audit-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-client.d.ts","sourceRoot":"","sources":["../../../src/clients/audit-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CA0BxE;AAED,wBAAgB,qBAAqB,IAAI,WAAW,CAInD"}
@@ -0,0 +1,37 @@
1
+ import { createHash } from 'node:crypto';
2
+ export function hashParameters(params) {
3
+ return createHash('sha256').update(JSON.stringify(params)).digest('hex');
4
+ }
5
+ export function createAuditClient(config) {
6
+ const url = `${config.apiUrl}/v2/${config.company}/mcp/audit`;
7
+ const headers = {
8
+ ...config.authHeaders,
9
+ 'Content-Type': 'application/json',
10
+ };
11
+ const log = config.log;
12
+ return {
13
+ async log(entry) {
14
+ try {
15
+ const response = await fetch(url, {
16
+ method: 'POST',
17
+ headers,
18
+ body: JSON.stringify(entry),
19
+ });
20
+ if (!response.ok) {
21
+ log?.warn({ status: response.status, toolName: entry.toolName }, 'Audit POST failed');
22
+ return;
23
+ }
24
+ log?.debug({ toolName: entry.toolName }, 'Audit entry logged');
25
+ }
26
+ catch (err) {
27
+ log?.warn({ err, toolName: entry.toolName }, 'Audit POST error');
28
+ }
29
+ },
30
+ };
31
+ }
32
+ export function createNoOpAuditClient() {
33
+ return {
34
+ async log() { },
35
+ };
36
+ }
37
+ //# sourceMappingURL=audit-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-client.js","sourceRoot":"","sources":["../../../src/clients/audit-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0BzC,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,OAAO,YAAY,CAAC;IAC9D,MAAM,OAAO,GAA2B;QACtC,GAAG,MAAM,CAAC,WAAW;QACrB,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAEvB,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,KAAiB;YACzB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAChC,MAAM,EAAE,MAAM;oBACd,OAAO;oBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;iBAC5B,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,mBAAmB,CAAC,CAAC;oBACtF,OAAO;gBACT,CAAC;gBACD,GAAG,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,oBAAoB,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,kBAAkB,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,KAAK,CAAC,GAAG,KAAmB,CAAC;KAC9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Logger } from 'pino';
2
+ export interface DataMartClientConfig {
3
+ apiUrl: string;
4
+ company: string;
5
+ authHeaders: Record<string, string>;
6
+ log?: Logger;
7
+ }
8
+ export interface DataMartQuery {
9
+ query: string;
10
+ variables: Record<string, unknown>;
11
+ }
12
+ export interface DataMartClient {
13
+ query(body: DataMartQuery): Promise<Record<string, unknown>>;
14
+ }
15
+ export declare function createDataMartClient(config: DataMartClientConfig): DataMartClient;
16
+ //# sourceMappingURL=datamart-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datamart-client.d.ts","sourceRoot":"","sources":["../../../src/clients/datamart-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAmCjF"}