@goodsamsoftware/freshbooks-mcp 1.0.0 → 1.0.2

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.
Files changed (199) hide show
  1. package/README.md +2 -2
  2. package/dist/auth/confirmation-store.d.ts +94 -0
  3. package/dist/auth/confirmation-store.d.ts.map +1 -0
  4. package/dist/auth/confirmation-store.js +126 -0
  5. package/dist/auth/confirmation-store.js.map +1 -0
  6. package/dist/auth/state-store.d.ts +96 -0
  7. package/dist/auth/state-store.d.ts.map +1 -0
  8. package/dist/auth/state-store.js +122 -0
  9. package/dist/auth/state-store.js.map +1 -0
  10. package/dist/auth/types.d.ts +1 -1
  11. package/dist/auth/types.d.ts.map +1 -1
  12. package/dist/auth/types.js.map +1 -1
  13. package/dist/config/environment.d.ts +25 -0
  14. package/dist/config/environment.d.ts.map +1 -0
  15. package/dist/config/environment.js +39 -0
  16. package/dist/config/environment.js.map +1 -0
  17. package/dist/errors/error-handler.d.ts.map +1 -1
  18. package/dist/errors/error-handler.js +18 -5
  19. package/dist/errors/error-handler.js.map +1 -1
  20. package/dist/errors/response-formatter.d.ts +3 -2
  21. package/dist/errors/response-formatter.d.ts.map +1 -1
  22. package/dist/errors/response-formatter.js +19 -2
  23. package/dist/errors/response-formatter.js.map +1 -1
  24. package/dist/server.js +85 -11
  25. package/dist/server.js.map +1 -1
  26. package/dist/tools/base-tool.d.ts +2 -2
  27. package/dist/tools/bill/bill-create.d.ts +4 -4
  28. package/dist/tools/bill/bill-delete.d.ts +6 -0
  29. package/dist/tools/bill/bill-delete.d.ts.map +1 -1
  30. package/dist/tools/bill/bill-list.d.ts +12 -12
  31. package/dist/tools/bill/bill-single.d.ts +4 -4
  32. package/dist/tools/bill/schemas.d.ts +28 -22
  33. package/dist/tools/bill/schemas.d.ts.map +1 -1
  34. package/dist/tools/bill/schemas.js +2 -0
  35. package/dist/tools/bill/schemas.js.map +1 -1
  36. package/dist/tools/bill-payment/billpayment-create.d.ts +4 -4
  37. package/dist/tools/bill-payment/billpayment-delete.d.ts +6 -0
  38. package/dist/tools/bill-payment/billpayment-delete.d.ts.map +1 -1
  39. package/dist/tools/bill-payment/billpayment-list.d.ts +12 -12
  40. package/dist/tools/bill-payment/billpayment-single.d.ts +4 -4
  41. package/dist/tools/bill-payment/billpayment-update.d.ts +4 -4
  42. package/dist/tools/bill-payment/schemas.d.ts +28 -22
  43. package/dist/tools/bill-payment/schemas.d.ts.map +1 -1
  44. package/dist/tools/bill-payment/schemas.js +2 -0
  45. package/dist/tools/bill-payment/schemas.js.map +1 -1
  46. package/dist/tools/bill-vendor/billvendor-create.d.ts +6 -6
  47. package/dist/tools/bill-vendor/billvendor-delete.d.ts +6 -0
  48. package/dist/tools/bill-vendor/billvendor-delete.d.ts.map +1 -1
  49. package/dist/tools/bill-vendor/billvendor-list.d.ts +14 -14
  50. package/dist/tools/bill-vendor/billvendor-single.d.ts +4 -4
  51. package/dist/tools/bill-vendor/billvendor-update.d.ts +6 -6
  52. package/dist/tools/bill-vendor/schemas.d.ts +34 -28
  53. package/dist/tools/bill-vendor/schemas.d.ts.map +1 -1
  54. package/dist/tools/bill-vendor/schemas.js +2 -0
  55. package/dist/tools/bill-vendor/schemas.js.map +1 -1
  56. package/dist/tools/callback/callback-create.d.ts +6 -6
  57. package/dist/tools/callback/callback-delete.d.ts +6 -0
  58. package/dist/tools/callback/callback-delete.d.ts.map +1 -1
  59. package/dist/tools/callback/callback-list.d.ts +12 -12
  60. package/dist/tools/callback/callback-resend-verification.d.ts +4 -4
  61. package/dist/tools/callback/callback-single.d.ts +4 -4
  62. package/dist/tools/callback/callback-update.d.ts +6 -6
  63. package/dist/tools/callback/schemas.d.ts +32 -26
  64. package/dist/tools/callback/schemas.d.ts.map +1 -1
  65. package/dist/tools/callback/schemas.js +2 -0
  66. package/dist/tools/callback/schemas.js.map +1 -1
  67. package/dist/tools/client/client-create.d.ts +2 -2
  68. package/dist/tools/client/client-delete.d.ts +8 -2
  69. package/dist/tools/client/client-delete.d.ts.map +1 -1
  70. package/dist/tools/client/client-list.d.ts +9 -9
  71. package/dist/tools/client/client-update.d.ts +2 -2
  72. package/dist/tools/client/schemas.d.ts +26 -20
  73. package/dist/tools/client/schemas.d.ts.map +1 -1
  74. package/dist/tools/client/schemas.js +2 -0
  75. package/dist/tools/client/schemas.js.map +1 -1
  76. package/dist/tools/credit-note/creditnote-create.d.ts +10 -10
  77. package/dist/tools/credit-note/creditnote-delete.d.ts +6 -0
  78. package/dist/tools/credit-note/creditnote-delete.d.ts.map +1 -1
  79. package/dist/tools/credit-note/creditnote-list.d.ts +14 -14
  80. package/dist/tools/credit-note/creditnote-single.d.ts +6 -6
  81. package/dist/tools/credit-note/creditnote-update.d.ts +10 -10
  82. package/dist/tools/credit-note/schemas.d.ts +42 -36
  83. package/dist/tools/credit-note/schemas.d.ts.map +1 -1
  84. package/dist/tools/credit-note/schemas.js +2 -0
  85. package/dist/tools/credit-note/schemas.js.map +1 -1
  86. package/dist/tools/expense/expense-create.d.ts +2 -2
  87. package/dist/tools/expense/expense-delete.d.ts +6 -0
  88. package/dist/tools/expense/expense-delete.d.ts.map +1 -1
  89. package/dist/tools/expense/expense-list.d.ts +8 -8
  90. package/dist/tools/expense/expense-single.d.ts +2 -2
  91. package/dist/tools/expense/expense-update.d.ts +2 -2
  92. package/dist/tools/expense/expense-update.d.ts.map +1 -1
  93. package/dist/tools/expense/expense-update.js +88 -63
  94. package/dist/tools/expense/expense-update.js.map +1 -1
  95. package/dist/tools/expense/schemas.d.ts +18 -12
  96. package/dist/tools/expense/schemas.d.ts.map +1 -1
  97. package/dist/tools/expense/schemas.js +2 -0
  98. package/dist/tools/expense/schemas.js.map +1 -1
  99. package/dist/tools/expense-category/expensecategory-list.d.ts +4 -4
  100. package/dist/tools/expense-category/schemas.d.ts +4 -4
  101. package/dist/tools/invoice/invoice-create.d.ts +10 -10
  102. package/dist/tools/invoice/invoice-delete.d.ts +6 -0
  103. package/dist/tools/invoice/invoice-delete.d.ts.map +1 -1
  104. package/dist/tools/invoice/invoice-list.d.ts +24 -24
  105. package/dist/tools/invoice/invoice-single.d.ts +10 -10
  106. package/dist/tools/invoice/invoice-update.d.ts +12 -12
  107. package/dist/tools/invoice/schemas.d.ts +56 -50
  108. package/dist/tools/invoice/schemas.d.ts.map +1 -1
  109. package/dist/tools/invoice/schemas.js +2 -0
  110. package/dist/tools/invoice/schemas.js.map +1 -1
  111. package/dist/tools/item/item-create.d.ts +8 -8
  112. package/dist/tools/item/item-list.d.ts +18 -18
  113. package/dist/tools/item/item-single.d.ts +6 -6
  114. package/dist/tools/item/item-update.d.ts +10 -10
  115. package/dist/tools/item/schemas.d.ts +38 -38
  116. package/dist/tools/journal-entry/journalentry-create.d.ts +4 -4
  117. package/dist/tools/journal-entry/schemas.d.ts +8 -8
  118. package/dist/tools/journal-entry-account/journalentryaccount-list.d.ts +14 -14
  119. package/dist/tools/journal-entry-account/schemas.d.ts +24 -24
  120. package/dist/tools/metadata.d.ts +13 -1
  121. package/dist/tools/metadata.d.ts.map +1 -1
  122. package/dist/tools/metadata.js +68 -1
  123. package/dist/tools/metadata.js.map +1 -1
  124. package/dist/tools/other-income/otherincome-create.d.ts +10 -10
  125. package/dist/tools/other-income/otherincome-delete.d.ts +6 -0
  126. package/dist/tools/other-income/otherincome-delete.d.ts.map +1 -1
  127. package/dist/tools/other-income/otherincome-list.d.ts +14 -14
  128. package/dist/tools/other-income/otherincome-single.d.ts +6 -6
  129. package/dist/tools/other-income/otherincome-update.d.ts +10 -10
  130. package/dist/tools/other-income/schemas.d.ts +40 -34
  131. package/dist/tools/other-income/schemas.d.ts.map +1 -1
  132. package/dist/tools/other-income/schemas.js +2 -0
  133. package/dist/tools/other-income/schemas.js.map +1 -1
  134. package/dist/tools/payment/payment-create.d.ts +2 -2
  135. package/dist/tools/payment/payment-delete.d.ts +6 -0
  136. package/dist/tools/payment/payment-delete.d.ts.map +1 -1
  137. package/dist/tools/payment/payment-list.d.ts +8 -8
  138. package/dist/tools/payment/payment-single.d.ts +2 -2
  139. package/dist/tools/payment/payment-update.d.ts +2 -2
  140. package/dist/tools/payment/schemas.d.ts +18 -12
  141. package/dist/tools/payment/schemas.d.ts.map +1 -1
  142. package/dist/tools/payment/schemas.js +3 -1
  143. package/dist/tools/payment/schemas.js.map +1 -1
  144. package/dist/tools/project/project-create.d.ts +8 -8
  145. package/dist/tools/project/project-delete.d.ts +8 -2
  146. package/dist/tools/project/project-delete.d.ts.map +1 -1
  147. package/dist/tools/project/project-list.d.ts +21 -21
  148. package/dist/tools/project/project-single.d.ts +6 -6
  149. package/dist/tools/project/project-update.d.ts +10 -10
  150. package/dist/tools/project/schemas.d.ts +52 -46
  151. package/dist/tools/project/schemas.d.ts.map +1 -1
  152. package/dist/tools/project/schemas.js +2 -0
  153. package/dist/tools/project/schemas.js.map +1 -1
  154. package/dist/tools/service/schemas.d.ts +11 -11
  155. package/dist/tools/service/service-create.d.ts +2 -2
  156. package/dist/tools/service/service-list.d.ts +8 -8
  157. package/dist/tools/task/schemas.d.ts +34 -28
  158. package/dist/tools/task/schemas.d.ts.map +1 -1
  159. package/dist/tools/task/schemas.js +2 -0
  160. package/dist/tools/task/schemas.js.map +1 -1
  161. package/dist/tools/task/task-create.d.ts +6 -6
  162. package/dist/tools/task/task-delete.d.ts +6 -0
  163. package/dist/tools/task/task-delete.d.ts.map +1 -1
  164. package/dist/tools/task/task-list.d.ts +18 -18
  165. package/dist/tools/task/task-single.d.ts +4 -4
  166. package/dist/tools/task/task-update.d.ts +8 -8
  167. package/dist/tools/time-entry/schemas.d.ts +42 -36
  168. package/dist/tools/time-entry/schemas.d.ts.map +1 -1
  169. package/dist/tools/time-entry/schemas.js +2 -0
  170. package/dist/tools/time-entry/schemas.js.map +1 -1
  171. package/dist/tools/time-entry/timeentry-create.d.ts +6 -6
  172. package/dist/tools/time-entry/timeentry-delete.d.ts +8 -2
  173. package/dist/tools/time-entry/timeentry-delete.d.ts.map +1 -1
  174. package/dist/tools/time-entry/timeentry-list.d.ts +17 -17
  175. package/dist/tools/time-entry/timeentry-single.d.ts +4 -4
  176. package/dist/tools/time-entry/timeentry-update.d.ts +6 -6
  177. package/dist/tools/timer/schemas.d.ts +30 -24
  178. package/dist/tools/timer/schemas.d.ts.map +1 -1
  179. package/dist/tools/timer/schemas.js +2 -0
  180. package/dist/tools/timer/schemas.js.map +1 -1
  181. package/dist/tools/timer/timer-current.d.ts +8 -8
  182. package/dist/tools/timer/timer-discard.d.ts +8 -2
  183. package/dist/tools/timer/timer-discard.d.ts.map +1 -1
  184. package/dist/tools/timer/timer-start.d.ts +6 -6
  185. package/dist/tools/timer/timer-stop.d.ts +4 -4
  186. package/dist/tools/types.d.ts +16 -0
  187. package/dist/tools/types.d.ts.map +1 -1
  188. package/dist/tools/types.js.map +1 -1
  189. package/dist/tools/user/schemas.d.ts +14 -14
  190. package/dist/tools/user/user-me.d.ts +6 -6
  191. package/dist/utils/logger.d.ts +9 -0
  192. package/dist/utils/logger.d.ts.map +1 -1
  193. package/dist/utils/logger.js +114 -20
  194. package/dist/utils/logger.js.map +1 -1
  195. package/dist/utils/sanitizer.d.ts +49 -0
  196. package/dist/utils/sanitizer.d.ts.map +1 -0
  197. package/dist/utils/sanitizer.js +163 -0
  198. package/dist/utils/sanitizer.js.map +1 -0
  199. package/package.json +5 -5
@@ -14,14 +14,14 @@ export declare const BusinessMembershipSchema: z.ZodObject<{
14
14
  role: z.ZodString;
15
15
  }, "strip", z.ZodTypeAny, {
16
16
  accountId: string;
17
+ id: number;
17
18
  name: string;
18
19
  role: string;
19
- id: number;
20
20
  }, {
21
21
  accountId: string;
22
+ id: number;
22
23
  name: string;
23
24
  role: string;
24
- id: number;
25
25
  }>;
26
26
  /**
27
27
  * Full User schema with all properties
@@ -38,14 +38,14 @@ export declare const UserSchema: z.ZodObject<{
38
38
  role: z.ZodString;
39
39
  }, "strip", z.ZodTypeAny, {
40
40
  accountId: string;
41
+ id: number;
41
42
  name: string;
42
43
  role: string;
43
- id: number;
44
44
  }, {
45
45
  accountId: string;
46
+ id: number;
46
47
  name: string;
47
48
  role: string;
48
- id: number;
49
49
  }>, "many">;
50
50
  phoneNumbers: z.ZodOptional<z.ZodArray<z.ZodObject<{
51
51
  title: z.ZodOptional<z.ZodString>;
@@ -85,15 +85,15 @@ export declare const UserSchema: z.ZodObject<{
85
85
  me: string;
86
86
  }>>;
87
87
  }, "strip", z.ZodTypeAny, {
88
- email: string;
89
88
  id: number;
89
+ email: string;
90
90
  firstName: string;
91
91
  lastName: string;
92
92
  businessMemberships: {
93
93
  accountId: string;
94
+ id: number;
94
95
  name: string;
95
96
  role: string;
96
- id: number;
97
97
  }[];
98
98
  phoneNumbers?: {
99
99
  number: string;
@@ -111,15 +111,15 @@ export declare const UserSchema: z.ZodObject<{
111
111
  me: string;
112
112
  } | undefined;
113
113
  }, {
114
- email: string;
115
114
  id: number;
115
+ email: string;
116
116
  firstName: string;
117
117
  lastName: string;
118
118
  businessMemberships: {
119
119
  accountId: string;
120
+ id: number;
120
121
  name: string;
121
122
  role: string;
122
- id: number;
123
123
  }[];
124
124
  phoneNumbers?: {
125
125
  number: string;
@@ -156,14 +156,14 @@ export declare const UserMeOutputSchema: z.ZodObject<{
156
156
  role: z.ZodString;
157
157
  }, "strip", z.ZodTypeAny, {
158
158
  accountId: string;
159
+ id: number;
159
160
  name: string;
160
161
  role: string;
161
- id: number;
162
162
  }, {
163
163
  accountId: string;
164
+ id: number;
164
165
  name: string;
165
166
  role: string;
166
- id: number;
167
167
  }>, "many">;
168
168
  phoneNumbers: z.ZodOptional<z.ZodArray<z.ZodObject<{
169
169
  title: z.ZodOptional<z.ZodString>;
@@ -203,15 +203,15 @@ export declare const UserMeOutputSchema: z.ZodObject<{
203
203
  me: string;
204
204
  }>>;
205
205
  }, "strip", z.ZodTypeAny, {
206
- email: string;
207
206
  id: number;
207
+ email: string;
208
208
  firstName: string;
209
209
  lastName: string;
210
210
  businessMemberships: {
211
211
  accountId: string;
212
+ id: number;
212
213
  name: string;
213
214
  role: string;
214
- id: number;
215
215
  }[];
216
216
  phoneNumbers?: {
217
217
  number: string;
@@ -229,15 +229,15 @@ export declare const UserMeOutputSchema: z.ZodObject<{
229
229
  me: string;
230
230
  } | undefined;
231
231
  }, {
232
- email: string;
233
232
  id: number;
233
+ email: string;
234
234
  firstName: string;
235
235
  lastName: string;
236
236
  businessMemberships: {
237
237
  accountId: string;
238
+ id: number;
238
239
  name: string;
239
240
  role: string;
240
- id: number;
241
241
  }[];
242
242
  phoneNumbers?: {
243
243
  number: string;
@@ -25,14 +25,14 @@ export declare const userMeTool: {
25
25
  role: z.ZodString;
26
26
  }, "strip", z.ZodTypeAny, {
27
27
  accountId: string;
28
+ id: number;
28
29
  name: string;
29
30
  role: string;
30
- id: number;
31
31
  }, {
32
32
  accountId: string;
33
+ id: number;
33
34
  name: string;
34
35
  role: string;
35
- id: number;
36
36
  }>, "many">;
37
37
  phoneNumbers: z.ZodOptional<z.ZodArray<z.ZodObject<{
38
38
  title: z.ZodOptional<z.ZodString>;
@@ -72,15 +72,15 @@ export declare const userMeTool: {
72
72
  me: string;
73
73
  }>>;
74
74
  }, "strip", z.ZodTypeAny, {
75
- email: string;
76
75
  id: number;
76
+ email: string;
77
77
  firstName: string;
78
78
  lastName: string;
79
79
  businessMemberships: {
80
80
  accountId: string;
81
+ id: number;
81
82
  name: string;
82
83
  role: string;
83
- id: number;
84
84
  }[];
85
85
  phoneNumbers?: {
86
86
  number: string;
@@ -98,15 +98,15 @@ export declare const userMeTool: {
98
98
  me: string;
99
99
  } | undefined;
100
100
  }, {
101
- email: string;
102
101
  id: number;
102
+ email: string;
103
103
  firstName: string;
104
104
  lastName: string;
105
105
  businessMemberships: {
106
106
  accountId: string;
107
+ id: number;
107
108
  name: string;
108
109
  role: string;
109
- id: number;
110
110
  }[];
111
111
  phoneNumbers?: {
112
112
  number: string;
@@ -7,6 +7,7 @@ import type { LogLevel } from '../types/index.js';
7
7
  declare class Logger {
8
8
  private currentLevel;
9
9
  private requestId;
10
+ private static readonly MAX_DEPTH;
10
11
  constructor(level?: LogLevel);
11
12
  /**
12
13
  * Set the current log level
@@ -24,6 +25,14 @@ declare class Logger {
24
25
  * Check if a log level should be output
25
26
  */
26
27
  private shouldLog;
28
+ /**
29
+ * Check if a key name indicates sensitive data
30
+ */
31
+ private isSensitiveKey;
32
+ /**
33
+ * Heuristically detect if a string value looks like a secret
34
+ */
35
+ private looksLikeSecret;
27
36
  /**
28
37
  * Sanitize data to prevent logging sensitive information
29
38
  */
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AASlD,cAAM,MAAM;IACV,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,SAAS,CAAuB;gBAE5B,KAAK,GAAE,QAAiB;IAIpC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAqChB;;OAEG;IACH,OAAO,CAAC,KAAK;IAiBb;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAezF;AAGD,eAAO,MAAM,MAAM,QAAe,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAgFlD,cAAM,MAAM;IACV,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAM;gBAE3B,KAAK,GAAE,QAAiB;IAIpC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACH,OAAO,CAAC,QAAQ;IA8BhB;;OAEG;IACH,OAAO,CAAC,KAAK;IAiBb;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAgBzF;AAGD,eAAO,MAAM,MAAM,QAAe,CAAC"}
@@ -3,15 +3,80 @@
3
3
  *
4
4
  * IMPORTANT: All logs go to stderr (stdout is reserved for MCP protocol)
5
5
  */
6
+ import { isProduction } from '../config/environment.js';
6
7
  const LOG_LEVELS = {
7
8
  debug: 0,
8
9
  info: 1,
9
10
  warn: 2,
10
11
  error: 3,
11
12
  };
13
+ /**
14
+ * Regex patterns for detecting sensitive keys
15
+ * These patterns catch various naming conventions (camelCase, snake_case, etc.)
16
+ */
17
+ const SENSITIVE_KEY_PATTERNS = [
18
+ // Tokens and authentication
19
+ /token/i,
20
+ /bearer/i,
21
+ /jwt/i,
22
+ /oauth/i,
23
+ /session/i,
24
+ /auth/i,
25
+ // Secrets and passwords
26
+ /secret/i,
27
+ /password/i,
28
+ /passwd/i,
29
+ /pwd/i,
30
+ /credential/i,
31
+ // API keys
32
+ /api[-_]?key/i,
33
+ /apikey/i,
34
+ /key/i,
35
+ // Cryptographic
36
+ /private[-_]?key/i,
37
+ /signing/i,
38
+ /cipher/i,
39
+ /encrypt/i,
40
+ /salt/i,
41
+ /hash/i,
42
+ /\biv\b/i, // initialization vector
43
+ // Personal identifiable information
44
+ /ssn/i,
45
+ /social[-_]?security/i,
46
+ /credit[-_]?card/i,
47
+ /card[-_]?number/i,
48
+ /cvv/i,
49
+ /\bpin\b/i,
50
+ // Headers
51
+ /x-api/i,
52
+ /x-auth/i,
53
+ /x-secret/i,
54
+ ];
55
+ /**
56
+ * Exact key matches (case-insensitive, normalized)
57
+ * These are checked after removing hyphens and underscores
58
+ */
59
+ const SENSITIVE_EXACT_KEYS = new Set([
60
+ 'password',
61
+ 'token',
62
+ 'secret',
63
+ 'key',
64
+ 'accesstoken',
65
+ 'refreshtoken',
66
+ 'apikey',
67
+ 'clientsecret',
68
+ 'privatekey',
69
+ 'authorization',
70
+ 'bearer',
71
+ 'jwt',
72
+ 'sessionid',
73
+ 'cookie',
74
+ 'credentials',
75
+ ]);
12
76
  class Logger {
13
77
  currentLevel;
14
78
  requestId = null;
79
+ static MAX_DEPTH = 10;
15
80
  constructor(level = 'info') {
16
81
  this.currentLevel = level;
17
82
  }
@@ -39,38 +104,66 @@ class Logger {
39
104
  shouldLog(level) {
40
105
  return LOG_LEVELS[level] >= LOG_LEVELS[this.currentLevel];
41
106
  }
107
+ /**
108
+ * Check if a key name indicates sensitive data
109
+ */
110
+ isSensitiveKey(key) {
111
+ // Normalize key: lowercase and remove separators
112
+ const normalizedKey = key.toLowerCase().replace(/[-_]/g, '');
113
+ // Check exact matches
114
+ if (SENSITIVE_EXACT_KEYS.has(normalizedKey)) {
115
+ return true;
116
+ }
117
+ // Check patterns
118
+ return SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(key));
119
+ }
120
+ /**
121
+ * Heuristically detect if a string value looks like a secret
122
+ */
123
+ looksLikeSecret(value) {
124
+ // Skip short values
125
+ if (value.length < 20) {
126
+ return false;
127
+ }
128
+ // JWT pattern: eyJ...
129
+ if (/^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value)) {
130
+ return true;
131
+ }
132
+ // Long hex strings (32+ chars) - likely keys/tokens
133
+ if (/^[a-f0-9]{32,}$/i.test(value)) {
134
+ return true;
135
+ }
136
+ // Base64-ish strings that are long (50+ chars) - likely tokens
137
+ if (/^[A-Za-z0-9+/=_-]{50,}$/.test(value)) {
138
+ return true;
139
+ }
140
+ return false;
141
+ }
42
142
  /**
43
143
  * Sanitize data to prevent logging sensitive information
44
144
  */
45
- sanitize(data) {
145
+ sanitize(data, depth = 0) {
146
+ // Prevent infinite recursion
147
+ if (depth > Logger.MAX_DEPTH) {
148
+ return '[DEPTH_LIMIT]';
149
+ }
46
150
  if (typeof data !== 'object' || data === null) {
47
151
  return data;
48
152
  }
49
153
  if (Array.isArray(data)) {
50
- return data.map((item) => this.sanitize(item));
154
+ return data.map((item) => this.sanitize(item, depth + 1));
51
155
  }
52
156
  const sanitized = {};
53
- const sensitiveKeys = [
54
- 'token',
55
- 'accessToken',
56
- 'refreshToken',
57
- 'access_token',
58
- 'refresh_token',
59
- 'secret',
60
- 'password',
61
- 'clientSecret',
62
- 'client_secret',
63
- 'authorization',
64
- 'apiKey',
65
- 'api_key',
66
- ];
67
157
  for (const [key, value] of Object.entries(data)) {
68
- const lowerKey = key.toLowerCase();
69
- if (sensitiveKeys.some((sensitive) => lowerKey.includes(sensitive))) {
158
+ if (this.isSensitiveKey(key)) {
70
159
  sanitized[key] = '[REDACTED]';
71
160
  }
161
+ else if (typeof value === 'string' && this.looksLikeSecret(value)) {
162
+ // Detect secret-like values even if key doesn't match
163
+ sanitized[key] = '[REDACTED_VALUE]';
164
+ }
72
165
  else {
73
- sanitized[key] = this.sanitize(value);
166
+ sanitized[key] = this.sanitize(value, depth + 1);
74
167
  }
75
168
  }
76
169
  return sanitized;
@@ -119,7 +212,8 @@ class Logger {
119
212
  errorContext.error = {
120
213
  name: error.name,
121
214
  message: error.message,
122
- stack: error.stack,
215
+ // Only include stack traces in non-production environments
216
+ ...(isProduction() ? {} : { stack: error.stack }),
123
217
  };
124
218
  }
125
219
  else if (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,UAAU,GAA6B;IAC3C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,MAAM;IACF,YAAY,CAAW;IACvB,SAAS,GAAkB,IAAI,CAAC;IAExC,YAAY,QAAkB,MAAM;QAClC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAe;QACtB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,EAAU;QACrB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,KAAe;QAC/B,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,IAAa;QAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,SAAS,GAA4B,EAAE,CAAC;QAC9C,MAAM,aAAa,GAAG;YACpB,OAAO;YACP,aAAa;YACb,cAAc;YACd,cAAc;YACd,eAAe;YACf,QAAQ;YACR,UAAU;YACV,cAAc;YACd,eAAe;YACf,eAAe;YACf,QAAQ;YACR,SAAS;SACV,CAAC;QAEF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACpE,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,KAAe,EAAE,OAAe,EAAE,OAAiC;QAC/E,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG;YACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK;YACL,OAAO;YACP,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YACpD,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;SACpD,CAAC;QAEF,0DAA0D;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,OAAiC;QACtD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,KAAuB,EAAE,OAAiC;QAC/E,MAAM,YAAY,GAA4B,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5E,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,YAAY,CAAC,KAAK,GAAG;gBACnB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,EAAE,CAAC;YACjB,YAAY,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Output sanitization utilities for MCP responses
3
+ *
4
+ * Prevents prompt injection attacks by sanitizing user-controlled data
5
+ * before returning it to Claude in MCP tool responses.
6
+ */
7
+ export interface SanitizeOptions {
8
+ /** Maximum string length before truncation (default: 10000) */
9
+ maxStringLength?: number;
10
+ /** Strip control characters (default: true) */
11
+ stripControlChars?: boolean;
12
+ /** Maximum recursion depth (default: 50) */
13
+ maxDepth?: number;
14
+ /** Flag suspicious content in metadata (default: true) */
15
+ flagSuspiciousContent?: boolean;
16
+ }
17
+ export interface SanitizeResult {
18
+ data: unknown;
19
+ warnings: string[];
20
+ }
21
+ /**
22
+ * Check if a string contains suspicious content that might be prompt injection
23
+ */
24
+ export declare function containsSuspiciousContent(str: string): boolean;
25
+ /**
26
+ * Sanitize data for MCP response with warnings
27
+ *
28
+ * Returns both the sanitized data and any warnings about suspicious content.
29
+ * Warnings are for logging purposes - the data is still returned.
30
+ */
31
+ export declare function sanitizeWithWarnings(data: unknown, options?: SanitizeOptions): SanitizeResult;
32
+ /**
33
+ * Sanitize data for MCP response
34
+ *
35
+ * This is the main function to use when preparing tool responses.
36
+ * It sanitizes user-controlled data to prevent prompt injection.
37
+ *
38
+ * @param data - The data to sanitize (typically from FreshBooks API)
39
+ * @param options - Optional sanitization options
40
+ * @returns Sanitized data safe for MCP response
41
+ */
42
+ export declare function sanitizeForMcpResponse(data: unknown, options?: SanitizeOptions): unknown;
43
+ /**
44
+ * Create a sanitized JSON string for MCP response content
45
+ *
46
+ * Convenience function that sanitizes and stringifies in one call.
47
+ */
48
+ export declare function toSanitizedJson(data: unknown, options?: SanitizeOptions): string;
49
+ //# sourceMappingURL=sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAsDD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAM9D;AA0FD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAahB;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAExF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAGhF"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Output sanitization utilities for MCP responses
3
+ *
4
+ * Prevents prompt injection attacks by sanitizing user-controlled data
5
+ * before returning it to Claude in MCP tool responses.
6
+ */
7
+ const DEFAULT_OPTIONS = {
8
+ maxStringLength: 10000,
9
+ stripControlChars: true,
10
+ maxDepth: 50,
11
+ flagSuspiciousContent: true,
12
+ };
13
+ /**
14
+ * Patterns that may indicate prompt injection attempts
15
+ * These are flagged but not blocked to avoid false positives
16
+ */
17
+ const SUSPICIOUS_PATTERNS = [
18
+ // Direct instruction overrides
19
+ /ignore\s+(all\s+)?previous\s+instructions?/i,
20
+ /ignore\s+(all\s+)?prior\s+instructions?/i,
21
+ /disregard\s+(all\s+)?previous/i,
22
+ /forget\s+(all\s+)?previous/i,
23
+ // Role manipulation
24
+ /you\s+are\s+now\s+a/i,
25
+ /pretend\s+you\s+are/i,
26
+ /act\s+as\s+(if\s+you\s+are\s+)?a/i,
27
+ /from\s+now\s+on,?\s+you/i,
28
+ // System prompt references
29
+ /system\s*prompt/i,
30
+ /\[system\]/i,
31
+ /\[INST\]/i,
32
+ /<\|system\|>/i,
33
+ // Jailbreak attempts
34
+ /do\s+anything\s+now/i,
35
+ /DAN\s+mode/i,
36
+ /developer\s+mode/i,
37
+ /jailbreak/i,
38
+ // Instruction injection markers
39
+ /\n\n---\n\nNew instructions:/i,
40
+ /END\s+OF\s+DOCUMENT/i,
41
+ /IMPORTANT:\s*As\s+an?\s+AI/i,
42
+ // Tool manipulation
43
+ /call\s+(the\s+)?tool/i,
44
+ /execute\s+(the\s+)?function/i,
45
+ /invoke\s+.*_delete/i,
46
+ ];
47
+ /**
48
+ * Control characters to strip (excluding common whitespace)
49
+ */
50
+ const CONTROL_CHAR_REGEX = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
51
+ /**
52
+ * Check if a string contains suspicious content that might be prompt injection
53
+ */
54
+ export function containsSuspiciousContent(str) {
55
+ if (typeof str !== 'string') {
56
+ return false;
57
+ }
58
+ return SUSPICIOUS_PATTERNS.some((pattern) => pattern.test(str));
59
+ }
60
+ /**
61
+ * Sanitize a string value
62
+ */
63
+ function sanitizeString(str, options) {
64
+ let result = str;
65
+ // Strip control characters
66
+ if (options.stripControlChars) {
67
+ result = result.replace(CONTROL_CHAR_REGEX, '');
68
+ }
69
+ // Truncate if too long
70
+ if (result.length > options.maxStringLength) {
71
+ result = result.substring(0, options.maxStringLength) + '... [TRUNCATED]';
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * Recursively sanitize data for MCP response
77
+ */
78
+ function sanitizeValue(data, options, warnings, path, depth) {
79
+ // Check depth limit
80
+ if (depth > options.maxDepth) {
81
+ warnings.push(`Max depth exceeded at path: ${path}`);
82
+ return '[MAX_DEPTH_EXCEEDED]';
83
+ }
84
+ // Handle null/undefined
85
+ if (data === null || data === undefined) {
86
+ return data;
87
+ }
88
+ // Handle primitives
89
+ if (typeof data === 'string') {
90
+ const sanitized = sanitizeString(data, options);
91
+ // Check for suspicious content
92
+ if (options.flagSuspiciousContent && containsSuspiciousContent(data)) {
93
+ warnings.push(`Suspicious content detected at path: ${path}`);
94
+ }
95
+ return sanitized;
96
+ }
97
+ if (typeof data === 'number' || typeof data === 'boolean') {
98
+ return data;
99
+ }
100
+ // Handle arrays
101
+ if (Array.isArray(data)) {
102
+ return data.map((item, index) => sanitizeValue(item, options, warnings, `${path}[${index}]`, depth + 1));
103
+ }
104
+ // Handle objects
105
+ if (typeof data === 'object') {
106
+ // Handle Date objects
107
+ if (data instanceof Date) {
108
+ return data.toISOString();
109
+ }
110
+ // Handle regular objects
111
+ const sanitized = {};
112
+ for (const [key, value] of Object.entries(data)) {
113
+ sanitized[key] = sanitizeValue(value, options, warnings, `${path}.${key}`, depth + 1);
114
+ }
115
+ return sanitized;
116
+ }
117
+ // Handle functions (shouldn't appear in JSON, but be safe)
118
+ if (typeof data === 'function') {
119
+ return '[FUNCTION]';
120
+ }
121
+ return data;
122
+ }
123
+ /**
124
+ * Sanitize data for MCP response with warnings
125
+ *
126
+ * Returns both the sanitized data and any warnings about suspicious content.
127
+ * Warnings are for logging purposes - the data is still returned.
128
+ */
129
+ export function sanitizeWithWarnings(data, options) {
130
+ const mergedOptions = {
131
+ ...DEFAULT_OPTIONS,
132
+ ...options,
133
+ };
134
+ const warnings = [];
135
+ const sanitizedData = sanitizeValue(data, mergedOptions, warnings, '$', 0);
136
+ return {
137
+ data: sanitizedData,
138
+ warnings,
139
+ };
140
+ }
141
+ /**
142
+ * Sanitize data for MCP response
143
+ *
144
+ * This is the main function to use when preparing tool responses.
145
+ * It sanitizes user-controlled data to prevent prompt injection.
146
+ *
147
+ * @param data - The data to sanitize (typically from FreshBooks API)
148
+ * @param options - Optional sanitization options
149
+ * @returns Sanitized data safe for MCP response
150
+ */
151
+ export function sanitizeForMcpResponse(data, options) {
152
+ return sanitizeWithWarnings(data, options).data;
153
+ }
154
+ /**
155
+ * Create a sanitized JSON string for MCP response content
156
+ *
157
+ * Convenience function that sanitizes and stringifies in one call.
158
+ */
159
+ export function toSanitizedJson(data, options) {
160
+ const sanitized = sanitizeForMcpResponse(data, options);
161
+ return JSON.stringify(sanitized, null, 2);
162
+ }
163
+ //# sourceMappingURL=sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../../src/utils/sanitizer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodsamsoftware/freshbooks-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "FreshBooks MCP server providing 1:1 parity with the FreshBooks Node.js SDK",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",
@@ -38,7 +38,7 @@
38
38
  }
39
39
  },
40
40
  "bin": {
41
- "freshbooks-mcp": "./dist/server.js"
41
+ "freshbooks-mcp": "dist/server.js"
42
42
  },
43
43
  "files": [
44
44
  "dist",
@@ -65,12 +65,12 @@
65
65
  "license": "MIT",
66
66
  "repository": {
67
67
  "type": "git",
68
- "url": "git+https://github.com/mcsei/freshbooks-mcp.git"
68
+ "url": "git+https://github.com/Good-Samaritan-Software-LLC/freshbooks-mcp.git"
69
69
  },
70
70
  "bugs": {
71
- "url": "https://github.com/mcsei/freshbooks-mcp/issues"
71
+ "url": "https://github.com/Good-Samaritan-Software-LLC/freshbooks-mcp/issues"
72
72
  },
73
- "homepage": "https://github.com/mcsei/freshbooks-mcp#readme",
73
+ "homepage": "https://freshbooks.goodsamsoftware.com/",
74
74
  "dependencies": {
75
75
  "@freshbooks/api": "^4.1.0",
76
76
  "@modelcontextprotocol/sdk": "^1.0.0",