@tinyweb_dev/tracking-mcp-server 0.1.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/.env.example +43 -0
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/http-client.d.ts +31 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +152 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +11 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +41 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompts/index.d.ts +14 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +120 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +18 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +168 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/schemas/common.d.ts +27 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +29 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/error.d.ts +236 -0
- package/dist/schemas/error.d.ts.map +1 -0
- package/dist/schemas/error.js +88 -0
- package/dist/schemas/error.js.map +1 -0
- package/dist/schemas/incident.d.ts +139 -0
- package/dist/schemas/incident.d.ts.map +1 -0
- package/dist/schemas/incident.js +53 -0
- package/dist/schemas/incident.js.map +1 -0
- package/dist/schemas/index.d.ts +13 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +13 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/invitation.d.ts +77 -0
- package/dist/schemas/invitation.d.ts.map +1 -0
- package/dist/schemas/invitation.js +45 -0
- package/dist/schemas/invitation.js.map +1 -0
- package/dist/schemas/monitor.d.ts +183 -0
- package/dist/schemas/monitor.d.ts.map +1 -0
- package/dist/schemas/monitor.js +81 -0
- package/dist/schemas/monitor.js.map +1 -0
- package/dist/schemas/organization.d.ts +87 -0
- package/dist/schemas/organization.d.ts.map +1 -0
- package/dist/schemas/organization.js +39 -0
- package/dist/schemas/organization.js.map +1 -0
- package/dist/schemas/project.d.ts +82 -0
- package/dist/schemas/project.d.ts.map +1 -0
- package/dist/schemas/project.js +38 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/recipient-group.d.ts +51 -0
- package/dist/schemas/recipient-group.d.ts.map +1 -0
- package/dist/schemas/recipient-group.js +30 -0
- package/dist/schemas/recipient-group.js.map +1 -0
- package/dist/schemas/status-page.d.ts +144 -0
- package/dist/schemas/status-page.d.ts.map +1 -0
- package/dist/schemas/status-page.js +64 -0
- package/dist/schemas/status-page.js.map +1 -0
- package/dist/tools/_helpers.d.ts +33 -0
- package/dist/tools/_helpers.d.ts.map +1 -0
- package/dist/tools/_helpers.js +62 -0
- package/dist/tools/_helpers.js.map +1 -0
- package/dist/tools/errors.d.ts +20 -0
- package/dist/tools/errors.d.ts.map +1 -0
- package/dist/tools/errors.js +196 -0
- package/dist/tools/errors.js.map +1 -0
- package/dist/tools/incidents.d.ts +14 -0
- package/dist/tools/incidents.d.ts.map +1 -0
- package/dist/tools/incidents.js +105 -0
- package/dist/tools/incidents.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +22 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/invitations.d.ts +12 -0
- package/dist/tools/invitations.d.ts.map +1 -0
- package/dist/tools/invitations.js +82 -0
- package/dist/tools/invitations.js.map +1 -0
- package/dist/tools/monitors.d.ts +15 -0
- package/dist/tools/monitors.d.ts.map +1 -0
- package/dist/tools/monitors.js +129 -0
- package/dist/tools/monitors.js.map +1 -0
- package/dist/tools/organizations.d.ts +16 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +152 -0
- package/dist/tools/organizations.js.map +1 -0
- package/dist/tools/projects.d.ts +22 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +218 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/recipient-groups.d.ts +12 -0
- package/dist/tools/recipient-groups.d.ts.map +1 -0
- package/dist/tools/recipient-groups.js +75 -0
- package/dist/tools/recipient-groups.js.map +1 -0
- package/dist/tools/status-pages.d.ts +17 -0
- package/dist/tools/status-pages.d.ts.map +1 -0
- package/dist/tools/status-pages.js +170 -0
- package/dist/tools/status-pages.js.map +1 -0
- package/package.json +77 -0
package/.env.example
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Tiny Tracking MCP Server — environment configuration
|
|
2
|
+
# Copy this file to `.env` (for local dev) or set these vars in your MCP client config.
|
|
3
|
+
|
|
4
|
+
# --- REQUIRED ---
|
|
5
|
+
|
|
6
|
+
# Base URL of the Tiny Tracking backend (no trailing slash).
|
|
7
|
+
TT_API_URL=http://localhost:3000
|
|
8
|
+
|
|
9
|
+
# Personal Access Token (PAT). Generated from the Tiny Tracking dashboard:
|
|
10
|
+
# 1. Sign in to the dashboard
|
|
11
|
+
# 2. Settings → Personal access tokens → Manage tokens
|
|
12
|
+
# (or visit /<orgId>/settings/api-tokens directly)
|
|
13
|
+
# 3. Click "Create token", give it a name, choose an expiry
|
|
14
|
+
# 4. Copy the `tt_pat_<32 chars>` value SHOWN ONCE (the server only stores
|
|
15
|
+
# a bcrypt hash; you cannot retrieve the plaintext later)
|
|
16
|
+
# 5. Paste it here.
|
|
17
|
+
#
|
|
18
|
+
# Format: literal prefix `tt_pat_` followed by 32 base62-ish characters
|
|
19
|
+
# (e.g. `tt_pat_aB3xY9Q2cD7eF8gH1iJ4kL5mN6oP7qR8s`).
|
|
20
|
+
# Token inherits the owning user's permissions across all orgs/projects they
|
|
21
|
+
# are a member of. Treat as a password: never commit, never paste in public chats.
|
|
22
|
+
TT_API_KEY=tt_pat_replace_me
|
|
23
|
+
|
|
24
|
+
# --- OPTIONAL ---
|
|
25
|
+
|
|
26
|
+
# Default organization ID, used when a tool does not receive `org_id` explicitly.
|
|
27
|
+
# Find it in the URL of your dashboard: /<orgId>/...
|
|
28
|
+
TT_DEFAULT_ORG_ID=
|
|
29
|
+
|
|
30
|
+
# Request timeout in milliseconds (default: 15000).
|
|
31
|
+
TT_HTTP_TIMEOUT_MS=15000
|
|
32
|
+
|
|
33
|
+
# Number of retry attempts on transient errors — 5xx, 429, network (default: 3).
|
|
34
|
+
TT_HTTP_RETRIES=3
|
|
35
|
+
|
|
36
|
+
# Logger level: trace | debug | info | warn | error | fatal (default: info).
|
|
37
|
+
# Output always goes to stderr — stdout is reserved for MCP JSON-RPC.
|
|
38
|
+
LOG_LEVEL=info
|
|
39
|
+
|
|
40
|
+
# Client identifier sent in `X-MCP-Client` header.
|
|
41
|
+
# Used by the backend audit log to attribute requests to this MCP instance.
|
|
42
|
+
# Default: tiny-tracking-mcp/<pkg-version>.
|
|
43
|
+
TT_MCP_CLIENT_NAME=
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@tinyweb_dev/tracking-mcp-server` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] — 2026-05-26
|
|
9
|
+
|
|
10
|
+
Initial public release.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **62 MCP tools** across 8 resource groups (organizations, projects,
|
|
15
|
+
monitors, status pages, incidents, errors, recipient groups, invitations)
|
|
16
|
+
wrapping the Tiny Tracking REST API.
|
|
17
|
+
- **6 read-only resource templates** for browsing org/project/monitor state
|
|
18
|
+
via `tinytracking://...` URIs.
|
|
19
|
+
- **3 prompt templates** (`triage-incident`, `summarize-error-group`,
|
|
20
|
+
`weekly-health-report`) that prime the agent with canonical investigation
|
|
21
|
+
workflows.
|
|
22
|
+
- **Confirmation pattern** on 10 destructive tools (`*_delete`,
|
|
23
|
+
`project_regenerate_api_key`, `invitation_revoke`, etc.) — each requires
|
|
24
|
+
an explicit `confirm_*` argument matching the resource's
|
|
25
|
+
name/slug/uuid before proceeding.
|
|
26
|
+
- **`X-MCP-Client: tiny-tracking-mcp/<version>` header** on every request so
|
|
27
|
+
backend audit logs can attribute calls to the MCP server.
|
|
28
|
+
- **Stdio transport** compatible with Claude Desktop, VS Code / Roo Code,
|
|
29
|
+
Cursor, ChatGPT Desktop, and any other MCP-compliant client.
|
|
30
|
+
- **Pino logger pinned to stderr** with automatic redaction of
|
|
31
|
+
`authorization`, `apiKey`, `token`, `password`, `secret`, `x-api-key`
|
|
32
|
+
fields — stdout is reserved for MCP JSON-RPC.
|
|
33
|
+
- **Axios HTTP client** with exponential-backoff retries on 5xx / 429 /
|
|
34
|
+
network errors and structured `McpError` mapping (401/403 →
|
|
35
|
+
`InvalidRequest`, 404/400/422 → `InvalidParams`, 5xx → `InternalError`).
|
|
36
|
+
- **219 unit tests** across 17 test files; coverage 98.60% lines / 97.96%
|
|
37
|
+
branches.
|
|
38
|
+
|
|
39
|
+
### Backend dependencies (required server-side, shipped in the same release)
|
|
40
|
+
|
|
41
|
+
- **Personal Access Token (PAT) system**: new `POST/GET/DELETE /api/me/tokens`
|
|
42
|
+
endpoints, bcrypt cost-10 hashing, prefix-indexed lookup, soft revoke.
|
|
43
|
+
- **Enhanced `JwtAuthGuard`**: now accepts both better-auth session cookies
|
|
44
|
+
AND `Authorization: Bearer tt_pat_*` tokens, hydrating the same
|
|
45
|
+
`request.user` shape for both paths.
|
|
46
|
+
- **`Settings → API tokens` dashboard page**: user-facing CRUD UI for
|
|
47
|
+
generating, listing, and revoking PATs.
|
|
48
|
+
- **MCP audit log**: every request carrying the `X-MCP-Client` header is
|
|
49
|
+
asynchronously recorded to the `mcp_audit_log` table (user, token,
|
|
50
|
+
org/project context, method, path, status, request/response excerpt with
|
|
51
|
+
sensitive-field redaction, IP, user-agent, duration). Owner-only read
|
|
52
|
+
endpoint `GET /api/organizations/:orgId/audit-log`.
|
|
53
|
+
|
|
54
|
+
### Engineering
|
|
55
|
+
|
|
56
|
+
- ESM module (`type: "module"`), TypeScript 5.7, Node ≥ 20.
|
|
57
|
+
- Build is `tsc -p tsconfig.json && chmod +x dist/index.js` so the published
|
|
58
|
+
binary is directly executable.
|
|
59
|
+
- `prepublishOnly` runs clean + typecheck + build + tests to guarantee no
|
|
60
|
+
broken release reaches the registry.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tinyweb dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# @tinyweb_dev/tracking-mcp-server
|
|
2
|
+
|
|
3
|
+
> **MCP server cho Tiny Tracking** — cho phép các AI agent (Claude Desktop, Cursor, Roo Code, VS Code, ChatGPT Desktop, custom agents…) điều khiển và quản lý toàn bộ resource của nền tảng monitoring **Tiny Tracking** thông qua REST API.
|
|
4
|
+
|
|
5
|
+
Standalone Node.js package, không xâm lấn backend, deploy độc lập, dùng được cho mọi MCP client hỗ trợ stdio transport.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Mục lục
|
|
10
|
+
|
|
11
|
+
- [Tính năng](#tính-năng)
|
|
12
|
+
- [Yêu cầu](#yêu-cầu)
|
|
13
|
+
- [Cài đặt](#cài-đặt)
|
|
14
|
+
- [Cấu hình](#cấu-hình)
|
|
15
|
+
- [Tích hợp với MCP client](#tích-hợp-với-mcp-client)
|
|
16
|
+
- [Claude Desktop](#claude-desktop)
|
|
17
|
+
- [VS Code / Roo Code](#vs-code--roo-code)
|
|
18
|
+
- [Cursor](#cursor)
|
|
19
|
+
- [Tool reference](#tool-reference)
|
|
20
|
+
- [Resources & Prompts](#resources--prompts)
|
|
21
|
+
- [Bảo mật & confirmation pattern](#bảo-mật--confirmation-pattern)
|
|
22
|
+
- [Troubleshooting](#troubleshooting)
|
|
23
|
+
- [Phát triển](#phát-triển)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Tính năng
|
|
28
|
+
|
|
29
|
+
- **62 tools** wrap toàn bộ REST API của Tiny Tracking backend (8 resource groups)
|
|
30
|
+
- **6 resources** read-only cho agent browse nhanh workspace
|
|
31
|
+
- **3 prompt templates** (triage incident, summarize error, weekly report)
|
|
32
|
+
- **Stdio transport** — tương thích Claude Desktop, Cursor, Roo Code, VS Code, ChatGPT Desktop
|
|
33
|
+
- **Type-safe** end-to-end với zod schemas mirror các DTO backend
|
|
34
|
+
- **Auto-retry** với exponential backoff trên network errors / 5xx / 429
|
|
35
|
+
- **Audit-friendly** — mỗi request gắn header `X-MCP-Client: <name>/<version>`
|
|
36
|
+
- **Safe by default** — tools destructive (delete, regenerate key) bắt buộc xác nhận
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Yêu cầu
|
|
41
|
+
|
|
42
|
+
- **Node.js 22+**
|
|
43
|
+
- **Tiny Tracking backend** đang chạy và truy cập được (mặc định `http://localhost:3000`)
|
|
44
|
+
- **Personal Access Token (PAT)** — generate từ dashboard:
|
|
45
|
+
1. Đăng nhập vào Tiny Tracking dashboard
|
|
46
|
+
2. Vào **Settings → Personal access tokens → Manage tokens** (hoặc truy cập trực tiếp `/<orgId>/settings/api-tokens`)
|
|
47
|
+
3. Bấm **Create token**, đặt tên (vd "Claude Desktop on MacBook"), chọn thời hạn → **Generate token**
|
|
48
|
+
4. **Copy ngay** giá trị `tt_pat_...` được hiển thị — backend chỉ lưu bcrypt hash, plaintext không thể recover sau khi đóng dialog
|
|
49
|
+
5. Paste vào `TT_API_KEY` trong MCP client config (xem ví dụ dưới)
|
|
50
|
+
|
|
51
|
+
Token thuộc về user, nên có quyền truy cập **toàn bộ org/project user đang là member**. Treat as password — không commit vào git, không paste vào public chat.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Cài đặt
|
|
56
|
+
|
|
57
|
+
### Từ source (recommended cho local dev)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/yourusername/tiny-tracking.git
|
|
61
|
+
cd tiny-tracking/mcp-server
|
|
62
|
+
npm install
|
|
63
|
+
npm run build
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Sau khi build thành công, [`dist/index.js`](dist/index.js) là entrypoint, có thể chạy thử:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
TT_API_URL=http://localhost:3000 TT_API_KEY=tt_pat_xxx node dist/index.js
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Server sẽ in một dòng JSON ra **stderr** rồi treo chờ JSON-RPC từ stdin — đó là hành vi đúng cho một MCP server stdio.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Cấu hình
|
|
77
|
+
|
|
78
|
+
Tất cả config qua biến môi trường. Xem [`.env.example`](.env.example) để có danh sách đầy đủ.
|
|
79
|
+
|
|
80
|
+
| Biến | Bắt buộc | Mô tả | Mặc định |
|
|
81
|
+
|---|:---:|---|---|
|
|
82
|
+
| `TT_API_URL` | ✅ | Base URL của Tiny Tracking backend (không trailing slash) | — |
|
|
83
|
+
| `TT_API_KEY` | ✅ | Personal Access Token format `tt_pat_<32 chars>` (generate ở Settings → API tokens) | — |
|
|
84
|
+
| `TT_DEFAULT_ORG_ID` | | Org UUID mặc định khi tool không nhận `org_id` | — |
|
|
85
|
+
| `TT_HTTP_TIMEOUT_MS` | | Timeout HTTP (ms) | `15000` |
|
|
86
|
+
| `TT_HTTP_RETRIES` | | Số lần retry với 5xx / 429 / network errors | `3` |
|
|
87
|
+
| `TT_MCP_CLIENT_NAME` | | Tên cho header `X-MCP-Client` | `mcp-server/<version>` |
|
|
88
|
+
| `LOG_LEVEL` | | `trace` \| `debug` \| `info` \| `warn` \| `error` \| `fatal` | `info` |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Tích hợp với MCP client
|
|
93
|
+
|
|
94
|
+
### Claude Desktop
|
|
95
|
+
|
|
96
|
+
Edit file config tại:
|
|
97
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
98
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"tiny-tracking": {
|
|
104
|
+
"command": "node",
|
|
105
|
+
"args": [
|
|
106
|
+
"/absolute/path/to/tiny-tracking/mcp-server/dist/index.js"
|
|
107
|
+
],
|
|
108
|
+
"env": {
|
|
109
|
+
"TT_API_URL": "https://api.tinytracking.com",
|
|
110
|
+
"TT_API_KEY": "tt_pat_replace_me",
|
|
111
|
+
"TT_DEFAULT_ORG_ID": "org_uuid_optional",
|
|
112
|
+
"LOG_LEVEL": "info"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Restart Claude Desktop. Mở Settings → Developer → MCP để xem trạng thái connection. Trong chat, gõ `/` để thấy 3 prompt templates (`triage-incident`, `summarize-error-group`, `weekly-health-report`).
|
|
120
|
+
|
|
121
|
+
### VS Code / Roo Code
|
|
122
|
+
|
|
123
|
+
Tạo `.vscode/mcp.json` trong workspace:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"servers": {
|
|
128
|
+
"tiny-tracking": {
|
|
129
|
+
"type": "stdio",
|
|
130
|
+
"command": "node",
|
|
131
|
+
"args": ["${workspaceFolder}/mcp-server/dist/index.js"],
|
|
132
|
+
"env": {
|
|
133
|
+
"TT_API_URL": "http://localhost:3000",
|
|
134
|
+
"TT_API_KEY": "tt_pat_replace_me"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
> ⚠️ **Không commit** file `.vscode/mcp.json` có chứa token thật vào git. Thêm vào `.gitignore` hoặc dùng VS Code user settings.
|
|
142
|
+
|
|
143
|
+
### Cursor
|
|
144
|
+
|
|
145
|
+
Tạo `.cursor/mcp.json` ở root project hoặc `~/.cursor/mcp.json` cho global config:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"mcpServers": {
|
|
150
|
+
"tiny-tracking": {
|
|
151
|
+
"command": "node",
|
|
152
|
+
"args": ["/absolute/path/to/tiny-tracking/mcp-server/dist/index.js"],
|
|
153
|
+
"env": {
|
|
154
|
+
"TT_API_URL": "http://localhost:3000",
|
|
155
|
+
"TT_API_KEY": "tt_pat_replace_me"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Tool reference
|
|
165
|
+
|
|
166
|
+
Tổng **62 tools** chia theo 8 resource groups. Naming convention: `<resource>_<action>` (snake_case).
|
|
167
|
+
|
|
168
|
+
### Organizations (8 tools)
|
|
169
|
+
|
|
170
|
+
| Tool | Mô tả |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `org_list` | List orgs mà user có quyền truy cập |
|
|
173
|
+
| `org_get` | Lấy chi tiết 1 org |
|
|
174
|
+
| `org_create` | Tạo org mới (user thành owner) |
|
|
175
|
+
| `org_update` | Update name/slug/logo (owner only) |
|
|
176
|
+
| `org_delete` | 🔴 Xóa org + toàn bộ dữ liệu (yêu cầu `confirm_slug`) |
|
|
177
|
+
| `org_list_members` | List members và roles |
|
|
178
|
+
| `org_update_member_role` | Đổi role (owner/member/viewer) |
|
|
179
|
+
| `org_remove_member` | 🔴 Remove user khỏi org (yêu cầu `confirm_user_id`) |
|
|
180
|
+
|
|
181
|
+
### Projects (12 tools)
|
|
182
|
+
|
|
183
|
+
| Tool | Mô tả |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `project_list` | List projects trong 1 org |
|
|
186
|
+
| `project_create` | Tạo project mới (trả về API key) |
|
|
187
|
+
| `project_get` | Lấy chi tiết project |
|
|
188
|
+
| `project_update` | Update project |
|
|
189
|
+
| `project_delete` | 🔴 Xóa project + monitors + errors (yêu cầu `confirm_name`) |
|
|
190
|
+
| `project_get_api_key_prefix` | Lấy prefix API key (an toàn share) |
|
|
191
|
+
| `project_reveal_api_key` | 🔐 Reveal full API key (admin only) |
|
|
192
|
+
| `project_regenerate_api_key` | 🔴 Rotate API key — invalidate key cũ |
|
|
193
|
+
| `project_list_members` | List members + roles |
|
|
194
|
+
| `project_add_member` | Thêm user vào project |
|
|
195
|
+
| `project_update_member_role` | Đổi role (admin/editor/viewer) |
|
|
196
|
+
| `project_remove_member` | 🔴 Remove member |
|
|
197
|
+
|
|
198
|
+
### Monitors (7 tools)
|
|
199
|
+
|
|
200
|
+
| Tool | Mô tả |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `monitor_list` | List monitors trong project |
|
|
203
|
+
| `monitor_get` | Lấy chi tiết monitor |
|
|
204
|
+
| `monitor_create` | Tạo monitor (http/keyword/ping/tcp/ssl_cert) |
|
|
205
|
+
| `monitor_update` | Update monitor (partial) |
|
|
206
|
+
| `monitor_delete` | 🔴 Xóa monitor (yêu cầu `confirm_name`) |
|
|
207
|
+
| `monitor_toggle` | Pause / resume monitor |
|
|
208
|
+
| `monitor_get_results` | Lấy check history (default 50, max 500) |
|
|
209
|
+
|
|
210
|
+
### Status Pages (9 tools)
|
|
211
|
+
|
|
212
|
+
| Tool | Mô tả |
|
|
213
|
+
|---|---|
|
|
214
|
+
| `status_page_list` | List status pages trong project |
|
|
215
|
+
| `status_page_get` | Lấy chi tiết + components |
|
|
216
|
+
| `status_page_create` | Tạo status page với slug public |
|
|
217
|
+
| `status_page_update` | Update name/theme/logo |
|
|
218
|
+
| `status_page_delete` | 🔴 Xóa status page (yêu cầu `confirm_slug`) |
|
|
219
|
+
| `status_page_add_component` | Thêm component (có thể link monitors) |
|
|
220
|
+
| `status_page_update_component` | Update component |
|
|
221
|
+
| `status_page_delete_component` | 🔴 Xóa component |
|
|
222
|
+
| `status_page_reorder_components` | Sắp xếp thứ tự component |
|
|
223
|
+
|
|
224
|
+
### Incidents (6 tools)
|
|
225
|
+
|
|
226
|
+
| Tool | Mô tả |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `incident_list` | List incidents của 1 status page |
|
|
229
|
+
| `incident_get` | Lấy incident + timeline updates |
|
|
230
|
+
| `incident_create` | Tạo incident manual |
|
|
231
|
+
| `incident_update` | Update title/status/impact/components |
|
|
232
|
+
| `incident_add_update` | Thêm update vào timeline (public) |
|
|
233
|
+
| `incident_resolve` | Resolve incident với optional message |
|
|
234
|
+
|
|
235
|
+
### Errors (12 tools)
|
|
236
|
+
|
|
237
|
+
| Tool | Mô tả |
|
|
238
|
+
|---|---|
|
|
239
|
+
| `error_list` | List error groups của project |
|
|
240
|
+
| `error_get_project_stats` | Aggregate stats của project |
|
|
241
|
+
| `error_get` | Lấy chi tiết 1 error group |
|
|
242
|
+
| `error_get_summary` | Header summary (first/latest/total/IPs/users) |
|
|
243
|
+
| `error_get_timeseries` | Histogram occurrences theo hour/day/2w/2mo |
|
|
244
|
+
| `error_list_occurrences` | Paginated occurrences (cursor-based) |
|
|
245
|
+
| `error_get_occurrence` | Chi tiết 1 occurrence (stack, tags, user) |
|
|
246
|
+
| `error_get_occurrence_neighbors` | Latest/prev/next ids |
|
|
247
|
+
| `error_get_affected_ips` | Top IPs |
|
|
248
|
+
| `error_get_affected_users` | Top users |
|
|
249
|
+
| `error_resolve` | Mark resolved (auto-reopen nếu có occurrence mới) |
|
|
250
|
+
| `error_ignore` | Mark ignored (skip notifications) |
|
|
251
|
+
|
|
252
|
+
### Recipient Groups (4 tools)
|
|
253
|
+
|
|
254
|
+
| Tool | Mô tả |
|
|
255
|
+
|---|---|
|
|
256
|
+
| `recipient_group_list` | List email distribution groups |
|
|
257
|
+
| `recipient_group_create` | Tạo group (name + emails) |
|
|
258
|
+
| `recipient_group_update` | Update group |
|
|
259
|
+
| `recipient_group_delete` | 🔴 Xóa group |
|
|
260
|
+
|
|
261
|
+
### Invitations (4 tools)
|
|
262
|
+
|
|
263
|
+
| Tool | Mô tả |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `invitation_list` | List pending invitations |
|
|
266
|
+
| `invitation_create` | Mời user (email + role, optional pre-assign project) |
|
|
267
|
+
| `invitation_resend` | Regenerate token + re-send email |
|
|
268
|
+
| `invitation_revoke` | 🔴 Cancel pending invitation |
|
|
269
|
+
|
|
270
|
+
Legend:
|
|
271
|
+
- 🔴 = **DESTRUCTIVE** — yêu cầu confirmation parameter
|
|
272
|
+
- 🔐 = **SENSITIVE** — trả về secret, không log/share
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Resources & Prompts
|
|
277
|
+
|
|
278
|
+
### Resources (read-only)
|
|
279
|
+
|
|
280
|
+
Agent có thể list/fetch các URI sau qua `resources/list` và `resources/read`:
|
|
281
|
+
|
|
282
|
+
| URI | Mô tả |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `tinytracking://organizations` | Tất cả orgs user có quyền |
|
|
285
|
+
| `tinytracking://organizations/{orgId}/projects` | Projects trong 1 org |
|
|
286
|
+
| `tinytracking://projects/{projectId}/overview` | Project + monitors + status pages + error stats |
|
|
287
|
+
| `tinytracking://projects/{projectId}/monitors` | Monitors của project |
|
|
288
|
+
| `tinytracking://projects/{projectId}/errors/stats` | Error stats |
|
|
289
|
+
| `tinytracking://projects/{projectId}/monitors/{monitorId}/health-summary` | Monitor + recent results (50) |
|
|
290
|
+
|
|
291
|
+
### Prompts
|
|
292
|
+
|
|
293
|
+
3 prompt templates dùng làm slash commands trong MCP client:
|
|
294
|
+
|
|
295
|
+
| Prompt | Args | Mục đích |
|
|
296
|
+
|---|---|---|
|
|
297
|
+
| `triage-incident` | `incident_id` | Điều tra root cause incident |
|
|
298
|
+
| `summarize-error-group` | `error_group_id`, `timeframe?` | Tóm tắt error cho dev |
|
|
299
|
+
| `weekly-health-report` | `org_id?` | Báo cáo health tuần qua |
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Bảo mật & confirmation pattern
|
|
304
|
+
|
|
305
|
+
### Destructive actions
|
|
306
|
+
|
|
307
|
+
Các tool xóa/rotate/revoke đều yêu cầu một field xác nhận matching giá trị thật của resource:
|
|
308
|
+
|
|
309
|
+
| Tool | Field xác nhận | Match với |
|
|
310
|
+
|---|---|---|
|
|
311
|
+
| `org_delete` | `confirm_slug` | Org slug |
|
|
312
|
+
| `project_delete` | `confirm_name` | Project name |
|
|
313
|
+
| `project_regenerate_api_key` | `confirm_project_id` | Project UUID |
|
|
314
|
+
| `project_remove_member` | `confirm_user_id` | User UUID |
|
|
315
|
+
| `monitor_delete` | `confirm_name` | Monitor name |
|
|
316
|
+
| `status_page_delete` | `confirm_slug` | Status page slug |
|
|
317
|
+
| `status_page_delete_component` | `confirm_component_id` | Component UUID |
|
|
318
|
+
| `recipient_group_delete` | `confirm_group_id` | Group UUID |
|
|
319
|
+
| `invitation_revoke` | `confirm_invitation_id` | Invitation UUID |
|
|
320
|
+
| `org_remove_member` | `confirm_user_id` | User UUID |
|
|
321
|
+
|
|
322
|
+
Pattern này đảm bảo agent phải explicitly "repeat back" identifier — phòng case prompt injection hoặc nhầm lẫn UUID.
|
|
323
|
+
|
|
324
|
+
### Secrets
|
|
325
|
+
|
|
326
|
+
- `TT_API_KEY` **không bao giờ** được hard-code vào file commit. Luôn đọc từ env hoặc MCP client config.
|
|
327
|
+
- Logger tự động redact các field nhạy cảm: `authorization`, `apiKey`, `token`, `password`, `secret`.
|
|
328
|
+
- `project_reveal_api_key` trả full key — đừng share log của tool call này.
|
|
329
|
+
|
|
330
|
+
### Audit
|
|
331
|
+
|
|
332
|
+
Mọi HTTP request đều gắn header `X-MCP-Client: tiny-tracking-mcp/<version>`. Backend có thể filter audit log theo header này để phân biệt traffic agent vs UI.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Troubleshooting
|
|
337
|
+
|
|
338
|
+
### "Configuration error: TT_API_KEY still has placeholder value"
|
|
339
|
+
|
|
340
|
+
`.env` hoặc env client config vẫn chứa `tt_pat_replace_me`. Generate token thật ở dashboard → Settings → API tokens và thay vào.
|
|
341
|
+
|
|
342
|
+
### "Authentication/authorization failed (401/403)"
|
|
343
|
+
|
|
344
|
+
- Kiểm tra `TT_API_KEY` còn hợp lệ (chưa expire, chưa revoke). Vào dashboard → Settings → API tokens để xem trạng thái và `lastUsedAt` của từng token.
|
|
345
|
+
- Verify user owner của PAT là member của org/project bạn đang thao tác — PAT thừa kế đúng permissions của user.
|
|
346
|
+
- Nếu token bị nghi ngờ leak, revoke ngay ở dashboard và generate token mới — backend sẽ từ chối token cũ từ request kế tiếp.
|
|
347
|
+
|
|
348
|
+
### "Not found (404)"
|
|
349
|
+
|
|
350
|
+
UUID sai. Dùng resource `tinytracking://organizations` rồi đi xuống dần để chắc chắn lấy đúng id.
|
|
351
|
+
|
|
352
|
+
### Agent không thấy server
|
|
353
|
+
|
|
354
|
+
1. Check process Node có chạy không: `ps aux | grep tiny-tracking-mcp`
|
|
355
|
+
2. Xem stderr log — Claude Desktop log tại `~/Library/Logs/Claude/mcp*.log`
|
|
356
|
+
3. Verify path trong config trỏ tới `dist/index.js` đã build (`npm run build`)
|
|
357
|
+
4. Đảm bảo Node 22+: `node --version`
|
|
358
|
+
|
|
359
|
+
### "Origin ... not allowed by CORS"
|
|
360
|
+
|
|
361
|
+
Lỗi này KHÔNG xảy ra với MCP server (gọi server-to-server, không browser). Nếu thấy, backend đang reject Bearer token — kiểm tra `TT_API_URL` đúng và token hợp lệ.
|
|
362
|
+
|
|
363
|
+
### Stdout bị "ô nhiễm" — agent disconnect
|
|
364
|
+
|
|
365
|
+
Chỉ xảy ra nếu có code `console.log` lẻ trong codebase. Tất cả log phải đi qua [`logger.ts`](src/logger.ts:1) (ghi stderr). Nếu thêm code mới, KHÔNG dùng `console.log`.
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Phát triển
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
# Watch mode — auto-restart on file change
|
|
373
|
+
npm run dev
|
|
374
|
+
|
|
375
|
+
# Typecheck
|
|
376
|
+
npm run typecheck
|
|
377
|
+
|
|
378
|
+
# Build production bundle to dist/
|
|
379
|
+
npm run build
|
|
380
|
+
|
|
381
|
+
# Run tests (vitest)
|
|
382
|
+
npm test
|
|
383
|
+
|
|
384
|
+
# Lint
|
|
385
|
+
npm run lint
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Cấu trúc thư mục
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
mcp-server/
|
|
392
|
+
├── src/
|
|
393
|
+
│ ├── index.ts # Entrypoint — boots McpServer + StdioServerTransport
|
|
394
|
+
│ ├── config.ts # Env loader + zod validation
|
|
395
|
+
│ ├── http-client.ts # Axios + auth + retry + error mapping
|
|
396
|
+
│ ├── logger.ts # Pino → stderr (NEVER stdout)
|
|
397
|
+
│ ├── schemas/ # Zod schemas mirror các backend DTOs
|
|
398
|
+
│ ├── tools/ # 62 MCP tools (8 resource groups)
|
|
399
|
+
│ ├── resources/ # 6 read-only resource URIs
|
|
400
|
+
│ └── prompts/ # 3 prompt templates
|
|
401
|
+
├── test/ # vitest specs
|
|
402
|
+
├── dist/ # Build output (gitignored)
|
|
403
|
+
├── package.json
|
|
404
|
+
├── tsconfig.json
|
|
405
|
+
└── .env.example
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Thêm tool mới
|
|
409
|
+
|
|
410
|
+
1. Thêm schema (nếu cần) vào `src/schemas/<resource>.ts`.
|
|
411
|
+
2. Trong `src/tools/<resource>.ts`, thêm một `server.registerTool(...)` block theo pattern hiện có (dùng [`wrapHandler`](src/tools/_helpers.ts:1) + [`buildToolResult`](src/tools/_helpers.ts:1)).
|
|
412
|
+
3. Nếu là destructive action, dùng [`requireConfirmation`](src/tools/_helpers.ts:1).
|
|
413
|
+
4. `npm run typecheck && npm run build` để verify.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## License
|
|
418
|
+
|
|
419
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const configSchema: z.ZodObject<{
|
|
3
|
+
TT_API_URL: z.ZodEffects<z.ZodString, string, string>;
|
|
4
|
+
TT_API_KEY: z.ZodEffects<z.ZodString, string, string>;
|
|
5
|
+
TT_DEFAULT_ORG_ID: z.ZodOptional<z.ZodString>;
|
|
6
|
+
TT_HTTP_TIMEOUT_MS: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
TT_HTTP_RETRIES: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
TT_MCP_CLIENT_NAME: z.ZodOptional<z.ZodString>;
|
|
9
|
+
LOG_LEVEL: z.ZodDefault<z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal"]>>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
TT_API_URL: string;
|
|
12
|
+
TT_API_KEY: string;
|
|
13
|
+
TT_HTTP_TIMEOUT_MS: number;
|
|
14
|
+
TT_HTTP_RETRIES: number;
|
|
15
|
+
LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
16
|
+
TT_DEFAULT_ORG_ID?: string | undefined;
|
|
17
|
+
TT_MCP_CLIENT_NAME?: string | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
TT_API_URL: string;
|
|
20
|
+
TT_API_KEY: string;
|
|
21
|
+
TT_DEFAULT_ORG_ID?: string | undefined;
|
|
22
|
+
TT_HTTP_TIMEOUT_MS?: number | undefined;
|
|
23
|
+
TT_HTTP_RETRIES?: number | undefined;
|
|
24
|
+
TT_MCP_CLIENT_NAME?: string | undefined;
|
|
25
|
+
LOG_LEVEL?: "trace" | "debug" | "info" | "warn" | "error" | "fatal" | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
export type AppConfig = z.infer<typeof configSchema> & {
|
|
28
|
+
packageName: string;
|
|
29
|
+
packageVersion: string;
|
|
30
|
+
mcpClientHeader: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Load and validate configuration from environment variables.
|
|
34
|
+
*
|
|
35
|
+
* On validation failure, prints a clear error to stderr and exits(1) — this is
|
|
36
|
+
* intentional for stdio MCP servers, because returning an invalid config would
|
|
37
|
+
* cause downstream tools to fail in confusing ways.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadConfig(): AppConfig;
|
|
40
|
+
/** Reset cached config (used by tests). */
|
|
41
|
+
export declare function _resetConfigForTests(): void;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoCxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;EAkBhB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,GAAG;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,SAAS,CA2BtC;AAED,2CAA2C;AAC3C,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment configuration loader with zod validation.
|
|
3
|
+
*
|
|
4
|
+
* Loads from process.env (which may have been populated via dotenv when running
|
|
5
|
+
* locally, or directly by the MCP client config in production).
|
|
6
|
+
*/
|
|
7
|
+
import { config as loadDotenv } from 'dotenv';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { dirname, join } from 'node:path';
|
|
12
|
+
// Load .env from package root if present (no-op when vars are already set).
|
|
13
|
+
// This is a no-op in production where the MCP client sets `env` directly.
|
|
14
|
+
loadDotenv();
|
|
15
|
+
function readPackageJson() {
|
|
16
|
+
try {
|
|
17
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
// From src/ or dist/ — package.json is one level up
|
|
19
|
+
const pkgPath = join(here, '..', 'package.json');
|
|
20
|
+
const raw = readFileSync(pkgPath, 'utf-8');
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return { name: '@tinyweb_dev/tracking-mcp-server', version: '0.0.0' };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const pkg = readPackageJson();
|
|
28
|
+
/* ------------------------------------------------------------------ */
|
|
29
|
+
/* Schema */
|
|
30
|
+
/* ------------------------------------------------------------------ */
|
|
31
|
+
const configSchema = z.object({
|
|
32
|
+
TT_API_URL: z
|
|
33
|
+
.string()
|
|
34
|
+
.url('TT_API_URL must be a valid URL')
|
|
35
|
+
.transform((url) => url.replace(/\/+$/, '')), // strip trailing slashes
|
|
36
|
+
TT_API_KEY: z
|
|
37
|
+
.string()
|
|
38
|
+
.min(1, 'TT_API_KEY is required')
|
|
39
|
+
.refine((v) => v !== 'tt_pat_replace_me', {
|
|
40
|
+
message: 'TT_API_KEY still has placeholder value. Set a real token.',
|
|
41
|
+
}),
|
|
42
|
+
TT_DEFAULT_ORG_ID: z.string().min(1).optional(),
|
|
43
|
+
TT_HTTP_TIMEOUT_MS: z.coerce.number().int().positive().default(15000),
|
|
44
|
+
TT_HTTP_RETRIES: z.coerce.number().int().min(0).max(10).default(3),
|
|
45
|
+
TT_MCP_CLIENT_NAME: z.string().min(1).optional(),
|
|
46
|
+
LOG_LEVEL: z
|
|
47
|
+
.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])
|
|
48
|
+
.default('info'),
|
|
49
|
+
});
|
|
50
|
+
let cached = null;
|
|
51
|
+
/**
|
|
52
|
+
* Load and validate configuration from environment variables.
|
|
53
|
+
*
|
|
54
|
+
* On validation failure, prints a clear error to stderr and exits(1) — this is
|
|
55
|
+
* intentional for stdio MCP servers, because returning an invalid config would
|
|
56
|
+
* cause downstream tools to fail in confusing ways.
|
|
57
|
+
*/
|
|
58
|
+
export function loadConfig() {
|
|
59
|
+
if (cached)
|
|
60
|
+
return cached;
|
|
61
|
+
const parsed = configSchema.safeParse(process.env);
|
|
62
|
+
if (!parsed.success) {
|
|
63
|
+
const issues = parsed.error.issues
|
|
64
|
+
.map((i) => ` • ${i.path.join('.') || '<root>'}: ${i.message}`)
|
|
65
|
+
.join('\n');
|
|
66
|
+
// eslint-disable-next-line no-console
|
|
67
|
+
console.error(`\n[tiny-tracking-mcp] Configuration error:\n${issues}\n\n` +
|
|
68
|
+
`Required env vars: TT_API_URL, TT_API_KEY\n` +
|
|
69
|
+
`See .env.example for full list.\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const clientHeader = parsed.data.TT_MCP_CLIENT_NAME ?? `${pkg.name.split('/').pop()}/${pkg.version}`;
|
|
73
|
+
cached = {
|
|
74
|
+
...parsed.data,
|
|
75
|
+
packageName: pkg.name,
|
|
76
|
+
packageVersion: pkg.version,
|
|
77
|
+
mcpClientHeader: clientHeader,
|
|
78
|
+
};
|
|
79
|
+
return cached;
|
|
80
|
+
}
|
|
81
|
+
/** Reset cached config (used by tests). */
|
|
82
|
+
export function _resetConfigForTests() {
|
|
83
|
+
cached = null;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|