@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 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 tidak menyimpan token global. Akses API memakai auth context runtime yang diberikan oleh user aktif melalui tool MCP.
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, it should ask the active user for the required runtime credentials and call `set_auth_context`.
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
- The MCP keeps auth context in process memory only, returns masked auth status, and never returns the bearer token from any tool.
147
+ Recommended flow for chat-based agents:
143
148
 
144
- Call `clear_auth_context` when the session is done.
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("http://localhost:3000"),
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);
@@ -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,uBAAuB,CAAC;IACnC,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;CAC/B,CAAC,CAAC;AAIH,MAAM,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC1C,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9B,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
+ }
@@ -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.TASK_MANAGEMENT_MAX_BULK_SIZE, config.TASK_MANAGEMENT_AUTH_TTL_MS);
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,EACpC,MAAM,CAAC,2BAA2B,CACnC,CAAC;AAEF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
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
+ }