@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.
- package/README.md +193 -0
- package/bin/mcp-server.js +2 -0
- package/dist/audit-config.d.ts +2 -0
- package/dist/audit-config.d.ts.map +1 -0
- package/dist/audit-config.js +4 -0
- package/dist/audit-config.js.map +1 -0
- package/dist/auth/api-key-auth.d.ts +3 -0
- package/dist/auth/api-key-auth.d.ts.map +1 -0
- package/dist/auth/api-key-auth.js +53 -0
- package/dist/auth/api-key-auth.js.map +1 -0
- package/dist/auth/effective-user-context.d.ts +16 -0
- package/dist/auth/effective-user-context.d.ts.map +1 -0
- package/dist/auth/effective-user-context.js +9 -0
- package/dist/auth/effective-user-context.js.map +1 -0
- package/dist/auth/license-resolver.d.ts +6 -0
- package/dist/auth/license-resolver.d.ts.map +1 -0
- package/dist/auth/license-resolver.js +12 -0
- package/dist/auth/license-resolver.js.map +1 -0
- package/dist/auth/oauth-auth.d.ts +22 -0
- package/dist/auth/oauth-auth.d.ts.map +1 -0
- package/dist/auth/oauth-auth.js +34 -0
- package/dist/auth/oauth-auth.js.map +1 -0
- package/dist/auth/oauth-metadata.d.ts +11 -0
- package/dist/auth/oauth-metadata.d.ts.map +1 -0
- package/dist/auth/oauth-metadata.js +14 -0
- package/dist/auth/oauth-metadata.js.map +1 -0
- package/dist/auth/token-extraction.d.ts +2 -0
- package/dist/auth/token-extraction.d.ts.map +1 -0
- package/dist/auth/token-extraction.js +7 -0
- package/dist/auth/token-extraction.js.map +1 -0
- package/dist/clients/audit-client.d.ts +25 -0
- package/dist/clients/audit-client.d.ts.map +1 -0
- package/dist/clients/audit-client.js +37 -0
- package/dist/clients/audit-client.js.map +1 -0
- package/dist/clients/datamart-client.d.ts +16 -0
- package/dist/clients/datamart-client.d.ts.map +1 -0
- package/dist/clients/datamart-client.js +32 -0
- package/dist/clients/datamart-client.js.map +1 -0
- package/dist/clients/index.d.ts +18 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +11 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/rest-client.d.ts +14 -0
- package/dist/clients/rest-client.d.ts.map +1 -0
- package/dist/clients/rest-client.js +29 -0
- package/dist/clients/rest-client.js.map +1 -0
- package/dist/gateway.d.ts +2 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +6 -0
- package/dist/gateway.js.map +1 -0
- package/dist/instrument-server.d.ts +11 -0
- package/dist/instrument-server.d.ts.map +1 -0
- package/dist/instrument-server.js +51 -0
- package/dist/instrument-server.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +39 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompts/portfolio-overview.d.ts +3 -0
- package/dist/prompts/portfolio-overview.d.ts.map +1 -0
- package/dist/prompts/portfolio-overview.js +21 -0
- package/dist/prompts/portfolio-overview.js.map +1 -0
- package/dist/prompts/project-status.d.ts +3 -0
- package/dist/prompts/project-status.d.ts.map +1 -0
- package/dist/prompts/project-status.js +24 -0
- package/dist/prompts/project-status.js.map +1 -0
- package/dist/prompts/risk-analysis.d.ts +3 -0
- package/dist/prompts/risk-analysis.d.ts.map +1 -0
- package/dist/prompts/risk-analysis.js +23 -0
- package/dist/prompts/risk-analysis.js.map +1 -0
- package/dist/prompts/team-workload.d.ts +3 -0
- package/dist/prompts/team-workload.d.ts.map +1 -0
- package/dist/prompts/team-workload.js +29 -0
- package/dist/prompts/team-workload.js.map +1 -0
- package/dist/resources/calendars.d.ts +4 -0
- package/dist/resources/calendars.d.ts.map +1 -0
- package/dist/resources/calendars.js +18 -0
- package/dist/resources/calendars.js.map +1 -0
- package/dist/resources/schemas.d.ts +4 -0
- package/dist/resources/schemas.d.ts.map +1 -0
- package/dist/resources/schemas.js +34 -0
- package/dist/resources/schemas.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +243 -0
- package/dist/server.js.map +1 -0
- package/dist/src/auth/api-key-auth.d.ts +3 -0
- package/dist/src/auth/api-key-auth.d.ts.map +1 -0
- package/dist/src/auth/api-key-auth.js +53 -0
- package/dist/src/auth/api-key-auth.js.map +1 -0
- package/dist/src/auth/effective-user-context.d.ts +16 -0
- package/dist/src/auth/effective-user-context.d.ts.map +1 -0
- package/dist/src/auth/effective-user-context.js +9 -0
- package/dist/src/auth/effective-user-context.js.map +1 -0
- package/dist/src/auth/license-resolver.d.ts +6 -0
- package/dist/src/auth/license-resolver.d.ts.map +1 -0
- package/dist/src/auth/license-resolver.js +12 -0
- package/dist/src/auth/license-resolver.js.map +1 -0
- package/dist/src/auth/oauth-auth.d.ts +22 -0
- package/dist/src/auth/oauth-auth.d.ts.map +1 -0
- package/dist/src/auth/oauth-auth.js +34 -0
- package/dist/src/auth/oauth-auth.js.map +1 -0
- package/dist/src/auth/oauth-metadata.d.ts +10 -0
- package/dist/src/auth/oauth-metadata.d.ts.map +1 -0
- package/dist/src/auth/oauth-metadata.js +8 -0
- package/dist/src/auth/oauth-metadata.js.map +1 -0
- package/dist/src/auth/token-extraction.d.ts +2 -0
- package/dist/src/auth/token-extraction.d.ts.map +1 -0
- package/dist/src/auth/token-extraction.js +7 -0
- package/dist/src/auth/token-extraction.js.map +1 -0
- package/dist/src/clients/audit-client.d.ts +25 -0
- package/dist/src/clients/audit-client.d.ts.map +1 -0
- package/dist/src/clients/audit-client.js +37 -0
- package/dist/src/clients/audit-client.js.map +1 -0
- package/dist/src/clients/datamart-client.d.ts +16 -0
- package/dist/src/clients/datamart-client.d.ts.map +1 -0
- package/dist/src/clients/datamart-client.js +32 -0
- package/dist/src/clients/datamart-client.js.map +1 -0
- package/dist/src/clients/index.d.ts +18 -0
- package/dist/src/clients/index.d.ts.map +1 -0
- package/dist/src/clients/index.js +11 -0
- package/dist/src/clients/index.js.map +1 -0
- package/dist/src/clients/rest-client.d.ts +14 -0
- package/dist/src/clients/rest-client.d.ts.map +1 -0
- package/dist/src/clients/rest-client.js +29 -0
- package/dist/src/clients/rest-client.js.map +1 -0
- package/dist/src/logger.d.ts +3 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +37 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/prompts/portfolio-overview.d.ts +3 -0
- package/dist/src/prompts/portfolio-overview.d.ts.map +1 -0
- package/dist/src/prompts/portfolio-overview.js +21 -0
- package/dist/src/prompts/portfolio-overview.js.map +1 -0
- package/dist/src/prompts/project-status.d.ts +3 -0
- package/dist/src/prompts/project-status.d.ts.map +1 -0
- package/dist/src/prompts/project-status.js +24 -0
- package/dist/src/prompts/project-status.js.map +1 -0
- package/dist/src/prompts/risk-analysis.d.ts +3 -0
- package/dist/src/prompts/risk-analysis.d.ts.map +1 -0
- package/dist/src/prompts/risk-analysis.js +23 -0
- package/dist/src/prompts/risk-analysis.js.map +1 -0
- package/dist/src/prompts/team-workload.d.ts +3 -0
- package/dist/src/prompts/team-workload.d.ts.map +1 -0
- package/dist/src/prompts/team-workload.js +29 -0
- package/dist/src/prompts/team-workload.js.map +1 -0
- package/dist/src/resources/calendars.d.ts +4 -0
- package/dist/src/resources/calendars.d.ts.map +1 -0
- package/dist/src/resources/calendars.js +18 -0
- package/dist/src/resources/calendars.js.map +1 -0
- package/dist/src/resources/schemas.d.ts +4 -0
- package/dist/src/resources/schemas.d.ts.map +1 -0
- package/dist/src/resources/schemas.js +34 -0
- package/dist/src/resources/schemas.js.map +1 -0
- package/dist/src/server.d.ts +2 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +213 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/tools/datamart.d.ts +17 -0
- package/dist/src/tools/datamart.d.ts.map +1 -0
- package/dist/src/tools/datamart.js +68 -0
- package/dist/src/tools/datamart.js.map +1 -0
- package/dist/src/tools/financials.d.ts +4 -0
- package/dist/src/tools/financials.d.ts.map +1 -0
- package/dist/src/tools/financials.js +50 -0
- package/dist/src/tools/financials.js.map +1 -0
- package/dist/src/tools/graphql-queries.d.ts +22 -0
- package/dist/src/tools/graphql-queries.d.ts.map +1 -0
- package/dist/src/tools/graphql-queries.js +26 -0
- package/dist/src/tools/graphql-queries.js.map +1 -0
- package/dist/src/tools/portfolio.d.ts +10 -0
- package/dist/src/tools/portfolio.d.ts.map +1 -0
- package/dist/src/tools/portfolio.js +54 -0
- package/dist/src/tools/portfolio.js.map +1 -0
- package/dist/src/tools/projects.d.ts +42 -0
- package/dist/src/tools/projects.d.ts.map +1 -0
- package/dist/src/tools/projects.js +73 -0
- package/dist/src/tools/projects.js.map +1 -0
- package/dist/src/tools/reference-data.d.ts +4 -0
- package/dist/src/tools/reference-data.d.ts.map +1 -0
- package/dist/src/tools/reference-data.js +19 -0
- package/dist/src/tools/reference-data.js.map +1 -0
- package/dist/src/tools/risks-issues.d.ts +4 -0
- package/dist/src/tools/risks-issues.d.ts.map +1 -0
- package/dist/src/tools/risks-issues.js +33 -0
- package/dist/src/tools/risks-issues.js.map +1 -0
- package/dist/src/tools/services.d.ts +41 -0
- package/dist/src/tools/services.d.ts.map +1 -0
- package/dist/src/tools/services.js +67 -0
- package/dist/src/tools/services.js.map +1 -0
- package/dist/src/tools/tasks.d.ts +4 -0
- package/dist/src/tools/tasks.d.ts.map +1 -0
- package/dist/src/tools/tasks.js +17 -0
- package/dist/src/tools/tasks.js.map +1 -0
- package/dist/src/tools/users.d.ts +4 -0
- package/dist/src/tools/users.d.ts.map +1 -0
- package/dist/src/tools/users.js +30 -0
- package/dist/src/tools/users.js.map +1 -0
- package/dist/src/tools/write-tools.d.ts +75 -0
- package/dist/src/tools/write-tools.d.ts.map +1 -0
- package/dist/src/tools/write-tools.js +193 -0
- package/dist/src/tools/write-tools.js.map +1 -0
- package/dist/src/validation/query-validator.d.ts +15 -0
- package/dist/src/validation/query-validator.d.ts.map +1 -0
- package/dist/src/validation/query-validator.js +141 -0
- package/dist/src/validation/query-validator.js.map +1 -0
- package/dist/startup-mode.d.ts +13 -0
- package/dist/startup-mode.d.ts.map +1 -0
- package/dist/startup-mode.js +17 -0
- package/dist/startup-mode.js.map +1 -0
- package/dist/tools/datamart.d.ts +17 -0
- package/dist/tools/datamart.d.ts.map +1 -0
- package/dist/tools/datamart.js +68 -0
- package/dist/tools/datamart.js.map +1 -0
- package/dist/tools/financials.d.ts +4 -0
- package/dist/tools/financials.d.ts.map +1 -0
- package/dist/tools/financials.js +50 -0
- package/dist/tools/financials.js.map +1 -0
- package/dist/tools/graphql-queries.d.ts +22 -0
- package/dist/tools/graphql-queries.d.ts.map +1 -0
- package/dist/tools/graphql-queries.js +26 -0
- package/dist/tools/graphql-queries.js.map +1 -0
- package/dist/tools/portfolio.d.ts +10 -0
- package/dist/tools/portfolio.d.ts.map +1 -0
- package/dist/tools/portfolio.js +54 -0
- package/dist/tools/portfolio.js.map +1 -0
- package/dist/tools/projects.d.ts +42 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +73 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/reference-data.d.ts +4 -0
- package/dist/tools/reference-data.d.ts.map +1 -0
- package/dist/tools/reference-data.js +20 -0
- package/dist/tools/reference-data.js.map +1 -0
- package/dist/tools/risks-issues.d.ts +4 -0
- package/dist/tools/risks-issues.d.ts.map +1 -0
- package/dist/tools/risks-issues.js +33 -0
- package/dist/tools/risks-issues.js.map +1 -0
- package/dist/tools/services.d.ts +41 -0
- package/dist/tools/services.d.ts.map +1 -0
- package/dist/tools/services.js +67 -0
- package/dist/tools/services.js.map +1 -0
- package/dist/tools/tasks.d.ts +4 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +17 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/users.d.ts +4 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +30 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/tools/write-tools.d.ts +74 -0
- package/dist/tools/write-tools.d.ts.map +1 -0
- package/dist/tools/write-tools.js +342 -0
- package/dist/tools/write-tools.js.map +1 -0
- package/dist/validation/query-validator.d.ts +15 -0
- package/dist/validation/query-validator.d.ts.map +1 -0
- package/dist/validation/query-validator.js +141 -0
- package/dist/validation/query-validator.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# ITM.MCP
|
|
2
|
+
|
|
3
|
+
> For cross-cutting documentation (debugging, database schema, environments, API versioning, build commands), see the [parent README](../README.md#documentation-index).
|
|
4
|
+
|
|
5
|
+
MCP (Model Context Protocol) server for ITM Platform. Exposes project management data to AI assistants -- Claude, ChatGPT, VS Code Copilot, Cursor, JetBrains -- through a universal open protocol.
|
|
6
|
+
|
|
7
|
+
**Status:** Phase 2 in progress -- 20 tools (15 read + 5 write), 6 resources, 4 prompts. OAuth scope enforcement, audit logging, and token exchange in place. 137 unit tests, 23 E2E tests.
|
|
8
|
+
|
|
9
|
+
See [House Rules](../House-rules.md) for coding conventions.
|
|
10
|
+
|
|
11
|
+
## How it works
|
|
12
|
+
|
|
13
|
+
MCP is a JSON-RPC 2.0 protocol that lets AI assistants discover and call tools on external servers. The server supports two transports:
|
|
14
|
+
|
|
15
|
+
- **HTTP + OAuth (recommended)** -- AI clients connect to a hosted URL and authenticate via OAuth 2.1 (PKCE). No local install needed.
|
|
16
|
+
- **stdio** -- AI clients spawn the server as a local child process. Auth via API key.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
AI Client (Claude, Cursor, VS Code, Codex...)
|
|
20
|
+
|
|
|
21
|
+
| HTTP (remote) or stdio (local)
|
|
22
|
+
v
|
|
23
|
+
ITM.MCP Server
|
|
24
|
+
| authenticates as the user, calls ITM APIs
|
|
25
|
+
v
|
|
26
|
+
ITM.API Gateway --> DataMart (GraphQL) + v2 REST (users, reference data)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Key point:** The AI model never sees user credentials. Auth is handled by the MCP server. The model only sees tool names, descriptions, and results.
|
|
30
|
+
|
|
31
|
+
### Three MCP primitives
|
|
32
|
+
|
|
33
|
+
| Primitive | Who controls it | What it does | Example |
|
|
34
|
+
|-----------|----------------|--------------|---------|
|
|
35
|
+
| **Tools** | AI model decides when to call | Executable read/write operations | `search_projects`, `get_project_budget` |
|
|
36
|
+
| **Resources** | Client app loads as context | Read-only reference data (schemas, docs) | `itm://schema/component` |
|
|
37
|
+
| **Prompts** | User triggers a workflow template | Pre-composed multi-tool request | `/project_status` fetches project + tasks + risks + budget in one shot |
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install
|
|
43
|
+
cp .env.sample .env # edit with your credentials
|
|
44
|
+
npm test # unit tests (124 tests)
|
|
45
|
+
npm run build # compile TypeScript to dist/
|
|
46
|
+
npm run dev # HTTP dev server on port 6170 (for testing with curl)
|
|
47
|
+
npm run test:e2e # E2E tests (requires local ITM.API + DataMart)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## End-user setup
|
|
51
|
+
|
|
52
|
+
For end-user setup instructions (OAuth, per-client configuration, npm package), see the [APIDocs site](APIDocs/).
|
|
53
|
+
|
|
54
|
+
**Quick connect (OAuth):**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
claude mcp add --scope user --transport http itm-platform https://api.itmplatform.com/v2/_/mcp/
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Quick connect (npm, local):**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
claude mcp add --scope user itm-platform -- npx @itm-platform/mcp-server
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Server configuration (development / deployment)
|
|
67
|
+
|
|
68
|
+
| Variable | Stdio | HTTP+OAuth | Description |
|
|
69
|
+
|----------|-------|------------|-------------|
|
|
70
|
+
| `ITM_API_URL` | Required | Required | ITM.API base URL |
|
|
71
|
+
| `ITM_COMPANY` | Required | -- | Company/tenant slug |
|
|
72
|
+
| `ITM_API_KEY` | Required* | -- | Per-user API key (generate from My Profile) |
|
|
73
|
+
| `ITM_TOKEN` | Required* | -- | Session token (alternative to API key) |
|
|
74
|
+
| `PORT` | -- | Required | HTTP listen port |
|
|
75
|
+
| `ITM_AUTH_URL` | -- | Required | Internal OAuth authorization server URL (used for token exchange) |
|
|
76
|
+
| `ITM_AUTH_PUBLIC_URL` | -- | Required* | Public OAuth URL advertised to AI clients. Falls back to `ITM_AUTH_URL` |
|
|
77
|
+
| `MCP_SERVER_URL` | -- | Required | MCP server public URL (OAuth audience) |
|
|
78
|
+
| `LOG_LEVEL` | Optional | Optional | Pino log level: `debug`, `info`, `warn`, `error` (default: `info`) |
|
|
79
|
+
| `ITM_AUDIT_ENABLED` | Optional | Optional | Enable audit logging to ITM backend |
|
|
80
|
+
|
|
81
|
+
\* One of `ITM_API_KEY` or `ITM_TOKEN` is required for stdio mode.
|
|
82
|
+
|
|
83
|
+
In HTTP mode, if both `ITM_AUTH_URL` and `MCP_SERVER_URL` are set, OAuth is mandatory and every session must provide a Bearer token. If either is missing, the server runs in dev mode using the startup identity.
|
|
84
|
+
|
|
85
|
+
On deployed environments, `ITM_AUTH_URL` points to `localhost` for internal server-to-server token exchange. `ITM_AUTH_PUBLIC_URL` must be set to the public URL so AI clients can discover the OAuth authorization server.
|
|
86
|
+
|
|
87
|
+
## Tools (Phase 1 -- read-only)
|
|
88
|
+
|
|
89
|
+
### DataMart-backed (fast, single-query reads)
|
|
90
|
+
|
|
91
|
+
| Tool | Description |
|
|
92
|
+
|------|-------------|
|
|
93
|
+
| `search_projects` | Find projects by name, status, type, date range |
|
|
94
|
+
| `search_services` | Find services by name, status, type, date range |
|
|
95
|
+
| `get_project` | Full project details with optional subcomponents (tasks, risks, budget, etc.) |
|
|
96
|
+
| `get_service` | Full service details with optional subcomponents |
|
|
97
|
+
| `list_project_tasks` | Tasks for a project |
|
|
98
|
+
| `get_project_risks` | Risks for a project |
|
|
99
|
+
| `get_project_issues` | Issues for a project |
|
|
100
|
+
| `get_project_budget` | Budget summary (top-down, bottom-up, actual, period-end close) |
|
|
101
|
+
| `get_project_purchases` | Purchase orders for a project |
|
|
102
|
+
| `get_project_revenues` | Revenue items for a project |
|
|
103
|
+
| `aggregate_portfolio` | Portfolio analytics -- group, count, sum, avg across all projects |
|
|
104
|
+
| `query_datamart` | Raw DataMart query for advanced analysis (validated, safe operators only) |
|
|
105
|
+
|
|
106
|
+
### v2 REST-backed (users, reference data)
|
|
107
|
+
|
|
108
|
+
| Tool | Description |
|
|
109
|
+
|------|-------------|
|
|
110
|
+
| `search_users` | Find team members |
|
|
111
|
+
| `get_user` | User details |
|
|
112
|
+
| `get_reference_data` | Status lists, types, priorities for any entity |
|
|
113
|
+
|
|
114
|
+
### Write tools (Phase 2 -- v2 REST-backed)
|
|
115
|
+
|
|
116
|
+
| Tool | Description |
|
|
117
|
+
|------|-------------|
|
|
118
|
+
| `create_task` | Create a new task in a project |
|
|
119
|
+
| `update_task` | PATCH task fields (status, dates, assignee, progress) |
|
|
120
|
+
| `create_risk` | Log a new risk in a project |
|
|
121
|
+
| `create_issue` | Log a new issue in a project |
|
|
122
|
+
| `update_project` | PATCH project fields (name, status, dates, priority) |
|
|
123
|
+
|
|
124
|
+
Write tools return confirmed state from v2 REST (source of truth). Subsequent DataMart reads may lag 5-60 seconds due to eventual consistency -- this is noted in every write response.
|
|
125
|
+
|
|
126
|
+
## Prompts
|
|
127
|
+
|
|
128
|
+
Workflow templates the user can trigger. The MCP server returns a pre-composed message that instructs the AI to call the right tools.
|
|
129
|
+
|
|
130
|
+
| Prompt | What it does |
|
|
131
|
+
|--------|-------------|
|
|
132
|
+
| `/project_status` | Fetches project + tasks + risks + budget, asks AI to summarize |
|
|
133
|
+
| `/portfolio_overview` | Aggregates projects by status/methodology/budget, asks AI for health overview |
|
|
134
|
+
| `/team_workload` | Fetches users + assignments, asks AI for workload analysis |
|
|
135
|
+
| `/risk_analysis` | Fetches risks + issues + budget, asks AI for risk assessment |
|
|
136
|
+
|
|
137
|
+
## Architecture
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
src/
|
|
141
|
+
server.ts # MCP server bootstrap (stdio + HTTP, per-session auth)
|
|
142
|
+
instrument-server.ts # Tool-call logging + audit wrapper (wraps registerTool)
|
|
143
|
+
logger.ts # Pino logger factory (stderr + rotating file in logs/mcp.log)
|
|
144
|
+
auth/
|
|
145
|
+
effective-user-context.ts # User identity type
|
|
146
|
+
api-key-auth.ts # API key auth, calls /resolve/identity
|
|
147
|
+
license-resolver.ts # License type -> access level
|
|
148
|
+
oauth-auth.ts # Phase 2: OAuth token exchange
|
|
149
|
+
oauth-metadata.ts # Phase 2: /.well-known/oauth-protected-resource
|
|
150
|
+
token-extraction.ts # Bearer token extraction from headers
|
|
151
|
+
clients/
|
|
152
|
+
datamart-client.ts # DataMart GraphQL through gateway
|
|
153
|
+
rest-client.ts # v2 REST through gateway (GET, POST, PATCH)
|
|
154
|
+
audit-client.ts # Phase 2: audit logging (fire-and-forget)
|
|
155
|
+
tools/ # One file per tool group
|
|
156
|
+
write-tools.ts # Phase 2: create/update tools (task, risk, issue, project)
|
|
157
|
+
resources/ # Schema + calendar resources
|
|
158
|
+
prompts/ # Workflow templates
|
|
159
|
+
validation/
|
|
160
|
+
query-validator.ts # Allowlist of safe MongoDB operators
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Access control
|
|
164
|
+
|
|
165
|
+
| License type | Access |
|
|
166
|
+
|-------------|--------|
|
|
167
|
+
| CompanyAdmin | Full |
|
|
168
|
+
| FullUser | Full |
|
|
169
|
+
| ProjectManager | Blocked in Phase 1 (requires gateway PM-scope injection -- Phase 2) |
|
|
170
|
+
| TeamMember | Blocked |
|
|
171
|
+
|
|
172
|
+
**OAuth scope enforcement:** OAuth sessions respect granted scopes. Sessions with `mcp:read` only see 15 read tools; `mcp:write` is required to see and use write tools. API-key/stdio sessions get all tools unconditionally (backward compatible).
|
|
173
|
+
|
|
174
|
+
## Logging
|
|
175
|
+
|
|
176
|
+
Uses [Pino](https://getpino.io/) (same as DataMart and MSTeamsBot). Logs go to two destinations:
|
|
177
|
+
|
|
178
|
+
- **stderr** -- pretty-printed, colorized (stdout is reserved for the MCP JSON-RPC protocol)
|
|
179
|
+
- **`logs/mcp.log`** -- rotating file relative to the MCP application root, 10 MB max, keeps 5 old files (skipped in test)
|
|
180
|
+
|
|
181
|
+
Set `LOG_LEVEL` in `.env` to control verbosity (`debug`, `info`, `warn`, `error`; default: `info`). All log entries include `{ service: 'mcp', app: 'ITM.MCP' }` base fields and ISO timestamps.
|
|
182
|
+
|
|
183
|
+
HTTP clients (DataMart, REST) log at `debug` level on success (with duration in ms) and `error` on failure.
|
|
184
|
+
|
|
185
|
+
**Tool-call logging:** Every MCP tool invocation is logged at `info` level with tool name, userId, and aiClientId. Completion is logged at `debug` with duration in ms. Failures are logged at `error`.
|
|
186
|
+
|
|
187
|
+
**Audit:** When `ITM_AUDIT_ENABLED=true`, every tool call (read and write) sends an audit entry to the ITM backend (`/v2/{company}/mcp/audit`). Audit is fire-and-forget -- failures do not affect tool execution. Each entry includes: timestamp, userId, accountId, toolName, parametersHash (SHA-256), success, error (if any), aiClientId, durationMs.
|
|
188
|
+
|
|
189
|
+
## Specification
|
|
190
|
+
|
|
191
|
+
Full design, architecture decisions, phased rollout, and E2E test details:
|
|
192
|
+
|
|
193
|
+
- [SPEC_MCP_SERVER.md](zz_Specifications/SPEC_MCP_SERVER.md)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-config.d.ts","sourceRoot":"","sources":["../src/audit-config.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,KAAK,qBAAgC,GAAG,OAAO,CAE7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-config.js","sourceRoot":"","sources":["../src/audit-config.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB;IAClE,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC;AAC1C,CAAC"}
|
|
@@ -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,11 @@
|
|
|
1
|
+
export interface ProtectedResourceMetadata {
|
|
2
|
+
resource: string;
|
|
3
|
+
authorization_servers: string[];
|
|
4
|
+
scopes_supported: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function buildResourceMetadataUrl(mcpServerUrl: string): string;
|
|
7
|
+
export declare function buildProtectedResourceMetadata(config: {
|
|
8
|
+
mcpServerUrl: string;
|
|
9
|
+
authorizationServerUrl: string;
|
|
10
|
+
}): ProtectedResourceMetadata;
|
|
11
|
+
//# 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;AAMD,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,MAAM,CAAC;CAChC,GAAG,yBAAyB,CAM5B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function stripTrailingSlashes(url) {
|
|
2
|
+
return url.replace(/\/+$/, '');
|
|
3
|
+
}
|
|
4
|
+
export function buildResourceMetadataUrl(mcpServerUrl) {
|
|
5
|
+
return `${stripTrailingSlashes(mcpServerUrl)}/.well-known/oauth-protected-resource`;
|
|
6
|
+
}
|
|
7
|
+
export function buildProtectedResourceMetadata(config) {
|
|
8
|
+
return {
|
|
9
|
+
resource: stripTrailingSlashes(config.mcpServerUrl),
|
|
10
|
+
authorization_servers: [config.authorizationServerUrl],
|
|
11
|
+
scopes_supported: ['mcp:read', 'mcp:write'],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# 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,SAAS,oBAAoB,CAAC,GAAW;IACvC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,YAAoB;IAC3D,OAAO,GAAG,oBAAoB,CAAC,YAAY,CAAC,uCAAuC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,MAG9C;IACC,OAAO;QACL,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC;QACnD,qBAAqB,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC;QACtD,gBAAgB,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
|
@@ -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 @@
|
|
|
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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export function createDataMartClient(config) {
|
|
3
|
+
const baseUrl = `${config.apiUrl}/v2/${config.company}/datamart/graphql`;
|
|
4
|
+
const log = config.log;
|
|
5
|
+
return {
|
|
6
|
+
async query(body) {
|
|
7
|
+
const requestId = randomUUID();
|
|
8
|
+
const start = Date.now();
|
|
9
|
+
const response = await fetch(baseUrl, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
...config.authHeaders,
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
'X-Request-Id': requestId,
|
|
15
|
+
},
|
|
16
|
+
body: JSON.stringify(body),
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
log?.error({ requestId, status: response.status, ms: Date.now() - start }, 'DataMart request failed');
|
|
20
|
+
throw new Error(`DataMart request failed: ${response.status} ${response.statusText}`);
|
|
21
|
+
}
|
|
22
|
+
const json = await response.json();
|
|
23
|
+
if (json.errors?.length) {
|
|
24
|
+
log?.error({ requestId, graphqlError: json.errors[0].message, ms: Date.now() - start }, 'DataMart GraphQL error');
|
|
25
|
+
throw new Error(`DataMart GraphQL error: ${json.errors[0].message}`);
|
|
26
|
+
}
|
|
27
|
+
log?.debug({ requestId, ms: Date.now() - start }, 'DataMart request OK');
|
|
28
|
+
return json.data ?? {};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=datamart-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datamart-client.js","sourceRoot":"","sources":["../../src/clients/datamart-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmBzC,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAC/D,MAAM,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,OAAO,mBAAmB,CAAC;IACzE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAEvB,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,IAAmB;YAC7B,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAEzB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;gBACpC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,GAAG,MAAM,CAAC,WAAW;oBACrB,cAAc,EAAE,kBAAkB;oBAClC,cAAc,EAAE,SAAS;iBAC1B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,GAAG,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,yBAAyB,CAAC,CAAC;gBACtG,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACxF,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6E,CAAC;YAE9G,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACxB,GAAG,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,wBAAwB,CAAC,CAAC;gBAClH,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACvE,CAAC;YAED,GAAG,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Logger } from 'pino';
|
|
2
|
+
import { type DataMartClient } from './datamart-client.js';
|
|
3
|
+
import { type RestClient } from './rest-client.js';
|
|
4
|
+
import { type AuditClient } from './audit-client.js';
|
|
5
|
+
export interface ClientConfig {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
company: string;
|
|
8
|
+
authHeaders: Record<string, string>;
|
|
9
|
+
log?: Logger;
|
|
10
|
+
}
|
|
11
|
+
export interface Clients {
|
|
12
|
+
datamart: DataMartClient;
|
|
13
|
+
rest: RestClient;
|
|
14
|
+
audit: AuditClient;
|
|
15
|
+
}
|
|
16
|
+
export declare function createClients(config: ClientConfig, audit?: AuditClient): Clients;
|
|
17
|
+
export type { DataMartClient, RestClient, AuditClient };
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAyB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE5E,MAAM,WAAW,YAAY;IAC3B,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,OAAO;IACtB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAMhF;AAED,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
|