@t4dhg/mcp-factorial 1.1.0 → 2.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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * HTTP client with retry logic for MCP FactorialHR
3
+ *
4
+ * Implements exponential backoff retry for transient failures.
5
+ */
6
+ /**
7
+ * Request options for the HTTP client
8
+ */
9
+ export interface RequestOptions {
10
+ /** Query parameters */
11
+ params?: Record<string, string | number | boolean | undefined>;
12
+ /** Request timeout in milliseconds (overrides default) */
13
+ timeout?: number;
14
+ /** Maximum retry attempts (overrides default) */
15
+ maxRetries?: number;
16
+ /** Skip retry logic */
17
+ noRetry?: boolean;
18
+ }
19
+ /**
20
+ * Make an HTTP request with retry logic
21
+ */
22
+ export declare function factorialRequest<T>(endpoint: string, options?: RequestOptions): Promise<T>;
23
+ /**
24
+ * Wrapper type for paginated API responses
25
+ */
26
+ export interface ApiResponse<T> {
27
+ data: T;
28
+ }
29
+ /**
30
+ * Wrapper type for list API responses
31
+ */
32
+ export interface ApiListResponse<T> {
33
+ data: T[];
34
+ }
35
+ /**
36
+ * Make a request expecting a single item response
37
+ */
38
+ export declare function fetchOne<T>(endpoint: string, options?: RequestOptions): Promise<T>;
39
+ /**
40
+ * Make a request expecting a list response
41
+ */
42
+ export declare function fetchList<T>(endpoint: string, options?: RequestOptions): Promise<T[]>;
43
+ //# sourceMappingURL=http-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/D,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6ED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CA6DZ;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;CACX;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAGxF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAG3F"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * HTTP client with retry logic for MCP FactorialHR
3
+ *
4
+ * Implements exponential backoff retry for transient failures.
5
+ */
6
+ import { getConfig, debug, getApiKey } from './config.js';
7
+ import { AuthenticationError, AuthorizationError, NotFoundError, RateLimitError, ServerError, TimeoutError, NetworkError, isRetryableError, } from './errors.js';
8
+ /**
9
+ * Sleep for a given number of milliseconds
10
+ */
11
+ function sleep(ms) {
12
+ return new Promise(resolve => setTimeout(resolve, ms));
13
+ }
14
+ /**
15
+ * Calculate delay for exponential backoff
16
+ * @param attempt - Current attempt number (1-based)
17
+ * @param baseDelay - Base delay in milliseconds
18
+ * @returns Delay in milliseconds with jitter
19
+ */
20
+ function getBackoffDelay(attempt, baseDelay = 1000) {
21
+ const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);
22
+ const maxDelay = 10000; // Cap at 10 seconds
23
+ const delay = Math.min(exponentialDelay, maxDelay);
24
+ // Add jitter (±20%)
25
+ const jitter = delay * 0.2 * (Math.random() * 2 - 1);
26
+ return Math.round(delay + jitter);
27
+ }
28
+ /**
29
+ * Build URL with query parameters
30
+ */
31
+ function buildUrl(endpoint, params) {
32
+ const config = getConfig();
33
+ const url = new URL(`${config.baseUrl}${endpoint}`);
34
+ if (params) {
35
+ Object.entries(params).forEach(([key, value]) => {
36
+ if (value !== undefined && value !== null) {
37
+ url.searchParams.append(key, String(value));
38
+ }
39
+ });
40
+ }
41
+ return url.toString();
42
+ }
43
+ /**
44
+ * Handle HTTP response and throw appropriate errors
45
+ */
46
+ async function handleResponse(response, endpoint) {
47
+ if (response.ok) {
48
+ const data = (await response.json());
49
+ debug('Response received', { endpoint, status: response.status });
50
+ return data;
51
+ }
52
+ const errorText = await response.text();
53
+ debug(`API error (${response.status})`, { endpoint, error: errorText });
54
+ switch (response.status) {
55
+ case 401:
56
+ throw new AuthenticationError(endpoint);
57
+ case 403:
58
+ throw new AuthorizationError(endpoint);
59
+ case 404:
60
+ throw new NotFoundError(endpoint);
61
+ case 429: {
62
+ const retryAfter = response.headers.get('Retry-After');
63
+ throw new RateLimitError(endpoint, retryAfter ? parseInt(retryAfter, 10) : undefined);
64
+ }
65
+ default:
66
+ if (response.status >= 500) {
67
+ throw new ServerError(response.status, endpoint, errorText);
68
+ }
69
+ throw new Error(`FactorialHR API error (${response.status}): ${errorText}`);
70
+ }
71
+ }
72
+ /**
73
+ * Make an HTTP request with retry logic
74
+ */
75
+ export async function factorialRequest(endpoint, options = {}) {
76
+ const config = getConfig();
77
+ const url = buildUrl(endpoint, options.params);
78
+ const timeout = options.timeout ?? config.timeout;
79
+ const maxRetries = options.noRetry ? 1 : (options.maxRetries ?? config.maxRetries);
80
+ debug(`Fetching: ${url}`);
81
+ let lastError;
82
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
83
+ const controller = new AbortController();
84
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
85
+ try {
86
+ const response = await fetch(url, {
87
+ method: 'GET',
88
+ headers: {
89
+ 'x-api-key': getApiKey(),
90
+ Accept: 'application/json',
91
+ },
92
+ signal: controller.signal,
93
+ });
94
+ clearTimeout(timeoutId);
95
+ return await handleResponse(response, endpoint);
96
+ }
97
+ catch (error) {
98
+ clearTimeout(timeoutId);
99
+ // Convert abort to timeout error
100
+ if (error instanceof Error && error.name === 'AbortError') {
101
+ lastError = new TimeoutError(timeout, endpoint);
102
+ }
103
+ else if (error instanceof Error) {
104
+ lastError = error;
105
+ }
106
+ else {
107
+ lastError = new NetworkError('An unexpected network error occurred');
108
+ }
109
+ // Check if we should retry
110
+ const shouldRetry = attempt < maxRetries && isRetryableError(lastError);
111
+ if (shouldRetry) {
112
+ // Handle rate limit with Retry-After header
113
+ let delay;
114
+ if (lastError instanceof RateLimitError && lastError.retryAfter) {
115
+ delay = lastError.retryAfter * 1000;
116
+ }
117
+ else {
118
+ delay = getBackoffDelay(attempt);
119
+ }
120
+ debug(`Retry attempt ${attempt}/${maxRetries} after ${delay}ms`, {
121
+ error: lastError.message,
122
+ });
123
+ await sleep(delay);
124
+ }
125
+ else {
126
+ break;
127
+ }
128
+ }
129
+ }
130
+ throw lastError ?? new NetworkError('Request failed after all retries');
131
+ }
132
+ /**
133
+ * Make a request expecting a single item response
134
+ */
135
+ export async function fetchOne(endpoint, options) {
136
+ const response = await factorialRequest(endpoint, options);
137
+ return response.data;
138
+ }
139
+ /**
140
+ * Make a request expecting a list response
141
+ */
142
+ export async function fetchList(endpoint, options) {
143
+ const response = await factorialRequest(endpoint, options);
144
+ return response.data || [];
145
+ }
146
+ //# sourceMappingURL=http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,13 @@
4
4
  *
5
5
  * Provides access to employee and organizational data from FactorialHR
6
6
  * through the Model Context Protocol for use with Claude Code and other MCP clients.
7
+ *
8
+ * Features:
9
+ * - 22 tools for employees, teams, locations, contracts, time off, attendance, documents, and job catalog
10
+ * - Pagination support for all list operations
11
+ * - Caching for improved performance
12
+ * - Retry logic with exponential backoff
13
+ * - Runtime validation with Zod schemas
7
14
  */
8
15
  export {};
9
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG"}