@starasia/task-management-mcp 1.0.1 → 1.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/README.md +43 -4
- package/dist/auth-store.d.ts +16 -0
- package/dist/auth-store.js +85 -0
- package/dist/auth-store.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.js +26 -1
- package/dist/config.js.map +1 -1
- package/dist/generated-config.d.ts +1 -0
- package/dist/generated-config.js +4 -0
- package/dist/generated-config.js.map +1 -0
- package/dist/hris-api.d.ts +10 -0
- package/dist/hris-api.js +108 -0
- package/dist/hris-api.js.map +1 -0
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/sso-api.d.ts +78 -0
- package/dist/sso-api.js +140 -0
- package/dist/sso-api.js.map +1 -0
- package/dist/tools.d.ts +17 -1
- package/dist/tools.js +733 -17
- package/dist/tools.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ MCP server for Star Perkasa Technology Task Management.
|
|
|
4
4
|
|
|
5
5
|
Package ini membantu AI agent membaca, membuat, memperbarui, memantau, dan merangkum task melalui Task Management API dengan permission sesuai user aktif.
|
|
6
6
|
|
|
7
|
-
Server ini
|
|
7
|
+
Server ini menyimpan auth context secara aman di runtime/persistent local store agar agent tidak perlu meminta login berulang selama token masih valid. Token tidak pernah dikembalikan ke output tool.
|
|
8
8
|
|
|
9
9
|
## Requirements
|
|
10
10
|
|
|
@@ -98,6 +98,11 @@ Untuk client lain yang memakai format JSON `mcpServers`:
|
|
|
98
98
|
|
|
99
99
|
### Auth/session
|
|
100
100
|
|
|
101
|
+
- `sso_login`
|
|
102
|
+
- `select_sso_organization`
|
|
103
|
+
- `start_web_sso_login`
|
|
104
|
+
- `check_web_sso_login`
|
|
105
|
+
- `cancel_web_sso_login`
|
|
101
106
|
- `set_auth_context`
|
|
102
107
|
- `get_auth_context_status`
|
|
103
108
|
- `clear_auth_context`
|
|
@@ -137,11 +142,45 @@ Assignee tools use project member ids from `list_project_members`.
|
|
|
137
142
|
|
|
138
143
|
## Auth model
|
|
139
144
|
|
|
140
|
-
Before using task tools, the agent should check whether an auth context is configured. If not,
|
|
145
|
+
Before using task tools, the agent should check whether an auth context is configured. If not, prefer SSO login instead of asking for a raw bearer token.
|
|
141
146
|
|
|
142
|
-
|
|
147
|
+
Recommended flow for chat-based agents:
|
|
143
148
|
|
|
144
|
-
Call `
|
|
149
|
+
1. Call `get_auth_context_status`.
|
|
150
|
+
2. If not configured, prefer `start_web_sso_login` and present the returned login URL/button to the user.
|
|
151
|
+
3. The user enters email/password in the browser form, not in chat.
|
|
152
|
+
4. Poll or call `check_web_sso_login` with the returned session id.
|
|
153
|
+
5. When completed, the MCP activates and persists the auth context without returning the token.
|
|
154
|
+
6. Use the task tools.
|
|
155
|
+
|
|
156
|
+
CLI/local fallback flow:
|
|
157
|
+
|
|
158
|
+
1. Call `sso_login` with the user's SSO email/password only when the platform can handle secrets safely.
|
|
159
|
+
2. If `sso_login` returns multiple organizations, present organization **names** in a human-friendly list and ask which organization should be used. Do not ask the user to copy an organization ID.
|
|
160
|
+
3. Call `select_sso_organization` with the user's typed organization name. The MCP supports normalized/fuzzy matching, so close inputs such as `star perkasa` can match `PT Star Perkasa Technology`.
|
|
161
|
+
4. Use the task tools.
|
|
162
|
+
|
|
163
|
+
Manual fallback remains available through `set_auth_context` when explicitly needed.
|
|
164
|
+
|
|
165
|
+
The MCP stores auth context in an encrypted local store and process memory, returns masked auth status, and never returns the bearer token from any tool.
|
|
166
|
+
|
|
167
|
+
Call `clear_auth_context` when the session is done; it clears process state, pending SSO sessions, web login sessions, and the persisted auth store.
|
|
168
|
+
|
|
169
|
+
### SSO configuration
|
|
170
|
+
|
|
171
|
+
For SSO login, provide the Task Management module client ID via environment:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
TASK_MANAGEMENT_SSO_CLIENT_ID=APP-xxxxxxxx
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Optional SSO API base URL override, mainly for local/dev testing:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
TASK_MANAGEMENT_SSO_API_BASE_URL=https://api.starasia.tech/sso
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Passwords are accepted only by `sso_login`; the resulting token stays in MCP process memory and is never returned.
|
|
145
184
|
|
|
146
185
|
## Safety notes
|
|
147
186
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface StoredAuthContext {
|
|
2
|
+
bearerToken: string;
|
|
3
|
+
userId: string;
|
|
4
|
+
organizationId: string;
|
|
5
|
+
environment?: string;
|
|
6
|
+
expiresAt: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class AuthStore {
|
|
9
|
+
private readonly storePath;
|
|
10
|
+
private readonly keyMaterial?;
|
|
11
|
+
constructor(storePath: string, keyMaterial?: string | undefined);
|
|
12
|
+
load(): StoredAuthContext | undefined;
|
|
13
|
+
save(context: StoredAuthContext): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
private resolveKeyMaterial;
|
|
16
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, createHash, randomBytes, } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
export class AuthStore {
|
|
5
|
+
storePath;
|
|
6
|
+
keyMaterial;
|
|
7
|
+
constructor(storePath, keyMaterial) {
|
|
8
|
+
this.storePath = storePath;
|
|
9
|
+
this.keyMaterial = keyMaterial;
|
|
10
|
+
}
|
|
11
|
+
load() {
|
|
12
|
+
if (!existsSync(this.storePath))
|
|
13
|
+
return undefined;
|
|
14
|
+
try {
|
|
15
|
+
const payload = JSON.parse(readFileSync(this.storePath, "utf8"));
|
|
16
|
+
if (payload.version !== 1 || payload.algorithm !== "aes-256-gcm")
|
|
17
|
+
return undefined;
|
|
18
|
+
const decipher = createDecipheriv("aes-256-gcm", deriveKey(this.resolveKeyMaterial()), Buffer.from(payload.iv, "base64url"));
|
|
19
|
+
decipher.setAuthTag(Buffer.from(payload.tag, "base64url"));
|
|
20
|
+
const decrypted = Buffer.concat([
|
|
21
|
+
decipher.update(Buffer.from(payload.data, "base64url")),
|
|
22
|
+
decipher.final(),
|
|
23
|
+
]).toString("utf8");
|
|
24
|
+
const context = JSON.parse(decrypted);
|
|
25
|
+
if (!isStoredAuthContext(context))
|
|
26
|
+
return undefined;
|
|
27
|
+
if (new Date(context.expiresAt).getTime() <= Date.now()) {
|
|
28
|
+
this.clear();
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return context;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
save(context) {
|
|
38
|
+
mkdirSync(dirname(this.storePath), { recursive: true, mode: 0o700 });
|
|
39
|
+
const iv = randomBytes(12);
|
|
40
|
+
const cipher = createCipheriv("aes-256-gcm", deriveKey(this.resolveKeyMaterial()), iv);
|
|
41
|
+
const encrypted = Buffer.concat([
|
|
42
|
+
cipher.update(JSON.stringify(context), "utf8"),
|
|
43
|
+
cipher.final(),
|
|
44
|
+
]);
|
|
45
|
+
const payload = {
|
|
46
|
+
version: 1,
|
|
47
|
+
algorithm: "aes-256-gcm",
|
|
48
|
+
iv: iv.toString("base64url"),
|
|
49
|
+
tag: cipher.getAuthTag().toString("base64url"),
|
|
50
|
+
data: encrypted.toString("base64url"),
|
|
51
|
+
};
|
|
52
|
+
writeFileSync(this.storePath, JSON.stringify(payload), { mode: 0o600 });
|
|
53
|
+
}
|
|
54
|
+
clear() {
|
|
55
|
+
rmSync(this.storePath, { force: true });
|
|
56
|
+
}
|
|
57
|
+
resolveKeyMaterial() {
|
|
58
|
+
if (this.keyMaterial)
|
|
59
|
+
return this.keyMaterial;
|
|
60
|
+
const keyPath = `${this.storePath}.key`;
|
|
61
|
+
mkdirSync(dirname(keyPath), { recursive: true, mode: 0o700 });
|
|
62
|
+
if (existsSync(keyPath))
|
|
63
|
+
return readFileSync(keyPath, "utf8");
|
|
64
|
+
const generatedKey = randomBytes(32).toString("base64url");
|
|
65
|
+
writeFileSync(keyPath, generatedKey, { mode: 0o600 });
|
|
66
|
+
return generatedKey;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function deriveKey(keyMaterial) {
|
|
70
|
+
return createHash("sha256").update(keyMaterial).digest();
|
|
71
|
+
}
|
|
72
|
+
function isStoredAuthContext(value) {
|
|
73
|
+
if (!value || typeof value !== "object")
|
|
74
|
+
return false;
|
|
75
|
+
const candidate = value;
|
|
76
|
+
return Boolean(typeof candidate.bearerToken === "string" &&
|
|
77
|
+
candidate.bearerToken &&
|
|
78
|
+
typeof candidate.userId === "string" &&
|
|
79
|
+
candidate.userId &&
|
|
80
|
+
typeof candidate.organizationId === "string" &&
|
|
81
|
+
candidate.organizationId &&
|
|
82
|
+
typeof candidate.expiresAt === "string" &&
|
|
83
|
+
candidate.expiresAt);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=auth-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../src/auth-store.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -4,16 +4,43 @@ declare const envSchema: z.ZodObject<{
|
|
|
4
4
|
TASK_MANAGEMENT_TIMEOUT_MS: z.ZodDefault<z.ZodNumber>;
|
|
5
5
|
TASK_MANAGEMENT_MAX_BULK_SIZE: z.ZodDefault<z.ZodNumber>;
|
|
6
6
|
TASK_MANAGEMENT_AUTH_TTL_MS: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
TASK_MANAGEMENT_SSO_CLIENT_ID: z.ZodOptional<z.ZodString>;
|
|
8
|
+
TASK_MANAGEMENT_SSO_API_BASE_URL: z.ZodDefault<z.ZodString>;
|
|
9
|
+
TASK_MANAGEMENT_HRIS_API_BASE_URL: z.ZodOptional<z.ZodString>;
|
|
10
|
+
TASK_MANAGEMENT_AUTH_STORE_PATH: z.ZodDefault<z.ZodString>;
|
|
11
|
+
TASK_MANAGEMENT_AUTH_STORE_KEY: z.ZodOptional<z.ZodString>;
|
|
12
|
+
TASK_MANAGEMENT_WEB_LOGIN_HOST: z.ZodDefault<z.ZodString>;
|
|
13
|
+
TASK_MANAGEMENT_WEB_LOGIN_PORT: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
TASK_MANAGEMENT_WEB_LOGIN_PUBLIC_BASE_URL: z.ZodOptional<z.ZodString>;
|
|
15
|
+
TASK_MANAGEMENT_WEB_LOGIN_TTL_MS: z.ZodDefault<z.ZodNumber>;
|
|
7
16
|
}, "strip", z.ZodTypeAny, {
|
|
8
17
|
TASK_MANAGEMENT_API_BASE_URL: string;
|
|
9
18
|
TASK_MANAGEMENT_TIMEOUT_MS: number;
|
|
10
19
|
TASK_MANAGEMENT_MAX_BULK_SIZE: number;
|
|
11
20
|
TASK_MANAGEMENT_AUTH_TTL_MS: number;
|
|
21
|
+
TASK_MANAGEMENT_SSO_API_BASE_URL: string;
|
|
22
|
+
TASK_MANAGEMENT_AUTH_STORE_PATH: string;
|
|
23
|
+
TASK_MANAGEMENT_WEB_LOGIN_HOST: string;
|
|
24
|
+
TASK_MANAGEMENT_WEB_LOGIN_PORT: number;
|
|
25
|
+
TASK_MANAGEMENT_WEB_LOGIN_TTL_MS: number;
|
|
26
|
+
TASK_MANAGEMENT_SSO_CLIENT_ID?: string | undefined;
|
|
27
|
+
TASK_MANAGEMENT_HRIS_API_BASE_URL?: string | undefined;
|
|
28
|
+
TASK_MANAGEMENT_AUTH_STORE_KEY?: string | undefined;
|
|
29
|
+
TASK_MANAGEMENT_WEB_LOGIN_PUBLIC_BASE_URL?: string | undefined;
|
|
12
30
|
}, {
|
|
13
31
|
TASK_MANAGEMENT_API_BASE_URL?: string | undefined;
|
|
14
32
|
TASK_MANAGEMENT_TIMEOUT_MS?: number | undefined;
|
|
15
33
|
TASK_MANAGEMENT_MAX_BULK_SIZE?: number | undefined;
|
|
16
34
|
TASK_MANAGEMENT_AUTH_TTL_MS?: number | undefined;
|
|
35
|
+
TASK_MANAGEMENT_SSO_CLIENT_ID?: string | undefined;
|
|
36
|
+
TASK_MANAGEMENT_SSO_API_BASE_URL?: string | undefined;
|
|
37
|
+
TASK_MANAGEMENT_HRIS_API_BASE_URL?: string | undefined;
|
|
38
|
+
TASK_MANAGEMENT_AUTH_STORE_PATH?: string | undefined;
|
|
39
|
+
TASK_MANAGEMENT_AUTH_STORE_KEY?: string | undefined;
|
|
40
|
+
TASK_MANAGEMENT_WEB_LOGIN_HOST?: string | undefined;
|
|
41
|
+
TASK_MANAGEMENT_WEB_LOGIN_PORT?: number | undefined;
|
|
42
|
+
TASK_MANAGEMENT_WEB_LOGIN_PUBLIC_BASE_URL?: string | undefined;
|
|
43
|
+
TASK_MANAGEMENT_WEB_LOGIN_TTL_MS?: number | undefined;
|
|
17
44
|
}>;
|
|
18
45
|
export type RuntimeConfig = z.infer<typeof envSchema>;
|
|
19
46
|
export declare function loadConfig(env?: NodeJS.ProcessEnv): RuntimeConfig;
|
package/dist/config.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
1
3
|
import { z } from "zod";
|
|
4
|
+
import { BUILD_TASK_MANAGEMENT_API_BASE_URL } from "./generated-config.js";
|
|
5
|
+
const DEFAULT_TASK_MANAGEMENT_API_BASE_URL = BUILD_TASK_MANAGEMENT_API_BASE_URL || "http://localhost:3000";
|
|
6
|
+
const DEFAULT_TASK_MANAGEMENT_SSO_API_BASE_URL = "https://api.starasia.tech/sso";
|
|
7
|
+
const DEFAULT_AUTH_STORE_PATH = join(homedir(), ".starasia", "task-management-mcp", "auth-context.enc");
|
|
2
8
|
const envSchema = z.object({
|
|
3
9
|
TASK_MANAGEMENT_API_BASE_URL: z
|
|
4
10
|
.string()
|
|
5
11
|
.url()
|
|
6
|
-
.default(
|
|
12
|
+
.default(DEFAULT_TASK_MANAGEMENT_API_BASE_URL),
|
|
7
13
|
TASK_MANAGEMENT_TIMEOUT_MS: z.coerce
|
|
8
14
|
.number()
|
|
9
15
|
.int()
|
|
@@ -15,6 +21,25 @@ const envSchema = z.object({
|
|
|
15
21
|
.int()
|
|
16
22
|
.positive()
|
|
17
23
|
.default(8 * 60 * 60 * 1000),
|
|
24
|
+
TASK_MANAGEMENT_SSO_CLIENT_ID: z.string().min(1).optional(),
|
|
25
|
+
TASK_MANAGEMENT_SSO_API_BASE_URL: z
|
|
26
|
+
.string()
|
|
27
|
+
.url()
|
|
28
|
+
.default(DEFAULT_TASK_MANAGEMENT_SSO_API_BASE_URL),
|
|
29
|
+
TASK_MANAGEMENT_HRIS_API_BASE_URL: z.string().url().optional(),
|
|
30
|
+
TASK_MANAGEMENT_AUTH_STORE_PATH: z
|
|
31
|
+
.string()
|
|
32
|
+
.min(1)
|
|
33
|
+
.default(DEFAULT_AUTH_STORE_PATH),
|
|
34
|
+
TASK_MANAGEMENT_AUTH_STORE_KEY: z.string().min(1).optional(),
|
|
35
|
+
TASK_MANAGEMENT_WEB_LOGIN_HOST: z.string().min(1).default("127.0.0.1"),
|
|
36
|
+
TASK_MANAGEMENT_WEB_LOGIN_PORT: z.coerce.number().int().min(0).default(0),
|
|
37
|
+
TASK_MANAGEMENT_WEB_LOGIN_PUBLIC_BASE_URL: z.string().url().optional(),
|
|
38
|
+
TASK_MANAGEMENT_WEB_LOGIN_TTL_MS: z.coerce
|
|
39
|
+
.number()
|
|
40
|
+
.int()
|
|
41
|
+
.positive()
|
|
42
|
+
.default(5 * 60 * 1000),
|
|
18
43
|
});
|
|
19
44
|
export function loadConfig(env = process.env) {
|
|
20
45
|
return envSchema.parse(env);
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,4BAA4B,EAAE,CAAC;SAC5B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kCAAkC,EAAE,MAAM,uBAAuB,CAAC;AAE3E,MAAM,oCAAoC,GACxC,kCAAkC,IAAI,uBAAuB,CAAC;AAChE,MAAM,wCAAwC,GAC5C,+BAA+B,CAAC;AAClC,MAAM,uBAAuB,GAAG,IAAI,CAClC,OAAO,EAAE,EACT,WAAW,EACX,qBAAqB,EACrB,kBAAkB,CACnB,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,4BAA4B,EAAE,CAAC;SAC5B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,OAAO,CAAC,oCAAoC,CAAC;IAChD,0BAA0B,EAAE,CAAC,CAAC,MAAM;SACjC,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,OAAO,CAAC,MAAM,CAAC;IAClB,6BAA6B,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7E,2BAA2B,EAAE,CAAC,CAAC,MAAM;SAClC,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC9B,6BAA6B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3D,gCAAgC,EAAE,CAAC;SAChC,MAAM,EAAE;SACR,GAAG,EAAE;SACL,OAAO,CAAC,wCAAwC,CAAC;IACpD,iCAAiC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC9D,+BAA+B,EAAE,CAAC;SAC/B,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,uBAAuB,CAAC;IACnC,8BAA8B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5D,8BAA8B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IACtE,8BAA8B,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACzE,yCAAyC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACtE,gCAAgC,EAAE,CAAC,CAAC,MAAM;SACvC,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;CAC1B,CAAC,CAAC;AAIH,MAAM,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC1C,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const BUILD_TASK_MANAGEMENT_API_BASE_URL = "https://api.starasia.tech/task-management";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// This file is generated by scripts/generate-build-config.mjs.
|
|
2
|
+
// BUILD_TASK_MANAGEMENT_API_BASE_URL is injected by CI for published builds.
|
|
3
|
+
export const BUILD_TASK_MANAGEMENT_API_BASE_URL = "https://api.starasia.tech/task-management";
|
|
4
|
+
//# sourceMappingURL=generated-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated-config.js","sourceRoot":"","sources":["../src/generated-config.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kCAAkC,GAAG,2CAA2C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SsoOrganizationOption } from "./sso-api.js";
|
|
2
|
+
export declare class HrisApi {
|
|
3
|
+
private readonly baseUrl;
|
|
4
|
+
private readonly timeoutMs;
|
|
5
|
+
constructor(baseUrl: string | undefined, timeoutMs: number);
|
|
6
|
+
listSwitchOrganizations(input: {
|
|
7
|
+
bearerToken: string;
|
|
8
|
+
}): Promise<SsoOrganizationOption[]>;
|
|
9
|
+
private request;
|
|
10
|
+
}
|
package/dist/hris-api.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { SsoApiError } from "./sso-api.js";
|
|
2
|
+
export class HrisApi {
|
|
3
|
+
baseUrl;
|
|
4
|
+
timeoutMs;
|
|
5
|
+
constructor(baseUrl, timeoutMs) {
|
|
6
|
+
this.baseUrl = baseUrl;
|
|
7
|
+
this.timeoutMs = timeoutMs;
|
|
8
|
+
}
|
|
9
|
+
async listSwitchOrganizations(input) {
|
|
10
|
+
if (!this.baseUrl) {
|
|
11
|
+
throw new Error("TASK_MANAGEMENT_HRIS_API_BASE_URL is not configured. Set it to the HRIS API base URL so MCP can fetch user organizations server-side.");
|
|
12
|
+
}
|
|
13
|
+
const rows = await this.request("GET", "admin/switch-organizations", undefined, { status: "active", perPage: 100 }, input.bearerToken);
|
|
14
|
+
const seen = new Set();
|
|
15
|
+
const organizations = [];
|
|
16
|
+
for (const row of rows) {
|
|
17
|
+
const id = typeof row.id === "string" ? row.id.trim() : "";
|
|
18
|
+
const name = typeof row.name === "string" ? row.name.trim() : "";
|
|
19
|
+
if (!id || !name || seen.has(id))
|
|
20
|
+
continue;
|
|
21
|
+
seen.add(id);
|
|
22
|
+
organizations.push({
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
isActive: typeof row.isActive === "boolean" ? row.isActive : undefined,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return organizations;
|
|
29
|
+
}
|
|
30
|
+
async request(method, path, body, query, bearerToken) {
|
|
31
|
+
const url = new URL(path, this.baseUrl.replace(/\/$/, "") + "/");
|
|
32
|
+
for (const [key, value] of Object.entries(query ?? {})) {
|
|
33
|
+
if (value === undefined || value === null || value === "")
|
|
34
|
+
continue;
|
|
35
|
+
url.searchParams.set(key, String(value));
|
|
36
|
+
}
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
39
|
+
try {
|
|
40
|
+
const headers = { Accept: "application/json" };
|
|
41
|
+
if (body !== undefined)
|
|
42
|
+
headers["Content-Type"] = "application/json";
|
|
43
|
+
if (bearerToken)
|
|
44
|
+
headers.Authorization = normalizeBearerToken(bearerToken);
|
|
45
|
+
const response = await fetch(url, {
|
|
46
|
+
method,
|
|
47
|
+
headers,
|
|
48
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
});
|
|
51
|
+
const text = await response.text();
|
|
52
|
+
const payload = parsePayload(text);
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new SsoApiError(extractErrorMessage(payload, response.statusText), response.status, payload);
|
|
55
|
+
}
|
|
56
|
+
if (isEnvelope(payload))
|
|
57
|
+
return payload.data;
|
|
58
|
+
return payload;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof SsoApiError)
|
|
62
|
+
throw error;
|
|
63
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
64
|
+
throw new SsoApiError("HRIS API request timed out", 408, undefined);
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
clearTimeout(timeout);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isEnvelope(payload) {
|
|
74
|
+
return Boolean(payload && typeof payload === "object" && "data" in payload);
|
|
75
|
+
}
|
|
76
|
+
function parsePayload(text) {
|
|
77
|
+
if (!text)
|
|
78
|
+
return undefined;
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(text);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { message: text };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function extractErrorMessage(payload, fallback) {
|
|
87
|
+
if (payload &&
|
|
88
|
+
typeof payload === "object" &&
|
|
89
|
+
"message" in payload &&
|
|
90
|
+
typeof payload.message === "string")
|
|
91
|
+
return payload.message;
|
|
92
|
+
if (payload &&
|
|
93
|
+
typeof payload === "object" &&
|
|
94
|
+
"error" in payload &&
|
|
95
|
+
payload.error &&
|
|
96
|
+
typeof payload.error === "object" &&
|
|
97
|
+
"message" in payload.error &&
|
|
98
|
+
typeof payload.error.message === "string")
|
|
99
|
+
return payload.error.message;
|
|
100
|
+
return fallback;
|
|
101
|
+
}
|
|
102
|
+
function normalizeBearerToken(token) {
|
|
103
|
+
const trimmed = token.trim();
|
|
104
|
+
return trimmed.toLowerCase().startsWith("bearer ")
|
|
105
|
+
? trimmed
|
|
106
|
+
: `Bearer ${trimmed}`;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=hris-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hris-api.js","sourceRoot":"","sources":["../src/hris-api.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,13 +3,27 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { loadConfig } from "./config.js";
|
|
5
5
|
import { TaskManagementApi } from "./api.js";
|
|
6
|
+
import { HrisApi } from "./hris-api.js";
|
|
7
|
+
import { SsoApi } from "./sso-api.js";
|
|
8
|
+
import { AuthStore } from "./auth-store.js";
|
|
6
9
|
import { registerTools } from "./tools.js";
|
|
7
10
|
const config = loadConfig();
|
|
8
11
|
const server = new McpServer({
|
|
9
12
|
name: "task-management-mcp",
|
|
10
13
|
version: "0.1.0",
|
|
11
14
|
});
|
|
12
|
-
registerTools(server, new TaskManagementApi(config), config.
|
|
15
|
+
registerTools(server, new TaskManagementApi(config), new SsoApi(config.TASK_MANAGEMENT_SSO_API_BASE_URL, config.TASK_MANAGEMENT_TIMEOUT_MS), new HrisApi(config.TASK_MANAGEMENT_HRIS_API_BASE_URL, config.TASK_MANAGEMENT_TIMEOUT_MS), {
|
|
16
|
+
maxBulkSize: config.TASK_MANAGEMENT_MAX_BULK_SIZE,
|
|
17
|
+
authTtlMs: config.TASK_MANAGEMENT_AUTH_TTL_MS,
|
|
18
|
+
defaultSsoClientId: config.TASK_MANAGEMENT_SSO_CLIENT_ID,
|
|
19
|
+
authStore: new AuthStore(config.TASK_MANAGEMENT_AUTH_STORE_PATH, config.TASK_MANAGEMENT_AUTH_STORE_KEY),
|
|
20
|
+
webLogin: {
|
|
21
|
+
host: config.TASK_MANAGEMENT_WEB_LOGIN_HOST,
|
|
22
|
+
port: config.TASK_MANAGEMENT_WEB_LOGIN_PORT,
|
|
23
|
+
publicBaseUrl: config.TASK_MANAGEMENT_WEB_LOGIN_PUBLIC_BASE_URL,
|
|
24
|
+
ttlMs: config.TASK_MANAGEMENT_WEB_LOGIN_TTL_MS,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
13
27
|
const transport = new StdioServerTransport();
|
|
14
28
|
await server.connect(transport);
|
|
15
29
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAC5B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,aAAa,CACX,MAAM,EACN,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAC7B,MAAM,CAAC,6BAA6B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAC5B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,aAAa,CACX,MAAM,EACN,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAC7B,IAAI,MAAM,CACR,MAAM,CAAC,gCAAgC,EACvC,MAAM,CAAC,0BAA0B,CAClC,EACD,IAAI,OAAO,CACT,MAAM,CAAC,iCAAiC,EACxC,MAAM,CAAC,0BAA0B,CAClC,EACD;IACE,WAAW,EAAE,MAAM,CAAC,6BAA6B;IACjD,SAAS,EAAE,MAAM,CAAC,2BAA2B;IAC7C,kBAAkB,EAAE,MAAM,CAAC,6BAA6B;IACxD,SAAS,EAAE,IAAI,SAAS,CACtB,MAAM,CAAC,+BAA+B,EACtC,MAAM,CAAC,8BAA8B,CACtC;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC,8BAA8B;QAC3C,IAAI,EAAE,MAAM,CAAC,8BAA8B;QAC3C,aAAa,EAAE,MAAM,CAAC,yCAAyC;QAC/D,KAAK,EAAE,MAAM,CAAC,gCAAgC;KAC/C;CACF,CACF,CAAC;AAEF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface SsoApplicationOption {
|
|
2
|
+
id?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
clientId?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SsoRoleOption {
|
|
7
|
+
id?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
key?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SsoOrganizationOption {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
isActive?: boolean;
|
|
15
|
+
application?: SsoApplicationOption | null;
|
|
16
|
+
role?: SsoRoleOption | null;
|
|
17
|
+
}
|
|
18
|
+
export interface SsoLoginResult {
|
|
19
|
+
authToken?: string;
|
|
20
|
+
redirectUri?: string;
|
|
21
|
+
requirePasswordChange?: boolean;
|
|
22
|
+
resetToken?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SsoHandoffResult {
|
|
25
|
+
status: "pending" | "completed";
|
|
26
|
+
authToken?: string;
|
|
27
|
+
userId?: string;
|
|
28
|
+
organizationId?: string;
|
|
29
|
+
organizationName?: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface SsoAccessTokenResult {
|
|
33
|
+
accessToken: string;
|
|
34
|
+
idToken?: string;
|
|
35
|
+
refreshToken?: string;
|
|
36
|
+
tokenType?: string;
|
|
37
|
+
expiresIn?: number;
|
|
38
|
+
userId?: string;
|
|
39
|
+
organization?: SsoOrganizationOption | null;
|
|
40
|
+
requireOrganizationSetup?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare class SsoApiError extends Error {
|
|
43
|
+
readonly status: number;
|
|
44
|
+
readonly payload: unknown;
|
|
45
|
+
constructor(message: string, status: number, payload: unknown);
|
|
46
|
+
}
|
|
47
|
+
export declare class SsoApi {
|
|
48
|
+
private readonly baseUrl;
|
|
49
|
+
private readonly timeoutMs;
|
|
50
|
+
constructor(baseUrl: string, timeoutMs: number);
|
|
51
|
+
login(input: {
|
|
52
|
+
email: string;
|
|
53
|
+
password: string;
|
|
54
|
+
clientId: string;
|
|
55
|
+
mode?: string;
|
|
56
|
+
}): Promise<SsoLoginResult>;
|
|
57
|
+
listUserOrganizations(input: {
|
|
58
|
+
userId: string;
|
|
59
|
+
clientId: string;
|
|
60
|
+
bearerToken: string;
|
|
61
|
+
}): Promise<SsoOrganizationOption[]>;
|
|
62
|
+
consumeTaskManagementMcpHandoff(input: {
|
|
63
|
+
sessionId: string;
|
|
64
|
+
secret: string;
|
|
65
|
+
}): Promise<SsoHandoffResult>;
|
|
66
|
+
completeTaskManagementMcpHandoff(input: {
|
|
67
|
+
sessionId: string;
|
|
68
|
+
secret: string;
|
|
69
|
+
authToken: string;
|
|
70
|
+
}): Promise<SsoHandoffResult>;
|
|
71
|
+
exchangeTaskManagementMcpAccessToken(input: {
|
|
72
|
+
sessionId: string;
|
|
73
|
+
secret: string;
|
|
74
|
+
clientId: string;
|
|
75
|
+
organizationId: string;
|
|
76
|
+
}): Promise<SsoAccessTokenResult>;
|
|
77
|
+
private request;
|
|
78
|
+
}
|