accessflow-mcp-server 1.0.0-cicd-npm.1

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 (70) hide show
  1. package/README.md +122 -0
  2. package/dist/http-server.d.ts +3 -0
  3. package/dist/http-server.d.ts.map +1 -0
  4. package/dist/http-server.js +58 -0
  5. package/dist/http-server.js.map +1 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +35 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/server.d.ts +28 -0
  11. package/dist/server.d.ts.map +1 -0
  12. package/dist/server.js +181 -0
  13. package/dist/server.js.map +1 -0
  14. package/dist/services/apiSchemas.d.ts +1452 -0
  15. package/dist/services/apiSchemas.d.ts.map +1 -0
  16. package/dist/services/apiSchemas.js +202 -0
  17. package/dist/services/apiSchemas.js.map +1 -0
  18. package/dist/services/apiService.d.ts +45 -0
  19. package/dist/services/apiService.d.ts.map +1 -0
  20. package/dist/services/apiService.js +225 -0
  21. package/dist/services/apiService.js.map +1 -0
  22. package/dist/services/loggerService.d.ts +3 -0
  23. package/dist/services/loggerService.d.ts.map +1 -0
  24. package/dist/services/loggerService.js +54 -0
  25. package/dist/services/loggerService.js.map +1 -0
  26. package/dist/tools/getIssueRemediation.d.ts +16 -0
  27. package/dist/tools/getIssueRemediation.d.ts.map +1 -0
  28. package/dist/tools/getIssueRemediation.js +83 -0
  29. package/dist/tools/getIssueRemediation.js.map +1 -0
  30. package/dist/tools/getMostUrgentIssues.d.ts +8 -0
  31. package/dist/tools/getMostUrgentIssues.d.ts.map +1 -0
  32. package/dist/tools/getMostUrgentIssues.js +105 -0
  33. package/dist/tools/getMostUrgentIssues.js.map +1 -0
  34. package/dist/tools/index.d.ts +13 -0
  35. package/dist/tools/index.d.ts.map +1 -0
  36. package/dist/tools/index.js +94 -0
  37. package/dist/tools/index.js.map +1 -0
  38. package/dist/tools/resolveIssue.d.ts +16 -0
  39. package/dist/tools/resolveIssue.d.ts.map +1 -0
  40. package/dist/tools/resolveIssue.js +88 -0
  41. package/dist/tools/resolveIssue.js.map +1 -0
  42. package/dist/tools/toolRegistry.d.ts +19 -0
  43. package/dist/tools/toolRegistry.d.ts.map +1 -0
  44. package/dist/tools/toolRegistry.js +9 -0
  45. package/dist/tools/toolRegistry.js.map +1 -0
  46. package/dist/types/issues.d.ts +32 -0
  47. package/dist/types/issues.d.ts.map +1 -0
  48. package/dist/types/issues.js +6 -0
  49. package/dist/types/issues.js.map +1 -0
  50. package/dist/types/remediation.d.ts +6 -0
  51. package/dist/types/remediation.d.ts.map +1 -0
  52. package/dist/types/remediation.js +6 -0
  53. package/dist/types/remediation.js.map +1 -0
  54. package/dist/utils/domains.d.ts +2 -0
  55. package/dist/utils/domains.d.ts.map +1 -0
  56. package/dist/utils/domains.js +14 -0
  57. package/dist/utils/domains.js.map +1 -0
  58. package/dist/utils/issues.d.ts +16 -0
  59. package/dist/utils/issues.d.ts.map +1 -0
  60. package/dist/utils/issues.js +24 -0
  61. package/dist/utils/issues.js.map +1 -0
  62. package/dist/utils/middleware.d.ts +14 -0
  63. package/dist/utils/middleware.d.ts.map +1 -0
  64. package/dist/utils/middleware.js +37 -0
  65. package/dist/utils/middleware.js.map +1 -0
  66. package/dist/utils/remediation.d.ts +19 -0
  67. package/dist/utils/remediation.d.ts.map +1 -0
  68. package/dist/utils/remediation.js +123 -0
  69. package/dist/utils/remediation.js.map +1 -0
  70. package/package.json +70 -0
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ [![accessFlow MCP](https://accessflow.accessibe.com/media/MCP-banner.png)](http://accessibe.com/accessflow)
2
+
3
+ # AccessFlow MCP Server
4
+
5
+ A Model Context Protocol (MCP) server that provides intelligent accessibility issue analysis and remediation guidance. This server connects to the accessFlow platform to help developers identify, prioritize, and fix accessibility issues in their web applications.
6
+
7
+ ## 🎯 Purpose
8
+
9
+ The accessFlow MCP Server enables AI clients (like Copilot) to:
10
+
11
+ - **Identify Priority Issues**: Get the most urgent accessibility issues ordered by severity and impact
12
+ - **Provide Fix Guidance**: Generate detailed remediation instructions with code examples
13
+ - **WCAG Compliance**: Reference specific WCAG guidelines and criteria for each issue
14
+ - **Streamline Workflow**: Integrate accessibility testing directly into your development environment
15
+
16
+ ## 🛠️ Available Tools
17
+
18
+ ### `getMostUrgentIssues`
19
+
20
+ Retrieves the most critical accessibility issues, prioritized by:
21
+
22
+ 1. **Severity**: EXTREME → HIGH → MEDIUM → LOW
23
+ 2. **Site Impact**: Number of locations affected across the site
24
+ 3. **Page Impact**: Number of occurrences on individual pages
25
+
26
+ **Parameters**: None (uses configured domain)
27
+
28
+ **Returns**: JSON data with structured issue information including severity, WCAG level, occurrence counts, and unique identifiers.
29
+
30
+ ### `getIssueRemediation`
31
+
32
+ Provides detailed remediation guidance for a specific accessibility issue.
33
+
34
+ **Parameters**:
35
+
36
+ - `issueDisplayName` (string, required): The unique identifier for the accessibility issue
37
+
38
+ **Returns**: Comprehensive fix guidance including:
39
+
40
+ - Problem summary and WCAG references
41
+ - Current problematic code
42
+ - Suggested code fixes with examples
43
+ - Step-by-step remediation instructions
44
+ - Links to tutorials and additional resources
45
+
46
+ ### `resolveIssue`
47
+
48
+ Marks the specified issue as resolved in accessFlow.
49
+ Note: If the next audit still detects this issue, it will be reopened automatically.
50
+
51
+ **Parameters**:
52
+
53
+ - `issueDisplayName` (string, required): The unique identifier for the accessibility issue
54
+
55
+ ## 📋 Usage
56
+
57
+ ### Configuration
58
+
59
+ Add the following configuration to your MCP client (e.g., VS Code Copilot Agent):
60
+
61
+ ```json
62
+ {
63
+ "mcpServers": {
64
+ "flow-mcp": {
65
+ "command": "npx",
66
+ "args": ["-y", "accessflow-mcp-server"],
67
+ "env": {
68
+ "API_KEY": "your-accessflow-api-key",
69
+ "DOMAIN": "https://your-app-domain.com"
70
+ },
71
+ "type": "stdio"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ #### Configuration Parameters
78
+
79
+ - **`API_KEY`** (required): Your accessFlow API key for authentication
80
+ - **`DOMAIN`** (required): The domain of your application being analyzed (e.g., `example.com` - without protocol)
81
+ - **`ENVIRONMENT`** (optional): API environment URL (defaults to `https://accessflow.accessibe.com`)
82
+
83
+ #### Environment Setup
84
+
85
+ For local development, create a `.env` file in the project root:
86
+
87
+ ```bash
88
+ # Required: Your domain name (without protocol)
89
+ DOMAIN=your-domain.com
90
+
91
+ # Required: Your accessFlow API key
92
+ API_KEY=your-api-key-here
93
+
94
+ # Optional: Environment URL (defaults to production)
95
+ ENVIRONMENT=https://accessflow.accessibe.com
96
+ ```
97
+
98
+ **Important**: Replace `your-domain.com` and `your-api-key-here` with your actual values before running the server.
99
+
100
+ ### 3. Example Usage
101
+
102
+ Once configured, you can interact with the server through your MCP client:
103
+
104
+ **Get Priority Issues:**
105
+
106
+ ```text
107
+ "Show me the most urgent accessibility issues for my site"
108
+ ```
109
+
110
+ **Get Specific Remediation:**
111
+
112
+ ```text
113
+ "Get remediation guidance for issue: Decorative-Content-6d277a13ba"
114
+ ```
115
+
116
+ ## Supported Clients
117
+
118
+ This MCP server works with AI agents in IDEs and other MCP-compatible clients:
119
+
120
+ - **VS Code Copilot**: Integrates with GitHub Copilot in VS Code
121
+ - **Cursor**: Works with Cursor's AI assistant
122
+ - **Other MCP Clients**: Any application supporting the Model Context Protocol
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import { FlowMcpServer } from './server.js';
4
+ import { logger } from './services/loggerService.js';
5
+ async function startServer() {
6
+ try {
7
+ console.log('Starting HTTP server...');
8
+ // Get port from environment variable or use default
9
+ const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 8080;
10
+ const stateless = process.env.STATELESS === 'true';
11
+ const transportConfig = {
12
+ type: 'httpStream',
13
+ port,
14
+ host: '0.0.0.0', // Listen on all network interfaces
15
+ stateless,
16
+ };
17
+ console.log('Creating server instance...');
18
+ const server = new FlowMcpServer(transportConfig);
19
+ // Handle graceful shutdown
20
+ process.on('SIGINT', async () => {
21
+ logger.info('Received SIGINT, shutting down gracefully...');
22
+ await server.stop();
23
+ logger.info('Server stopped successfully');
24
+ process.exit(0);
25
+ });
26
+ process.on('SIGTERM', async () => {
27
+ logger.info('Received SIGTERM, shutting down gracefully...');
28
+ await server.stop();
29
+ logger.info('Server stopped successfully');
30
+ process.exit(0);
31
+ });
32
+ console.log('Initializing server...');
33
+ // Start server with HTTP transport
34
+ await server.init();
35
+ logger.info(`HTTP server is running at http://${transportConfig.host}:${port}/mcp`);
36
+ console.log(`HTTP server is running at http://${transportConfig.host}:${port}/mcp`);
37
+ }
38
+ catch (error) {
39
+ console.error('Error starting HTTP server:', error);
40
+ logger.error({
41
+ error: error instanceof Error ? error.message : 'Unknown error',
42
+ stack: error instanceof Error ? error.stack : undefined,
43
+ }, 'Failed to start Flow MCP HTTP Server');
44
+ // Exit code 1 will indicate failure to the parent process
45
+ process.exit(1);
46
+ }
47
+ }
48
+ // Add top-level error handlers
49
+ process.on('uncaughtException', (error) => {
50
+ console.error('Uncaught exception:', error);
51
+ process.exit(1);
52
+ });
53
+ process.on('unhandledRejection', (reason, promise) => {
54
+ console.error('Unhandled rejection at:', promise, 'reason:', reason);
55
+ process.exit(1);
56
+ });
57
+ startServer();
58
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import { FlowMcpServer } from './server.js';
4
+ import { logger } from './services/loggerService.js';
5
+ async function startServer() {
6
+ const transportConfig = { type: 'stdio' };
7
+ const server = new FlowMcpServer(transportConfig);
8
+ // Handle graceful shutdown
9
+ process.on('SIGINT', async () => {
10
+ logger.info('Received SIGINT, shutting down gracefully...');
11
+ await server.stop();
12
+ logger.info('Server stopped successfully');
13
+ process.exit(0);
14
+ });
15
+ process.on('SIGTERM', async () => {
16
+ logger.info('Received SIGTERM, shutting down gracefully...');
17
+ await server.stop();
18
+ logger.info('Server stopped successfully');
19
+ process.exit(0);
20
+ });
21
+ try {
22
+ // Start server with stdio transport (default for MCP clients)
23
+ await server.init();
24
+ }
25
+ catch (error) {
26
+ logger.error({
27
+ error: error instanceof Error ? error.message : 'Unknown error',
28
+ stack: error instanceof Error ? error.stack : undefined,
29
+ }, 'Failed to start Flow MCP Server');
30
+ // Exit code 1 will indicate failure to the parent process
31
+ process.exit(1);
32
+ }
33
+ }
34
+ startServer();
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,KAAK,UAAU,WAAW;IACxB,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,OAAgB,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,eAAe,CAAC,CAAC;IAElD,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QAC5D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC7D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV;YACE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;YAC/D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACxD,EACD,iCAAiC,CAClC,CAAC;QAEF,0DAA0D;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,WAAW,EAAE,CAAC"}
@@ -0,0 +1,28 @@
1
+ import 'dotenv/config';
2
+ export type TransportConfig = {
3
+ type: 'stdio';
4
+ } | {
5
+ type: 'httpStream';
6
+ port: number;
7
+ host?: string;
8
+ stateless?: boolean;
9
+ };
10
+ export interface SessionData {
11
+ apiKey: string;
12
+ domain: string;
13
+ environment?: string;
14
+ nonProdUsername?: string;
15
+ nonProdPassword?: string;
16
+ [key: string]: unknown;
17
+ }
18
+ export declare class FlowMcpServer {
19
+ private readonly options;
20
+ private readonly server;
21
+ private readonly environment;
22
+ private readonly transportConfig;
23
+ private stdioApiService?;
24
+ constructor(transportConfig: TransportConfig);
25
+ init(): Promise<this>;
26
+ stop(): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAQvB,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAGlD,OAAO,CAAC,eAAe,CAAC,CAAa;gBAEzB,eAAe,EAAE,eAAe;IAoItC,IAAI;IAqFJ,IAAI;CAGX"}
package/dist/server.js ADDED
@@ -0,0 +1,181 @@
1
+ import 'dotenv/config';
2
+ import { FastMCP } from 'fastmcp';
3
+ import packageJson from '../package.json' with { type: 'json' };
4
+ import { registerTools } from './tools/index.js';
5
+ import { sanitizeDomain } from './utils/domains.js';
6
+ import { ApiService } from './services/apiService.js';
7
+ import { logger } from './services/loggerService.js';
8
+ export class FlowMcpServer {
9
+ options;
10
+ server;
11
+ environment;
12
+ transportConfig;
13
+ // For stdio mode only
14
+ stdioApiService;
15
+ constructor(transportConfig) {
16
+ this.transportConfig = transportConfig;
17
+ this.environment =
18
+ process.env.ENVIRONMENT || 'https://accessflow.accessibe.com';
19
+ const nonProdUserName = process.env.NON_PROD_USER_NAME;
20
+ const nonProdPassword = process.env.NON_PROD_PASSWORD;
21
+ // Configure server options based on transport type
22
+ if (transportConfig.type === 'httpStream') {
23
+ // HTTP mode: Extract credentials from headers per-request
24
+ this.options = {
25
+ name: 'accessFlow MCP Server',
26
+ version: packageJson.version,
27
+ authenticate: async (request) => {
28
+ // Helper function for case-insensitive header lookup
29
+ const getHeader = (name) => {
30
+ const lowerName = name.toLowerCase();
31
+ // Try lowercase first (most common)
32
+ if (request.headers[lowerName]) {
33
+ return request.headers[lowerName];
34
+ }
35
+ // Try exact case
36
+ if (request.headers[name]) {
37
+ return request.headers[name];
38
+ }
39
+ // Search case-insensitively through all headers
40
+ for (const [key, value] of Object.entries(request.headers)) {
41
+ if (key.toLowerCase() === lowerName) {
42
+ return value;
43
+ }
44
+ }
45
+ return undefined;
46
+ };
47
+ // Log all headers for debugging
48
+ logger.debug({ headers: Object.keys(request.headers) }, 'Incoming HTTP request headers');
49
+ // Extract Authorization header (Bearer token)
50
+ const authHeader = getHeader('authorization');
51
+ const apiKey = authHeader?.replace(/^Bearer\s+/i, '') || '';
52
+ // Extract X-Domain header
53
+ const domainHeader = getHeader('x-domain');
54
+ const domain = sanitizeDomain(domainHeader || '');
55
+ // Extract optional X-Environment header (defaults to production)
56
+ const environmentHeader = getHeader('x-environment');
57
+ const environment = environmentHeader || 'https://accessflow.accessibe.com';
58
+ // Extract optional non-prod basic auth credentials (for staging environments)
59
+ const nonProdUsername = getHeader('x-nonprod-username');
60
+ const nonProdPassword = getHeader('x-nonprod-password');
61
+ if (nonProdUsername && nonProdPassword) {
62
+ logger.debug({
63
+ domain,
64
+ hasNonProdCreds: true,
65
+ }, 'Using non-prod credentials for API calls');
66
+ }
67
+ if (!apiKey || !domain) {
68
+ logger.warn({
69
+ hasAuthHeader: !!authHeader,
70
+ hasDomainHeader: !!domainHeader,
71
+ headerKeys: Object.keys(request.headers),
72
+ }, 'Authentication failed: missing headers');
73
+ throw new Response(null, {
74
+ status: 401,
75
+ statusText: 'Unauthorized: Missing Authorization or X-Domain header',
76
+ });
77
+ }
78
+ logger.debug({
79
+ domain,
80
+ environment,
81
+ apiKeyPrefix: apiKey.substring(0, 10) + '...',
82
+ }, 'HTTP request authenticated');
83
+ const sessionData = {
84
+ apiKey,
85
+ domain,
86
+ environment,
87
+ };
88
+ // Only include nonProd credentials if they are defined
89
+ if (nonProdUsername !== undefined) {
90
+ sessionData.nonProdUsername = nonProdUsername;
91
+ }
92
+ if (nonProdPassword !== undefined) {
93
+ sessionData.nonProdPassword = nonProdPassword;
94
+ }
95
+ return sessionData;
96
+ },
97
+ };
98
+ }
99
+ else {
100
+ // stdio mode: Use environment variables (backward compatible)
101
+ const domain = sanitizeDomain(process.env.DOMAIN || '');
102
+ const apiKey = process.env.API_KEY || '';
103
+ this.stdioApiService = new ApiService(this.environment, domain, apiKey, nonProdUserName, nonProdPassword);
104
+ this.options = {
105
+ name: 'accessFlow MCP Server',
106
+ version: packageJson.version,
107
+ };
108
+ }
109
+ this.server = new FastMCP(this.options);
110
+ }
111
+ async init() {
112
+ const transportType = this.transportConfig.type;
113
+ const transportMode = transportType === 'stdio' ? 'stdio' : 'HTTP';
114
+ logger.info(`Initializing Flow MCP Server (${transportMode} mode)...`);
115
+ const nonProdUserName = process.env.NON_PROD_USER_NAME;
116
+ const nonProdPassword = process.env.NON_PROD_PASSWORD;
117
+ // Register tools with appropriate configuration
118
+ if (transportType === 'stdio') {
119
+ // stdio mode: Use pre-created ApiService
120
+ if (!this.stdioApiService) {
121
+ throw new Error('ApiService not initialized for stdio mode');
122
+ }
123
+ registerTools(this.server, {
124
+ mode: 'stdio',
125
+ apiService: this.stdioApiService,
126
+ });
127
+ }
128
+ else {
129
+ // HTTP mode: Create ApiService per-request from session
130
+ registerTools(this.server, {
131
+ mode: 'http',
132
+ createApiService: (session) => {
133
+ // Use environment from session (X-Environment header) or fall back to default
134
+ const environment = session.environment || 'https://accessflow.accessibe.com';
135
+ // Use credentials from session headers, or fall back to environment variables
136
+ const username = session.nonProdUsername || nonProdUserName;
137
+ const password = session.nonProdPassword || nonProdPassword;
138
+ return new ApiService(environment, session.domain, session.apiKey, username, password);
139
+ },
140
+ });
141
+ }
142
+ // Start the FastMCP server with the specified transport
143
+ if (transportType === 'stdio') {
144
+ await this.server.start({
145
+ transportType: 'stdio',
146
+ });
147
+ }
148
+ else {
149
+ const httpStreamConfig = {
150
+ port: this.transportConfig.port,
151
+ ...(this.transportConfig.host !== undefined && {
152
+ host: this.transportConfig.host,
153
+ }),
154
+ };
155
+ if (this.transportConfig.stateless !== undefined) {
156
+ httpStreamConfig.stateless = this.transportConfig.stateless;
157
+ }
158
+ await this.server.start({
159
+ transportType: 'httpStream',
160
+ httpStream: httpStreamConfig,
161
+ });
162
+ }
163
+ logger.info({
164
+ environment: this.environment,
165
+ transport: transportMode,
166
+ ...(transportType === 'httpStream' && {
167
+ port: this.transportConfig.port,
168
+ }),
169
+ ...(transportType === 'stdio' &&
170
+ this.stdioApiService && {
171
+ domain: this.stdioApiService.domain,
172
+ }),
173
+ }, 'Flow MCP Server started successfully');
174
+ return this;
175
+ }
176
+ async stop() {
177
+ if (this.server)
178
+ await this.server.stop();
179
+ }
180
+ }
181
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}