accessflow-mcp-server 1.0.15 → 1.1.0-beta.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.
Files changed (144) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +66 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/services/apiSchemas.d.ts +200 -0
  6. package/dist/services/apiSchemas.d.ts.map +1 -0
  7. package/dist/services/apiSchemas.js +95 -0
  8. package/dist/services/apiSchemas.js.map +1 -0
  9. package/dist/services/apiService.d.ts +37 -0
  10. package/dist/services/apiService.d.ts.map +1 -0
  11. package/dist/services/apiService.js +198 -0
  12. package/dist/services/apiService.js.map +1 -0
  13. package/dist/services/loggerService.d.ts +3 -0
  14. package/dist/services/loggerService.d.ts.map +1 -0
  15. package/dist/services/loggerService.js +38 -0
  16. package/dist/services/loggerService.js.map +1 -0
  17. package/dist/services/rulesService.d.ts +10 -0
  18. package/dist/services/rulesService.d.ts.map +1 -0
  19. package/dist/services/rulesService.js +70 -0
  20. package/dist/services/rulesService.js.map +1 -0
  21. package/dist/tools/getIssueRemediation.d.ts +16 -0
  22. package/dist/tools/getIssueRemediation.d.ts.map +1 -0
  23. package/dist/tools/getIssueRemediation.js +77 -0
  24. package/dist/tools/getIssueRemediation.js.map +1 -0
  25. package/dist/tools/getMostUrgentIssues.d.ts +7 -0
  26. package/dist/tools/getMostUrgentIssues.d.ts.map +1 -0
  27. package/dist/tools/getMostUrgentIssues.js +94 -0
  28. package/dist/tools/getMostUrgentIssues.js.map +1 -0
  29. package/dist/tools/index.d.ts +4 -0
  30. package/dist/tools/index.d.ts.map +1 -0
  31. package/dist/tools/index.js +21 -0
  32. package/dist/tools/index.js.map +1 -0
  33. package/dist/tools/resolveIssue.d.ts +16 -0
  34. package/dist/tools/resolveIssue.d.ts.map +1 -0
  35. package/dist/tools/resolveIssue.js +70 -0
  36. package/dist/tools/resolveIssue.js.map +1 -0
  37. package/dist/tools/toolRegistry.d.ts +19 -0
  38. package/dist/tools/toolRegistry.d.ts.map +1 -0
  39. package/dist/tools/toolRegistry.js +9 -0
  40. package/dist/tools/toolRegistry.js.map +1 -0
  41. package/dist/types/issues.d.ts +32 -0
  42. package/dist/types/issues.d.ts.map +1 -0
  43. package/dist/types/issues.js +6 -0
  44. package/dist/types/issues.js.map +1 -0
  45. package/dist/types/remediation.d.ts +24 -0
  46. package/dist/types/remediation.d.ts.map +1 -0
  47. package/dist/types/remediation.js +6 -0
  48. package/dist/types/remediation.js.map +1 -0
  49. package/dist/utils/domains.d.ts +2 -0
  50. package/dist/utils/domains.d.ts.map +1 -0
  51. package/dist/utils/domains.js +14 -0
  52. package/dist/utils/domains.js.map +1 -0
  53. package/dist/utils/issues.d.ts +16 -0
  54. package/dist/utils/issues.d.ts.map +1 -0
  55. package/dist/utils/issues.js +24 -0
  56. package/dist/utils/issues.js.map +1 -0
  57. package/dist/utils/middleware.d.ts +14 -0
  58. package/dist/utils/middleware.d.ts.map +1 -0
  59. package/dist/utils/middleware.js +37 -0
  60. package/dist/utils/middleware.js.map +1 -0
  61. package/dist/utils/remediation.d.ts +27 -0
  62. package/dist/utils/remediation.d.ts.map +1 -0
  63. package/dist/utils/remediation.js +139 -0
  64. package/dist/utils/remediation.js.map +1 -0
  65. package/dist/utils.d.ts +2 -0
  66. package/dist/utils.d.ts.map +1 -0
  67. package/dist/utils.js +14 -0
  68. package/dist/utils.js.map +1 -0
  69. package/package.json +48 -14
  70. package/TOOL_REFERENCE.md +0 -126
  71. package/assets/MCP_banner.png +0 -0
  72. package/bin/flow-mcp +0 -4
  73. package/build/index.d.ts +0 -12
  74. package/build/index.d.ts.map +0 -1
  75. package/build/index.js +0 -95
  76. package/build/index.js.map +0 -1
  77. package/build/prompts/formatUrgentIssues.d.ts +0 -4
  78. package/build/prompts/formatUrgentIssues.d.ts.map +0 -1
  79. package/build/prompts/formatUrgentIssues.js +0 -78
  80. package/build/prompts/formatUrgentIssues.js.map +0 -1
  81. package/build/prompts/index.d.ts +0 -4
  82. package/build/prompts/index.d.ts.map +0 -1
  83. package/build/prompts/index.js +0 -12
  84. package/build/prompts/index.js.map +0 -1
  85. package/build/prompts/types.d.ts +0 -22
  86. package/build/prompts/types.d.ts.map +0 -1
  87. package/build/prompts/types.js +0 -2
  88. package/build/prompts/types.js.map +0 -1
  89. package/build/rules.json +0 -4591
  90. package/build/services/accessflow.d.ts +0 -6
  91. package/build/services/accessflow.d.ts.map +0 -1
  92. package/build/services/accessflow.js +0 -8
  93. package/build/services/accessflow.js.map +0 -1
  94. package/build/tools/getIssueRemediation.d.ts +0 -4
  95. package/build/tools/getIssueRemediation.d.ts.map +0 -1
  96. package/build/tools/getIssueRemediation.js +0 -165
  97. package/build/tools/getIssueRemediation.js.map +0 -1
  98. package/build/tools/getMostUrgentIssues.d.ts +0 -4
  99. package/build/tools/getMostUrgentIssues.d.ts.map +0 -1
  100. package/build/tools/getMostUrgentIssues.js +0 -106
  101. package/build/tools/getMostUrgentIssues.js.map +0 -1
  102. package/build/tools/index.d.ts +0 -9
  103. package/build/tools/index.d.ts.map +0 -1
  104. package/build/tools/index.js +0 -19
  105. package/build/tools/index.js.map +0 -1
  106. package/build/tools/types.d.ts +0 -19
  107. package/build/tools/types.d.ts.map +0 -1
  108. package/build/tools/types.js +0 -2
  109. package/build/tools/types.js.map +0 -1
  110. package/build/utils/config.d.ts +0 -8
  111. package/build/utils/config.d.ts.map +0 -1
  112. package/build/utils/config.js +0 -26
  113. package/build/utils/config.js.map +0 -1
  114. package/build/utils/database.d.ts +0 -13
  115. package/build/utils/database.d.ts.map +0 -1
  116. package/build/utils/database.js +0 -64
  117. package/build/utils/database.js.map +0 -1
  118. package/build/utils/domain.d.ts +0 -2
  119. package/build/utils/domain.d.ts.map +0 -1
  120. package/build/utils/domain.js +0 -11
  121. package/build/utils/domain.js.map +0 -1
  122. package/build/utils/logger.d.ts +0 -18
  123. package/build/utils/logger.d.ts.map +0 -1
  124. package/build/utils/logger.js +0 -51
  125. package/build/utils/logger.js.map +0 -1
  126. package/build/utils/responses.d.ts +0 -19
  127. package/build/utils/responses.d.ts.map +0 -1
  128. package/build/utils/responses.js +0 -41
  129. package/build/utils/responses.js.map +0 -1
  130. package/build/utils/validation.d.ts +0 -7
  131. package/build/utils/validation.d.ts.map +0 -1
  132. package/build/utils/validation.js +0 -47
  133. package/build/utils/validation.js.map +0 -1
  134. package/mcp-config.json +0 -11
  135. package/src/index.ts +0 -125
  136. package/src/services/accessflow.ts +0 -9
  137. package/src/tools/getIssueRemediation.ts +0 -218
  138. package/src/tools/getMostUrgentIssues.ts +0 -144
  139. package/src/tools/index.ts +0 -33
  140. package/src/tools/types.ts +0 -20
  141. package/src/utils/domain.ts +0 -13
  142. package/test.mjs +0 -63
  143. package/tsconfig.json +0 -20
  144. /package/{src → dist/data}/rules.json +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AAED,MAAM,OAAO,MAAM;IACT,KAAK,CAAW;IAExB,YAAY,QAAgB,MAAM;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAEO,aAAa,CAAC,KAAa;QACjC,QAAQ,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,KAAK,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC;YACpC,KAAK,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC;YAClC,KAAK,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC;YAClC,KAAK,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC;YACpC,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,KAAe;QAC/B,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;IAC7B,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,OAAe,EAAE,IAAU;QAC9D,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,SAAS,KAAK,KAAK,KAAK,OAAO,GAAG,OAAO,EAAE,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAU;QAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAU;QAC9B,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAU;QAC9B,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAU;QAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;CACF"}
@@ -1,19 +0,0 @@
1
- export interface McpResponse {
2
- content: Array<{
3
- type: "text";
4
- text: string;
5
- }>;
6
- }
7
- export interface ErrorResponse {
8
- error: string;
9
- code: string;
10
- details?: any;
11
- }
12
- export declare class ResponseFormatter {
13
- static success(text: string): McpResponse;
14
- static error(message: string, code?: string, details?: any): McpResponse;
15
- static notFound(resource: string, identifier: string): McpResponse;
16
- static validationError(message: string, field?: string): McpResponse;
17
- static websiteMismatch(issueId: string, expectedWebsite: string, actualWebsite: string): McpResponse;
18
- }
19
- //# sourceMappingURL=responses.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/utils/responses.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,qBAAa,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAWzC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAyB,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,WAAW;IAiB1F,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW;IAQlE,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW;IAQpE,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,WAAW;CAWrG"}
@@ -1,41 +0,0 @@
1
- export class ResponseFormatter {
2
- static success(text) {
3
- return {
4
- content: [
5
- {
6
- type: "text",
7
- text
8
- }
9
- ]
10
- };
11
- }
12
- static error(message, code = "INTERNAL_ERROR", details) {
13
- const errorResponse = {
14
- error: message,
15
- code,
16
- ...(details && { details })
17
- };
18
- return {
19
- content: [
20
- {
21
- type: "text",
22
- text: `**Error (${code})**\n\n${message}${details ? `\n\n**Details:**\n\`\`\`json\n${JSON.stringify(details, null, 2)}\n\`\`\`` : ""}`
23
- }
24
- ]
25
- };
26
- }
27
- static notFound(resource, identifier) {
28
- return this.error(`${resource} not found: ${identifier}`, "NOT_FOUND", { resource, identifier });
29
- }
30
- static validationError(message, field) {
31
- return this.error(`Validation error: ${message}`, "VALIDATION_ERROR", { field });
32
- }
33
- static websiteMismatch(issueId, expectedWebsite, actualWebsite) {
34
- return this.error(`Issue "${issueId}" belongs to website "${actualWebsite}" but expected website "${expectedWebsite}"`, "WEBSITE_MISMATCH", {
35
- issueId,
36
- expectedWebsite,
37
- actualWebsite
38
- });
39
- }
40
- }
41
- //# sourceMappingURL=responses.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/utils/responses.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CAAC,IAAY;QACzB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,OAAe,gBAAgB,EAAE,OAAa;QAC1E,MAAM,aAAa,GAAkB;YACnC,KAAK,EAAE,OAAO;YACd,IAAI;YACJ,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;SAC5B,CAAC;QAEF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,YAAY,IAAI,UAAU,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,iCAAiC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE;iBACvI;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,QAAgB,EAAE,UAAkB;QAClD,OAAO,IAAI,CAAC,KAAK,CACf,GAAG,QAAQ,eAAe,UAAU,EAAE,EACtC,WAAW,EACX,EAAE,QAAQ,EAAE,UAAU,EAAE,CACzB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,OAAe,EAAE,KAAc;QACpD,OAAO,IAAI,CAAC,KAAK,CACf,qBAAqB,OAAO,EAAE,EAC9B,kBAAkB,EAClB,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,OAAe,EAAE,eAAuB,EAAE,aAAqB;QACpF,OAAO,IAAI,CAAC,KAAK,CACf,UAAU,OAAO,yBAAyB,aAAa,2BAA2B,eAAe,GAAG,EACpG,kBAAkB,EAClB;YACE,OAAO;YACP,eAAe;YACf,aAAa;SACd,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -1,7 +0,0 @@
1
- export declare class ValidationError extends Error {
2
- constructor(message: string);
3
- }
4
- export declare function validateIssueDisplayName(displayName: string): void;
5
- export declare function validateObjectId(id: string): void;
6
- export declare function sanitizeMongoQuery(query: any): any;
7
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAalE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CAwBlD"}
@@ -1,47 +0,0 @@
1
- import { ObjectId } from "mongodb";
2
- import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
3
- export class ValidationError extends Error {
4
- constructor(message) {
5
- super(message);
6
- this.name = "ValidationError";
7
- }
8
- }
9
- export function validateIssueDisplayName(displayName) {
10
- if (!displayName || typeof displayName !== "string") {
11
- throw new McpError(ErrorCode.InvalidParams, "Issue display name must be a non-empty string");
12
- }
13
- // Sanitize input - remove potentially dangerous characters
14
- if (!/^[a-zA-Z0-9\-_]+$/.test(displayName)) {
15
- throw new McpError(ErrorCode.InvalidParams, "Issue display name contains invalid characters");
16
- }
17
- if (displayName.length > 100) {
18
- throw new McpError(ErrorCode.InvalidParams, "Issue display name too long (max 100 characters)");
19
- }
20
- }
21
- export function validateObjectId(id) {
22
- if (!ObjectId.isValid(id)) {
23
- throw new McpError(ErrorCode.InvalidParams, `Invalid ObjectId format: ${id}`);
24
- }
25
- }
26
- export function sanitizeMongoQuery(query) {
27
- // Remove any potential MongoDB injection operators
28
- const sanitized = JSON.parse(JSON.stringify(query));
29
- function removeOperators(obj) {
30
- if (Array.isArray(obj)) {
31
- return obj.map(removeOperators);
32
- }
33
- if (obj && typeof obj === "object") {
34
- const cleaned = {};
35
- for (const [key, value] of Object.entries(obj)) {
36
- // Remove keys that start with $ (MongoDB operators)
37
- if (!key.startsWith("$")) {
38
- cleaned[key] = removeOperators(value);
39
- }
40
- }
41
- return cleaned;
42
- }
43
- return obj;
44
- }
45
- return removeOperators(sanitized);
46
- }
47
- //# sourceMappingURL=validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,+CAA+C,CAAC,CAAC;IAC/F,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,gDAAgD,CAAC,CAAC;IAChG,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,kDAAkD,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAU;IAC3C,mDAAmD;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpD,SAAS,eAAe,CAAC,GAAQ;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,OAAO,GAAQ,EAAE,CAAC;YACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,oDAAoD;gBACpD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACzB,OAAO,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC"}
package/mcp-config.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "accessflow": {
4
- "command": "node",
5
- "args": ["./build/index.js"],
6
- "env": {
7
- "MONGO_URI": "mongodb://localhost:27017/accessflow"
8
- }
9
- }
10
- }
11
- }
package/src/index.ts DELETED
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import {
6
- CallToolRequestSchema,
7
- ErrorCode,
8
- ListToolsRequestSchema,
9
- McpError,
10
- } from "@modelcontextprotocol/sdk/types.js";
11
- import rulesData from "./rules.json" with { type: "json" };
12
- import { getToolDefinitions, getToolHandler } from "./tools/index.js";
13
- import { ToolContext } from "./tools/types.js";
14
- import { sanitizeDomain } from "./utils/domain.js";
15
-
16
- export class AccessFlowMCPServer {
17
- private server: Server;
18
- private environment: string;
19
- private domain: string;
20
- private apiKey: string;
21
- private rules: any[] = rulesData;
22
-
23
- constructor() {
24
- this.server = new Server(
25
- {
26
- name: "flow-mcp",
27
- version: "1.0.0",
28
- },
29
- {
30
- capabilities: {
31
- tools: {},
32
- },
33
- }
34
- );
35
-
36
- this.environment = process.env.ENVIRONMENT || "https://accessflow.accessibe.com";
37
-
38
- // Get DOMAIN Key from environment variable
39
- this.domain = sanitizeDomain(process.env.DOMAIN || "");
40
- if (!this.domain) {
41
- console.error("DOMAIN environment variable is required");
42
- process.exit(1);
43
- }
44
-
45
-
46
- // Get API Key from environment variable
47
- this.apiKey = process.env.API_KEY || "";
48
- if (!this.apiKey) {
49
- console.error("API_KEY environment variable is required");
50
- process.exit(1);
51
- }
52
-
53
- this.setupToolHandlers();
54
- }
55
-
56
- private setupToolHandlers(): void {
57
- this.server.setRequestHandler(ListToolsRequestSchema, async () => {
58
- return {
59
- tools: getToolDefinitions(),
60
- };
61
- });
62
-
63
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
64
- const { name, arguments: args } = request.params;
65
-
66
- try {
67
- const handler = getToolHandler(name);
68
- if (!handler) {
69
- throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
70
- }
71
-
72
- const headers: Record<string, string> = {
73
- "x-api-key": this.apiKey,
74
- "x-accessflow-domain": this.domain,
75
- "Content-Type": "application/json",
76
- };
77
-
78
- if (this.environment.toLowerCase().includes("test")) {
79
- const basicAuth = Buffer.from("test:acsb123").toString("base64");
80
- headers["Authorization"] = `Basic ${basicAuth}`;
81
- }
82
-
83
- const context: ToolContext = {
84
- rules: this.rules,
85
- environment: this.environment,
86
- apiKey: this.apiKey,
87
- headers: headers,
88
- };
89
-
90
- return await handler(args || {}, context);
91
- } catch (error) {
92
- if (error instanceof McpError) {
93
- throw error;
94
- }
95
- const errorMessage =
96
- error instanceof Error ? error.message : String(error);
97
- throw new McpError(
98
- ErrorCode.InternalError,
99
- `Tool execution failed: ${errorMessage}`
100
- );
101
- }
102
- });
103
- }
104
-
105
- async run(): Promise<void> {
106
- const transport = new StdioServerTransport();
107
- await this.server.connect(transport);
108
- console.error("AccessFlow MCP Server running on stdio");
109
-
110
- // Handle graceful shutdown
111
- process.on("SIGINT", async () => {
112
- console.error("Shutting down AccessFlow MCP Server...");
113
- process.exit(0);
114
- });
115
-
116
- process.on("SIGTERM", async () => {
117
- console.error("Shutting down AccessFlow MCP Server...");
118
- process.exit(0);
119
- });
120
- }
121
- }
122
-
123
- // Start the server
124
- const server = new AccessFlowMCPServer();
125
- server.run().catch(console.error);
@@ -1,9 +0,0 @@
1
- export class AccessflowService {
2
- private authCookie: string;
3
-
4
- constructor(authCookie: string) {
5
- this.authCookie = authCookie;
6
- }
7
-
8
- async fetchIssue(displayName: string, domain: string) {}
9
- }
@@ -1,218 +0,0 @@
1
- import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
2
- import { ToolDefinition, ToolHandler, ToolContext } from "./types.js";
3
-
4
- export const getIssueRemediationDefinition: ToolDefinition = {
5
- name: "getIssueRemediation",
6
- description:
7
- "Get detailed remediation guidance for an accessibility issue by issue display name",
8
- inputSchema: {
9
- type: "object",
10
- properties: {
11
- issueDisplayName: {
12
- type: "string",
13
- description:
14
- "The accessibility issue display name (e.g., Decorative-Content-6d277a13ba)",
15
- },
16
- },
17
- required: ["issueDisplayName"],
18
- },
19
- };
20
-
21
- export const getIssueRemediationHandler: ToolHandler = async (
22
- args,
23
- context
24
- ) => {
25
- const { issueDisplayName } = args;
26
- const { environment, headers } = context;
27
-
28
- if (!issueDisplayName) {
29
- throw new McpError(
30
- ErrorCode.InvalidParams,
31
- "Issue display name is required"
32
- );
33
- }
34
-
35
- let issue: any;
36
-
37
- try {
38
- const response = await fetch(
39
- `${environment}/api/v6/mcp/${issueDisplayName}`,
40
- {
41
- method: "GET",
42
- headers: headers,
43
- }
44
- );
45
-
46
- if (!response.ok) {
47
- if (response.status === 404) {
48
- return {
49
- content: [
50
- {
51
- type: "text",
52
- text: `**Issue Not Found**\n\nNo accessibility issue found with display name: ${issueDisplayName}\n\nPlease verify the issue display name and try again.`,
53
- },
54
- ],
55
- };
56
- }
57
-
58
- throw new McpError(
59
- ErrorCode.InternalError,
60
- `API request failed: ${response.status} ${response.statusText}`
61
- );
62
- }
63
-
64
- issue = await response.json();
65
- } catch (error) {
66
- if (error instanceof McpError) {
67
- throw error;
68
- }
69
-
70
- throw new McpError(
71
- ErrorCode.InternalError,
72
- `Failed to fetch issue data: ${
73
- error instanceof Error ? error.message : "Unknown error"
74
- }`
75
- );
76
- }
77
-
78
- if (!issue) {
79
- return {
80
- content: [
81
- {
82
- type: "text",
83
- text: `**Issue Not Found**\n\nNo accessibility issue found with display name: ${issueDisplayName}\n\nPlease verify the issue display name and try again.`,
84
- },
85
- ],
86
- };
87
- }
88
-
89
- // Find the related rule
90
- // Handle MongoDB ObjectId - convert to string for comparison
91
- let relatedRuleId = issue.relatedRuleId;
92
-
93
- if (relatedRuleId && typeof relatedRuleId === "object") {
94
- if (relatedRuleId.$oid) {
95
- relatedRuleId = relatedRuleId.$oid;
96
- } else if (
97
- relatedRuleId.toString &&
98
- typeof relatedRuleId.toString === "function"
99
- ) {
100
- relatedRuleId = relatedRuleId.toString();
101
- }
102
- }
103
-
104
- const rule = relatedRuleId
105
- ? context.rules.find((r) => r._id?.$oid === relatedRuleId)
106
- : null;
107
-
108
- // Format the remediation response
109
- const response = formatRemediationResponse(issue, rule);
110
-
111
- return {
112
- content: [
113
- {
114
- type: "text",
115
- text: response,
116
- },
117
- ],
118
- };
119
- };
120
-
121
- function formatRemediationResponse(issue: any, rule: any = null): string {
122
- // 1. Short summary of the problem
123
- const summary =
124
- rule?.shortDescription ||
125
- `Accessibility issue detected: ${issue.displayName}`;
126
-
127
- // 2. WCAG reference & severity
128
- const wcagLevel = issue.WCAGLevel || "Unknown";
129
- const severity = issue.severity?.toUpperCase() || "Unknown";
130
- const criteria = issue.criteria || "Unknown";
131
- const wcagLink = rule?.issueWCAGLink || "";
132
-
133
- // 3. Code-level fix suggestions
134
- let codeFix = "\n## Code-Level Fix\n\n";
135
-
136
- if (rule) {
137
- codeFix += rule.shortDescription
138
- ? `**Solution:** ${rule.shortDescription}\n\n`
139
- : "";
140
-
141
- // Show the current problematic code
142
- if (issue.HTML) {
143
- codeFix += "**Current code:**\n```html\n" + issue.HTML + "\n```\n\n";
144
- }
145
-
146
- // Extract code examples from the HTML resolution if available
147
- if (rule.issueResolution) {
148
- const htmlResolution = rule.issueResolution;
149
- const codeBlocks =
150
- htmlResolution.match(/<pre[^>]*><code[^>]*>(.*?)<\/code><\/pre>/gs) ||
151
- [];
152
-
153
- if (codeBlocks.length > 0) {
154
- // Extract and clean up code examples
155
- codeBlocks.forEach((block: string, index: number) => {
156
- const cleanCode = block
157
- .replace(/<pre[^>]*><code[^>]*>/, "")
158
- .replace(/<\/code><\/pre>/, "")
159
- .replace(/&lt;/g, "<")
160
- .replace(/&gt;/g, ">")
161
- .replace(/&quot;/g, '"')
162
- .replace(/&amp;/g, "&")
163
- .trim();
164
-
165
- codeFix += `**Suggested fix ${
166
- index + 1
167
- }:**\n\`\`\`html\n${cleanCode}\n\`\`\`\n\n`;
168
- });
169
- }
170
- }
171
-
172
- // Add suggested fix details if available
173
- if (rule.suggestedFix && rule.suggestedFix.length > 0) {
174
- codeFix += "**Quick Fix Suggestions:**\n";
175
- rule.suggestedFix.forEach((fix: any, index: number) => {
176
- codeFix += `${index + 1}. **${fix.suggestedFixType}**: `;
177
- if (fix.suggestedFixKey) {
178
- codeFix += `Add attribute \`${fix.suggestedFixKey}="${fix.suggestedFixValue}"\`\n`;
179
- } else {
180
- codeFix += `${fix.suggestedFixValue}\n`;
181
- }
182
- });
183
- codeFix += "\n";
184
- }
185
- } else {
186
- codeFix += "No specific rule found for this issue.\n\n";
187
- }
188
-
189
- // 4. Links back to remediation panel
190
- const remediationLinks = `
191
- ## 📚 Additional Resources
192
-
193
- - **WCAG Reference:** ${
194
- wcagLink
195
- ? `[${wcagLevel} - ${criteria}](${wcagLink})`
196
- : `${wcagLevel} - ${criteria}`
197
- }
198
- - **Tutorial:** ${
199
- rule?.issueTutorialLink || "Contact your AccessFlow administrator"
200
- }
201
- - **Issue Location:** ${issue.webpath} (Selector: \`${issue.selector}\`)
202
- - **AccessFlow Panel:** View full remediation details in your AccessFlow dashboard
203
-
204
- ---
205
- **Issue ID:** ${issue.displayName} | **Detected:** ${new Date(
206
- issue.date?.$date || issue.modified?.$date || Date.now()
207
- ).toLocaleDateString()} | **Confidence:** ${issue.confidence}%`;
208
-
209
- return `# 🚨 ${summary}
210
-
211
- ## 📊 WCAG Reference & Severity
212
- - **Severity:** ${severity}
213
- - **WCAG Level:** ${wcagLevel}
214
- - **Criteria:** ${criteria}
215
- - **Occurrences:** ${issue.occurrences} time(s) on this page
216
- ${codeFix}
217
- ${remediationLinks}`;
218
- }
@@ -1,144 +0,0 @@
1
- import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
2
- import { ToolDefinition, ToolHandler, ToolContext } from "./types.js";
3
-
4
- export const getMostUrgentIssuesDefinition: ToolDefinition = {
5
- name: "getMostUrgentIssues",
6
- description:
7
- "Get the most urgent accessibility issues as structured JSON data, ordered by severity (extreme > high > medium > low), then by site occurrences, then by page occurrences. Use the formatUrgentIssues prompt to format the JSON response into user-friendly markdown.",
8
- inputSchema: {
9
- type: "object",
10
- properties: {},
11
- required: [],
12
- },
13
- };
14
-
15
- export const getMostUrgentIssuesHandler: ToolHandler = async (
16
- args,
17
- context
18
- ) => {
19
- const { environment, headers } = context;
20
-
21
- // Validate limit parameter
22
- const issueLimit = 5;
23
-
24
- try {
25
- const response = await fetch(
26
- `${environment}/api/v6/mcp/urgent-issues?limit=${issueLimit}`,
27
- {
28
- method: "GET",
29
- headers: headers,
30
- }
31
- );
32
-
33
- if (!response.ok) {
34
- throw new McpError(
35
- ErrorCode.InternalError,
36
- `API request failed: ${response.status} ${response.statusText}`
37
- );
38
- }
39
-
40
- const apiResponse = await response.json();
41
-
42
- // Extract the issues array from the response
43
- let issues: any[];
44
- if (Array.isArray(apiResponse)) {
45
- issues = apiResponse;
46
- } else if (apiResponse && Array.isArray(apiResponse.issues)) {
47
- issues = apiResponse.issues;
48
- } else {
49
- throw new McpError(
50
- ErrorCode.InternalError,
51
- `Invalid API response format. Expected array or object with 'issues' array. Received: ${JSON.stringify(
52
- apiResponse,
53
- null,
54
- 2
55
- )}`
56
- );
57
- }
58
-
59
- // The API returns issues already sorted by severity, site occurrences, and page occurrences
60
- const sortedIssues = issues.slice(0, issueLimit);
61
-
62
- if (sortedIssues.length === 0) {
63
- return {
64
- content: [
65
- {
66
- type: "text",
67
- text: JSON.stringify(
68
- {
69
- totalIssues: 0,
70
- showing: 0,
71
- issues: [],
72
- hasMore: false,
73
- },
74
- null,
75
- 2
76
- ),
77
- },
78
- ],
79
- };
80
- }
81
-
82
- // Format the issues data for structured response
83
- const formattedIssues = sortedIssues.map((issue: any, index: number) => ({
84
- rank: index + 1,
85
- displayName: issue.displayName,
86
- severity: issue.severity?.toUpperCase() || "UNKNOWN",
87
- severityEmoji: getSeverityEmoji(issue.severity),
88
- wcagLevel: issue.WCAGLevel || "Unknown",
89
- criteria: issue.criteria || "Unknown",
90
- siteOccurrences: issue.siteOccurrences || 0,
91
- pageOccurrences: issue.occurrences || 0,
92
- }));
93
-
94
- const responseData = {
95
- totalIssues: issues.length,
96
- showing: sortedIssues.length,
97
- limit: issueLimit,
98
- issues: formattedIssues,
99
- hasMore: issues.length > issueLimit,
100
- nextSteps: {
101
- suggestion:
102
- "Use getIssueRemediation with issueDisplayName for detailed fix guidance",
103
- instructions:
104
- "List to the user these issues with all the data for every one of them: severity, wcag, etc. For every issue, show the displayName to the user. After listing all the issues, suggest the user to get full issue remediation data. Do not fix the issues unless explicitly asked to fix",
105
- },
106
- };
107
-
108
- return {
109
- content: [
110
- {
111
- type: "text",
112
- text: JSON.stringify(responseData, null, 2),
113
- },
114
- ],
115
- };
116
- } catch (error) {
117
- if (error instanceof McpError) {
118
- throw error;
119
- }
120
-
121
- // Enhanced error with more context
122
- const errorMessage =
123
- error instanceof Error ? error.message : "Unknown error";
124
- throw new McpError(
125
- ErrorCode.InternalError,
126
- `Failed to fetch urgent issues: ${errorMessage}. This may be due to an unexpected API response format or network issue.`
127
- );
128
- }
129
- };
130
-
131
- function getSeverityEmoji(severity: string): string {
132
- switch (severity?.toLowerCase()) {
133
- case "extreme":
134
- return "🔴";
135
- case "high":
136
- return "🟠";
137
- case "medium":
138
- return "🟡";
139
- case "low":
140
- return "🟢";
141
- default:
142
- return "⚪";
143
- }
144
- }
@@ -1,33 +0,0 @@
1
- import { ToolDefinition, ToolHandler } from "./types.js";
2
- import {
3
- getIssueRemediationDefinition,
4
- getIssueRemediationHandler,
5
- } from "./getIssueRemediation.js";
6
- import {
7
- getMostUrgentIssuesDefinition,
8
- getMostUrgentIssuesHandler,
9
- } from "./getMostUrgentIssues.js";
10
-
11
- export interface Tool {
12
- definition: ToolDefinition;
13
- handler: ToolHandler;
14
- }
15
-
16
- export const tools: Record<string, Tool> = {
17
- getIssueRemediation: {
18
- definition: getIssueRemediationDefinition,
19
- handler: getIssueRemediationHandler,
20
- },
21
- getMostUrgentIssues: {
22
- definition: getMostUrgentIssuesDefinition,
23
- handler: getMostUrgentIssuesHandler,
24
- },
25
- };
26
-
27
- export const getToolDefinitions = (): ToolDefinition[] => {
28
- return Object.values(tools).map((tool) => tool.definition);
29
- };
30
-
31
- export const getToolHandler = (name: string): ToolHandler | undefined => {
32
- return tools[name]?.handler;
33
- };