# Directory Structure
```
├── .env.example
├── .eslintrc
├── .github
│   └── workflows
│       └── node.yml
├── .gitignore
├── Dockerfile
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── src
│   ├── config
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── controllers
│   │   ├── mcp.controller.test.ts
│   │   └── mcp.controller.ts
│   ├── index.ts
│   ├── middleware
│   │   └── auth.middleware.ts
│   ├── models
│   │   ├── mcp-client-config.ts
│   │   └── mcp.types.ts
│   ├── routes
│   │   └── mcp.routes.ts
│   ├── services
│   │   ├── falkordb.service.test.ts
│   │   └── falkordb.service.ts
│   └── utils
│       └── connection-parser.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
```
 1 | # Server Configuration
 2 | PORT=3000
 3 | NODE_ENV=development
 4 | 
 5 | # FalkorDB Configuration
 6 | FALKORDB_HOST=localhost
 7 | FALKORDB_PORT=6379
 8 | FALKORDB_USERNAME=
 9 | FALKORDB_PASSWORD=
10 | 
11 | # MCP Configuration
12 | MCP_API_KEY=your_mcp_api_key_here
```
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
```
 1 | {
 2 |     "root": true,
 3 |     "parser": "@typescript-eslint/parser",
 4 |     "plugins": [
 5 |       "@typescript-eslint"
 6 |     ],
 7 |     "extends": [
 8 |       "eslint:recommended",
 9 |       "plugin:@typescript-eslint/recommended"
10 |     ],
11 |     "rules": {
12 |       "@typescript-eslint/explicit-module-boundary-types": "warn",
13 |       "@typescript-eslint/no-explicit-any": "off",
14 |       "no-console": "off"
15 |     },
16 |     "env": {
17 |       "node": true,
18 |       "es6": true
19 |     }
20 |   }
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
  1 | # Logs
  2 | logs
  3 | *.log
  4 | npm-debug.log*
  5 | yarn-debug.log*
  6 | yarn-error.log*
  7 | lerna-debug.log*
  8 | .pnpm-debug.log*
  9 | 
 10 | # Diagnostic reports (https://nodejs.org/api/report.html)
 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
 12 | 
 13 | # Runtime data
 14 | pids
 15 | *.pid
 16 | *.seed
 17 | *.pid.lock
 18 | 
 19 | # Directory for instrumented libs generated by jscoverage/JSCover
 20 | lib-cov
 21 | 
 22 | # Coverage directory used by tools like istanbul
 23 | coverage
 24 | *.lcov
 25 | 
 26 | # nyc test coverage
 27 | .nyc_output
 28 | 
 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
 30 | .grunt
 31 | 
 32 | # Bower dependency directory (https://bower.io/)
 33 | bower_components
 34 | 
 35 | # node-waf configuration
 36 | .lock-wscript
 37 | 
 38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
 39 | build/Release
 40 | 
 41 | # Dependency directories
 42 | node_modules/
 43 | jspm_packages/
 44 | 
 45 | # Snowpack dependency directory (https://snowpack.dev/)
 46 | web_modules/
 47 | 
 48 | # TypeScript cache
 49 | *.tsbuildinfo
 50 | 
 51 | # Optional npm cache directory
 52 | .npm
 53 | 
 54 | # Optional eslint cache
 55 | .eslintcache
 56 | 
 57 | # Optional stylelint cache
 58 | .stylelintcache
 59 | 
 60 | # Microbundle cache
 61 | .rpt2_cache/
 62 | .rts2_cache_cjs/
 63 | .rts2_cache_es/
 64 | .rts2_cache_umd/
 65 | 
 66 | # Optional REPL history
 67 | .node_repl_history
 68 | 
 69 | # Output of 'npm pack'
 70 | *.tgz
 71 | 
 72 | # Yarn Integrity file
 73 | .yarn-integrity
 74 | 
 75 | # dotenv environment variable files
 76 | .env
 77 | .env.development.local
 78 | .env.test.local
 79 | .env.production.local
 80 | .env.local
 81 | 
 82 | # parcel-bundler cache (https://parceljs.org/)
 83 | .cache
 84 | .parcel-cache
 85 | 
 86 | # Next.js build output
 87 | .next
 88 | out
 89 | 
 90 | # Nuxt.js build / generate output
 91 | .nuxt
 92 | dist
 93 | 
 94 | # Gatsby files
 95 | .cache/
 96 | # Comment in the public line in if your project uses Gatsby and not Next.js
 97 | # https://nextjs.org/blog/next-9-1#public-directory-support
 98 | # public
 99 | 
100 | # vuepress build output
101 | .vuepress/dist
102 | 
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 | 
107 | # vitepress build output
108 | **/.vitepress/dist
109 | 
110 | # vitepress cache directory
111 | **/.vitepress/cache
112 | 
113 | # Docusaurus cache and generated files
114 | .docusaurus
115 | 
116 | # Serverless directories
117 | .serverless/
118 | 
119 | # FuseBox cache
120 | .fusebox/
121 | 
122 | # DynamoDB Local files
123 | .dynamodb/
124 | 
125 | # TernJS port file
126 | .tern-port
127 | 
128 | # Stores VSCode versions used for testing VSCode extensions
129 | .vscode-test
130 | 
131 | # yarn v2
132 | .yarn/cache
133 | .yarn/unplugged
134 | .yarn/build-state.yml
135 | .yarn/install-state.gz
136 | .pnp.*
137 | 
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
  1 | # FalkorDB MCP Server
  2 | 
  3 | A Model Context Protocol (MCP) server for FalkorDB, allowing AI models to query and interact with graph databases.
  4 | 
  5 | ## Overview
  6 | 
  7 | This project implements a server that follows the Model Context Protocol (MCP) specification to connect AI models with FalkorDB graph databases. The server translates and routes MCP requests to FalkorDB and formats the responses according to the MCP standard.
  8 | 
  9 | ## Prerequisites
 10 | 
 11 | * Node.js (v16 or later)
 12 | * npm or yarn
 13 | * FalkorDB instance (can be run locally or remotely)
 14 | 
 15 | ## Installation
 16 | 
 17 | 1. Clone this repository:
 18 | 
 19 |    ```bash
 20 |    git clone https://github.com/falkordb/falkordb-mcpserver.git
 21 |    cd falkordb-mcpserver
 22 |    ```
 23 | 2. Install dependencies:
 24 | 
 25 |    ```bash
 26 |    npm install
 27 |    ```
 28 | 3. Copy the example environment file and configure it:
 29 | 
 30 |    ```bash
 31 |    cp .env.example .env
 32 |    ```
 33 | 
 34 |    Edit `.env` with your configuration details.
 35 | 
 36 | ## Configuration
 37 | 
 38 | Configuration is managed through environment variables in the `.env` file:
 39 | 
 40 | * `PORT`: Server port (default: 3000)
 41 | * `NODE_ENV`: Environment (development, production)
 42 | * `FALKORDB_HOST`: FalkorDB host (default: localhost)
 43 | * `FALKORDB_PORT`: FalkorDB port (default: 6379)
 44 | * `FALKORDB_USERNAME`: Username for FalkorDB authentication (if required)
 45 | * `FALKORDB_PASSWORD`: Password for FalkorDB authentication (if required)
 46 | * `MCP_API_KEY`: API key for authenticating MCP requests
 47 | 
 48 | ## Usage
 49 | 
 50 | ### Development
 51 | 
 52 | Start the development server with hot-reloading:
 53 | 
 54 | ```bash
 55 | npm run dev
 56 | ```
 57 | 
 58 | ### Production
 59 | 
 60 | Build and start the server:
 61 | 
 62 | ```bash
 63 | npm run build
 64 | npm start
 65 | ```
 66 | 
 67 | ## API Endpoints
 68 | 
 69 | * `GET /api/mcp/metadata`: Get metadata about the FalkorDB instance and available capabilities
 70 | * `POST /api/mcp/context`: Execute queries against FalkorDB
 71 | * `GET /api/mcp/health`: Check server health
 72 | * `GET /api/mcp/graphs`: Returns the list of Graphs
 73 | * 
 74 | 
 75 | ## MCP Configuration
 76 | 
 77 | To use this server with MCP clients, you can add it to your MCP configuration:
 78 | 
 79 | ```json
 80 | {
 81 |   "mcpServers": {
 82 |     "falkordb": {
 83 |       "command": "docker",
 84 |       "args": [
 85 |         "run",
 86 |         "-i",
 87 |         "--rm",
 88 |         "-p", "3000:3000",
 89 |         "--env-file", ".env",
 90 |         "falkordb-mcpserver",
 91 |         "falkordb://host.docker.internal:6379"
 92 |       ]
 93 |     }
 94 |   }
 95 | }
 96 | ```
 97 | 
 98 | For client-side configuration:
 99 | 
100 | ```json
101 | {
102 |   "defaultServer": "falkordb",
103 |   "servers": {
104 |     "falkordb": {
105 |       "url": "http://localhost:3000/api/mcp",
106 |       "apiKey": "your_api_key_here"
107 |     }
108 |   }
109 | }
110 | ```
111 | 
112 | ## Contributing
113 | 
114 | Contributions are welcome! Please feel free to submit a Pull Request.
115 | 
116 | ## License
117 | 
118 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
119 | 
```
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import dotenv from 'dotenv';
 2 | 
 3 | // Load environment variables from .env file
 4 | dotenv.config();
 5 | 
 6 | export const config = {
 7 |   server: {
 8 |     port: process.env.PORT || 3000,
 9 |     nodeEnv: process.env.NODE_ENV || 'development',
10 |   },
11 |   falkorDB: {
12 |     host: process.env.FALKORDB_HOST || 'localhost',
13 |     port: parseInt(process.env.FALKORDB_PORT || '6379'),
14 |     username: process.env.FALKORDB_USERNAME || '',
15 |     password: process.env.FALKORDB_PASSWORD || '',
16 |   },
17 |   mcp: {
18 |     apiKey: process.env.MCP_API_KEY || '',
19 |   },
20 | };
```
--------------------------------------------------------------------------------
/src/routes/mcp.routes.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import { Router } from 'express';
 2 | import { mcpController } from '../controllers/mcp.controller';
 3 | 
 4 | const router = Router();
 5 | 
 6 | // MCP API routes
 7 | router.post('/context', mcpController.processContextRequest.bind(mcpController));
 8 | router.get('/metadata', mcpController.processMetadataRequest.bind(mcpController));
 9 | router.get('/graphs', mcpController.listGraphs.bind(mcpController));
10 | 
11 | // Additional MCP related routes could be added here
12 | router.get('/health', (req, res) => {
13 |   res.status(200).json({ status: 'ok' });
14 | });
15 | 
16 | export const mcpRoutes = router;
```
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
```javascript
 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */
 2 | module.exports = {
 3 |     preset: 'ts-jest',
 4 |     testEnvironment: 'node',
 5 |     roots: ['<rootDir>/src'],
 6 |     transform: {
 7 |       '^.+\\.tsx?$': 'ts-jest',
 8 |     },
 9 |     testRegex: '(\\.|/)(test|spec)\\.tsx?$',
10 |     moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
11 |     collectCoverageFrom: [
12 |       'src/**/*.ts',
13 |       '!src/**/*.d.ts',
14 |       '!src/**/*.test.ts',
15 |       '!src/**/*.spec.ts',
16 |     ],
17 |     coverageDirectory: 'coverage',
18 |     testPathIgnorePatterns: ['/node_modules/', '/dist/']
19 |   };
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
 1 | FROM node:18-alpine AS builder
 2 | 
 3 | WORKDIR /app
 4 | 
 5 | # Copy package files and install dependencies
 6 | COPY package*.json ./
 7 | RUN npm ci
 8 | 
 9 | # Copy source code
10 | COPY . .
11 | 
12 | # Build the application
13 | RUN npm run build
14 | 
15 | # Remove development dependencies
16 | RUN npm prune --production
17 | 
18 | # Production image
19 | FROM node:18-alpine
20 | 
21 | WORKDIR /app
22 | 
23 | # Set environment variables
24 | ENV NODE_ENV=production
25 | 
26 | # Copy built application from builder stage
27 | COPY --from=builder /app/dist ./dist
28 | COPY --from=builder /app/node_modules ./node_modules
29 | COPY --from=builder /app/package*.json ./
30 | 
31 | # Expose the port the app runs on
32 | EXPOSE 3000
33 | 
34 | # Run the application
35 | CMD ["node", "dist/index.js"]
```
--------------------------------------------------------------------------------
/src/models/mcp.types.ts:
--------------------------------------------------------------------------------
```typescript
 1 | /**
 2 |  * MCP Types - based on Model Context Protocol specification
 3 |  */
 4 | 
 5 | export interface MCPContextRequest {
 6 |   graphName: string;
 7 |   query: string;
 8 |   params?: Record<string, any>;
 9 |   context?: Record<string, any>;
10 |   options?: MCPOptions;
11 | }
12 | 
13 | export interface MCPOptions {
14 |   timeout?: number;
15 |   maxResults?: number;
16 |   [key: string]: any;
17 | }
18 | 
19 | export interface MCPResponse {
20 |   data: any;
21 |   metadata: MCPMetadata;
22 | }
23 | 
24 | export interface MCPMetadata {
25 |   timestamp: string;
26 |   queryTime: number;
27 |   provider?: string;
28 |   source?: string;
29 |   [key: string]: any;
30 | }
31 | 
32 | export interface MCPProviderMetadata {
33 |   provider: string;
34 |   version: string;
35 |   capabilities: string[];
36 |   graphTypes: string[];
37 |   queryLanguages: string[];
38 |   [key: string]: any;
39 | }
```
--------------------------------------------------------------------------------
/src/config/index.test.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import { config } from '../config';
 2 | 
 3 | describe('Config', () => {
 4 |   test('should have server configuration', () => {
 5 |     expect(config).toHaveProperty('server');
 6 |     expect(config.server).toHaveProperty('port');
 7 |     expect(config.server).toHaveProperty('nodeEnv');
 8 |   });
 9 | 
10 |   test('should have FalkorDB configuration', () => {
11 |     expect(config).toHaveProperty('falkorDB');
12 |     expect(config.falkorDB).toHaveProperty('host');
13 |     expect(config.falkorDB).toHaveProperty('port');
14 |     expect(config.falkorDB).toHaveProperty('username');
15 |     expect(config.falkorDB).toHaveProperty('password');
16 |   });
17 | 
18 |   test('should have MCP configuration', () => {
19 |     expect(config).toHaveProperty('mcp');
20 |     expect(config.mcp).toHaveProperty('apiKey');
21 |   });
22 | });
```
--------------------------------------------------------------------------------
/src/middleware/auth.middleware.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import { Request, Response, NextFunction } from 'express';
 2 | import { config } from '../config';
 3 | 
 4 | /**
 5 |  * Middleware to authenticate MCP API requests
 6 |  */
 7 | export const authenticateMCP = (req: Request, res: Response, next: NextFunction): Response<any, Record<string, any>> | void => {
 8 |   const apiKey = req.headers['x-api-key'] || req.query.apiKey;
 9 |   
10 |   // Skip authentication for development environment
11 |   if (config.server.nodeEnv === 'development' && !config.mcp.apiKey) {
12 |     console.warn('Warning: Running without API key authentication in development mode');
13 |     return next();
14 |   }
15 |   
16 |   if (!apiKey) {
17 |     return res.status(401).json({ error: 'Missing API key' });
18 |   }
19 |   
20 |   if (apiKey !== config.mcp.apiKey) {
21 |     return res.status(403).json({ error: 'Invalid API key' });
22 |   }
23 |   
24 |   next();
25 | };
```
--------------------------------------------------------------------------------
/src/models/mcp-client-config.ts:
--------------------------------------------------------------------------------
```typescript
 1 | /**
 2 |  * MCP Client Configuration Types
 3 |  */
 4 | 
 5 | export interface MCPServerConfig {
 6 |     mcpServers: {
 7 |       [key: string]: {
 8 |         command: string;
 9 |         args: string[];
10 |       };
11 |     };
12 |   }
13 |   
14 |   export interface MCPClientConfig {
15 |     defaultServer?: string;
16 |     servers: {
17 |       [key: string]: {
18 |         url: string;
19 |         apiKey?: string;
20 |       };
21 |     };
22 |   }
23 |   
24 |   /**
25 |    * Sample MCP Client Configuration
26 |    */
27 |   export const sampleMCPClientConfig: MCPClientConfig = {
28 |     defaultServer: "falkordb",
29 |     servers: {
30 |       "falkordb": {
31 |         url: "http://localhost:3000/api/mcp",
32 |         apiKey: "your_api_key_here"
33 |       }
34 |     }
35 |   };
36 |   
37 |   /**
38 |    * Sample MCP Server Configuration
39 |    */
40 |   export const sampleMCPServerConfig: MCPServerConfig = {
41 |     mcpServers: {
42 |       "falkordb": {
43 |         command: "docker",
44 |         args: [
45 |           "run",
46 |           "-i",
47 |           "--rm",
48 |           "-p", "3000:3000",
49 |           "--env-file", ".env",
50 |           "falkordb-mcpserver",
51 |           "falkordb://host.docker.internal:6379"
52 |         ]
53 |       }
54 |     }
55 |   };
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
 1 | {
 2 |   "name": "falkordb-mcpserver",
 3 |   "version": "1.0.0",
 4 |   "description": "Model Context Protocol server for FalkorDB",
 5 |   "main": "dist/index.js",
 6 |   "scripts": {
 7 |     "build": "tsc",
 8 |     "start": "node dist/index.js",
 9 |     "dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts",
10 |     "lint": "eslint . --ext .ts",
11 |     "test": "jest",
12 |     "test:coverage": "jest --coverage",
13 |     "docker:build": "docker build -t falkordb-mcpserver .",
14 |     "docker:run": "docker run -p 3000:3000 falkordb-mcpserver"
15 |   },
16 |   "keywords": [
17 |     "mcp",
18 |     "modelcontextprotocol",
19 |     "falkordb",
20 |     "graph",
21 |     "database"
22 |   ],
23 |   "author": "",
24 |   "license": "ISC",
25 |   "devDependencies": {
26 |     "@types/express": "^4.17.21",
27 |     "@types/node": "^20.11.0",
28 |     "@typescript-eslint/eslint-plugin": "^6.15.0",
29 |     "@typescript-eslint/parser": "^6.15.0",
30 |     "eslint": "^8.56.0",
31 |     "jest": "^29.7.0",
32 |     "@types/jest": "^29.5.11",
33 |     "ts-jest": "^29.1.1",
34 |     "nodemon": "^3.0.2",
35 |     "ts-node": "^10.9.2",
36 |     "typescript": "^5.3.3"
37 |   },
38 |   "dependencies": {
39 |     "@modelcontextprotocol/sdk": "^1.8.0",
40 |     "dotenv": "^16.4.7",
41 |     "express": "^4.21.2",
42 |     "falkordb": "^6.2.07"
43 |   }
44 | }
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import express from 'express';
 2 | import { config } from './config';
 3 | import { mcpRoutes } from './routes/mcp.routes';
 4 | import { authenticateMCP } from './middleware/auth.middleware';
 5 | import { falkorDBService } from './services/falkordb.service';
 6 | 
 7 | // Initialize Express app
 8 | const app = express();
 9 | 
10 | // Middleware
11 | app.use(express.json());
12 | app.use(express.urlencoded({ extended: true }));
13 | 
14 | // Apply authentication to MCP routes
15 | app.use('/api/mcp', authenticateMCP, mcpRoutes);
16 | 
17 | // Basic routes
18 | app.get('/', (req, res) => {
19 |   res.json({
20 |     name: 'FalkorDB MCP Server',
21 |     version: '1.0.0',
22 |     status: 'running',
23 |   });
24 | });
25 | 
26 | // Start server
27 | const PORT = config.server.port;
28 | app.listen(PORT, () => {
29 |   console.log(`FalkorDB MCP Server listening on port ${PORT}`);
30 |   console.log(`Environment: ${config.server.nodeEnv}`);
31 | });
32 | 
33 | // Handle graceful shutdown
34 | process.on('SIGTERM', async () => {
35 |   console.log('SIGTERM received. Shutting down gracefully...');
36 |   // Close database connections
37 |   await falkorDBService.close();
38 |   process.exit(0);
39 | });
40 | 
41 | process.on('SIGINT', async () => {
42 |   console.log('SIGINT received. Shutting down gracefully...');
43 |   // Close database connections
44 |   await falkorDBService.close();
45 |   process.exit(0);
46 | });
47 | 
48 | export default app;
```
--------------------------------------------------------------------------------
/.github/workflows/node.yml:
--------------------------------------------------------------------------------
```yaml
 1 | name: Node.js CI/CD
 2 | 
 3 | on:
 4 |   push:
 5 |     branches: [ main, master, develop ]
 6 |   pull_request:
 7 |     branches: [ main, master ]
 8 | 
 9 | jobs:
10 |   build:
11 |     runs-on: ubuntu-latest
12 | 
13 |     strategy:
14 |       matrix:
15 |         node-version: [16.x, 18.x, 20.x]
16 | 
17 |     steps:
18 |     - uses: actions/checkout@v3
19 |     
20 |     - name: Use Node.js ${{ matrix.node-version }}
21 |       uses: actions/setup-node@v3
22 |       with:
23 |         node-version: ${{ matrix.node-version }}
24 |         cache: 'npm'
25 |         
26 |     - name: Install dependencies
27 |       run: npm ci
28 |       
29 |     - name: Build
30 |       run: npm run build --if-present
31 |       
32 |     - name: Lint
33 |       run: npm run lint --if-present
34 |       
35 |     - name: Test
36 |       run: npm test --if-present
37 |       env:
38 |         CI: true
39 |         
40 |   docker:
41 |     needs: build
42 |     if: github.event_name != 'pull_request'
43 |     runs-on: ubuntu-latest
44 |     
45 |     steps:
46 |     - uses: actions/checkout@v3
47 |     
48 |     - name: Set up Docker Buildx
49 |       uses: docker/setup-buildx-action@v2
50 |       
51 |     - name: Login to GitHub Container Registry
52 |       uses: docker/login-action@v2
53 |       with:
54 |         registry: ghcr.io
55 |         username: ${{ github.repository_owner }}
56 |         password: ${{ secrets.GITHUB_TOKEN }}
57 |         
58 |     - name: Extract metadata for Docker
59 |       id: meta
60 |       uses: docker/metadata-action@v4
61 |       with:
62 |         images: ghcr.io/${{ github.repository }}
63 |         tags: |
64 |           type=sha,format=long
65 |           type=ref,event=branch
66 |           type=ref,event=tag
67 |           
68 |     - name: Build and push Docker image
69 |       uses: docker/build-push-action@v4
70 |       with:
71 |         context: .
72 |         push: true
73 |         tags: ${{ steps.meta.outputs.tags }}
74 |         labels: ${{ steps.meta.outputs.labels }}
```
--------------------------------------------------------------------------------
/src/services/falkordb.service.ts:
--------------------------------------------------------------------------------
```typescript
 1 | import { FalkorDB } from 'falkordb';
 2 | import { config } from '../config';
 3 | 
 4 | class FalkorDBService {
 5 |   private client: FalkorDB | null = null;
 6 | 
 7 |   constructor() {
 8 |     this.init();
 9 |   }
10 | 
11 |   private async init() {
12 |     try {
13 |       this.client = await FalkorDB.connect({
14 |         socket: {
15 |           host: config.falkorDB.host,
16 |           port: config.falkorDB.port,
17 |         },
18 |         password: config.falkorDB.password,
19 |         username: config.falkorDB.username,
20 |       });
21 |       
22 |       // Test connection
23 |       const connection = await this.client.connection;
24 |       await connection.ping();
25 |       console.log('Successfully connected to FalkorDB');
26 |     } catch (error) {
27 |       console.error('Failed to connect to FalkorDB:', error);
28 |       // Retry connection after a delay
29 |       setTimeout(() => this.init(), 5000);
30 |     }
31 |   }
32 | 
33 |   async executeQuery(graphName: string, query: string, params?: Record<string, any>): Promise<any> {
34 |     if (!this.client) {
35 |       throw new Error('FalkorDB client not initialized');
36 |     }
37 |     
38 |     try {
39 |       const graph = this.client.selectGraph(graphName);
40 |       const result = await graph.query(query, params);
41 |       return result;
42 |     } catch (error) {
43 |       const sanitizedGraphName = graphName.replace(/\n|\r/g, "");
44 |       console.error('Error executing FalkorDB query on graph %s:', sanitizedGraphName, error);
45 |       throw error;
46 |     }
47 |   }
48 | 
49 |   /**
50 |    * Lists all available graphs in FalkorDB
51 |    * @returns Array of graph names
52 |    */
53 |   async listGraphs(): Promise<string[]> {
54 |     if (!this.client) {
55 |       throw new Error('FalkorDB client not initialized');
56 |     }
57 | 
58 |     try {
59 |       // Using the simplified list method which always returns an array
60 |       return await this.client.list();
61 |     } catch (error) {
62 |       console.error('Error listing FalkorDB graphs:', error);
63 |       throw error;
64 |     }
65 |   }
66 | 
67 |   async close() {
68 |     if (this.client) {
69 |       await this.client.close();
70 |       this.client = null;
71 |     }
72 |   }
73 | }
74 | 
75 | // Export a singleton instance
76 | export const falkorDBService = new FalkorDBService();
```
--------------------------------------------------------------------------------
/src/utils/connection-parser.ts:
--------------------------------------------------------------------------------
```typescript
 1 | /**
 2 |  * Utility to parse FalkorDB connection strings
 3 |  */
 4 | 
 5 | interface FalkorDBConnectionOptions {
 6 |     host: string;
 7 |     port: number;
 8 |     username?: string;
 9 |     password?: string;
10 |   }
11 |   
12 |   /**
13 |    * Parse a FalkorDB connection string
14 |    * Format: falkordb://[username:password@]host:port
15 |    * 
16 |    * @param connectionString The connection string to parse
17 |    * @returns Parsed connection options
18 |    */
19 |   export function parseFalkorDBConnectionString(connectionString: string): FalkorDBConnectionOptions {
20 |     try {
21 |       // Default values
22 |       const defaultOptions: FalkorDBConnectionOptions = {
23 |         host: 'localhost',
24 |         port: 6379
25 |       };
26 |       
27 |       // Handle empty or undefined input
28 |       if (!connectionString) {
29 |         return defaultOptions;
30 |       }
31 |       
32 |       // Remove protocol prefix if present
33 |       let cleanString = connectionString;
34 |       if (cleanString.startsWith('falkordb://')) {
35 |         cleanString = cleanString.substring('falkordb://'.length);
36 |       }
37 |       
38 |       // Parse authentication if present
39 |       let auth = '';
40 |       let hostPort = cleanString;
41 |       
42 |       if (cleanString.includes('@')) {
43 |         const parts = cleanString.split('@');
44 |         auth = parts[0];
45 |         hostPort = parts[1];
46 |       }
47 |       
48 |       // Parse host and port
49 |       let host = 'localhost';
50 |       let port = 6379;
51 |       
52 |       if (hostPort.includes(':')) {
53 |         const parts = hostPort.split(':');
54 |         host = parts[0] || 'localhost';
55 |         port = parseInt(parts[1], 10) || 6379;
56 |       } else {
57 |         host = hostPort || 'localhost';
58 |       }
59 |       
60 |       // Parse username and password
61 |       let username = undefined;
62 |       let password = undefined;
63 |       
64 |       if (auth && auth.includes(':')) {
65 |         const parts = auth.split(':');
66 |         username = parts[0] || undefined;
67 |         password = parts[1] || undefined;
68 |       } else if (auth) {
69 |         password = auth;
70 |       }
71 |       
72 |       return {
73 |         host,
74 |         port,
75 |         username,
76 |         password
77 |       };
78 |     } catch (error) {
79 |       console.error('Error parsing connection string:', error);
80 |       return {
81 |         host: 'localhost',
82 |         port: 6379
83 |       };
84 |     }
85 |   }
```
--------------------------------------------------------------------------------
/src/controllers/mcp.controller.ts:
--------------------------------------------------------------------------------
```typescript
  1 | import { Request, Response } from 'express';
  2 | import { falkorDBService } from '../services/falkordb.service';
  3 | 
  4 | import { 
  5 |   MCPContextRequest, 
  6 |   MCPResponse, 
  7 |   MCPProviderMetadata 
  8 | } from '../models/mcp.types';
  9 | 
 10 | export class MCPController {
 11 |   /**
 12 |    * Process MCP context requests
 13 |    */
 14 |   async processContextRequest(req: Request, res: Response): Promise<Response<any, Record<string, any>>> {
 15 |     try {
 16 |       const contextRequest: MCPContextRequest = req.body;
 17 |       
 18 |       if (!contextRequest.query) {
 19 |         return res.status(400).json({ error: 'Query is required' });
 20 |       }
 21 |       
 22 |       // Graph name is always required from the client
 23 |       if (!contextRequest.graphName) {
 24 |         return res.status(400).json({ error: 'Graph name is required' });
 25 |       }
 26 |       
 27 |       const startTime = Date.now();
 28 |       
 29 |       // Execute the query on FalkorDB
 30 |       const result = await falkorDBService.executeQuery(
 31 |         contextRequest.graphName,
 32 |         contextRequest.query, 
 33 |         contextRequest.params
 34 |       );
 35 |       
 36 |       const queryTime = Date.now() - startTime;
 37 |       
 38 |       // Format the result according to MCP standards
 39 |       const formattedResult: MCPResponse = {
 40 |         data: result,
 41 |         metadata: {
 42 |           timestamp: new Date().toISOString(),
 43 |           queryTime,
 44 |           provider: 'FalkorDB MCP Server',
 45 |           source: 'falkordb'
 46 |         }
 47 |       };
 48 |       
 49 |       return res.status(200).json(formattedResult);
 50 |     } catch (error: any) {
 51 |       console.error('Error processing MCP context request:', error);
 52 |       return res.status(500).json({ 
 53 |         error: error.message,
 54 |         metadata: {
 55 |           timestamp: new Date().toISOString()
 56 |         }
 57 |       });
 58 |     }
 59 |   }
 60 | 
 61 |   /**
 62 |    * Process MCP metadata requests
 63 |    */
 64 |   async processMetadataRequest(req: Request, res: Response): Promise<Response<any, Record<string, any>>>  {
 65 |     try {
 66 |       // Return metadata about available graphs or capabilities
 67 |       const metadata: MCPProviderMetadata = {
 68 |         provider: 'FalkorDB MCP Server',
 69 |         version: '1.0.0',
 70 |         capabilities: [
 71 |           'graph.query',
 72 |           'graph.list',
 73 |           'node.properties',
 74 |           'relationship.properties'
 75 |         ],
 76 |         graphTypes: ['property', 'directed'],
 77 |         queryLanguages: ['cypher'],
 78 |       };
 79 |       
 80 |       return res.status(200).json(metadata);
 81 |     } catch (error: any) {
 82 |       console.error('Error processing MCP metadata request:', error);
 83 |       return res.status(500).json({ error: error.message });
 84 |     }
 85 |   }
 86 | 
 87 |   /**
 88 |    * List available graphs in FalkorDB
 89 |    */
 90 |   async listGraphs(req: Request, res: Response): Promise<Response<any, Record<string, any>>>  {
 91 |     try {
 92 |       const graphNames = await falkorDBService.listGraphs();
 93 |       
 94 |       // Format the graph list into a more structured response
 95 |       const graphs = graphNames.map(name => ({
 96 |         name,
 97 |         // We don't have additional metadata from just the graph list
 98 |         // If needed, additional queries could be made for each graph
 99 |         // to fetch more detailed information
100 |       }));
101 |       
102 |       return res.status(200).json({
103 |         data: graphs,
104 |         metadata: {
105 |           timestamp: new Date().toISOString(),
106 |           count: graphs.length
107 |         }
108 |       });
109 |     } catch (error: any) {
110 |       console.error('Error listing graphs:', error);
111 |       return res.status(500).json({ error: error.message });
112 |     }
113 |   }
114 | }
115 | 
116 | export const mcpController = new MCPController();
```
--------------------------------------------------------------------------------
/src/controllers/mcp.controller.test.ts:
--------------------------------------------------------------------------------
```typescript
  1 | import { Request, Response } from 'express';
  2 | import { mcpController } from './mcp.controller';
  3 | import { falkorDBService } from '../services/falkordb.service';
  4 | 
  5 | // Mock the falkorDBService
  6 | jest.mock('../services/falkordb.service', () => ({
  7 |   falkorDBService: {
  8 |     executeQuery: jest.fn(),
  9 |     listGraphs: jest.fn()
 10 |   }
 11 | }));
 12 | 
 13 | describe('MCP Controller', () => {
 14 |   let mockRequest: Partial<Request>;
 15 |   let mockResponse: Partial<Response>;
 16 |   let mockJson: jest.Mock;
 17 |   let mockStatus: jest.Mock;
 18 | 
 19 |   beforeEach(() => {
 20 |     // Reset mocks
 21 |     jest.clearAllMocks();
 22 |     
 23 |     // Set up response mock
 24 |     mockJson = jest.fn().mockReturnValue({});
 25 |     mockStatus = jest.fn().mockReturnThis();
 26 |     mockResponse = {
 27 |       json: mockJson,
 28 |       status: mockStatus
 29 |     };
 30 |   });
 31 | 
 32 |   describe('processContextRequest', () => {
 33 |     test('should return 400 if query is missing', async () => {
 34 |       // Arrange
 35 |       mockRequest = {
 36 |         body: {
 37 |           graphName: 'testGraph'
 38 |         }
 39 |       };
 40 | 
 41 |       // Act
 42 |       await mcpController.processContextRequest(
 43 |         mockRequest as Request,
 44 |         mockResponse as Response
 45 |       );
 46 | 
 47 |       // Assert
 48 |       expect(mockStatus).toHaveBeenCalledWith(400);
 49 |       expect(mockJson).toHaveBeenCalledWith({ error: 'Query is required' });
 50 |     });
 51 | 
 52 |     test('should return 400 if graphName is missing', async () => {
 53 |       // Arrange
 54 |       mockRequest = {
 55 |         body: {
 56 |           query: 'MATCH (n) RETURN n'
 57 |         }
 58 |       };
 59 | 
 60 |       // Act
 61 |       await mcpController.processContextRequest(
 62 |         mockRequest as Request,
 63 |         mockResponse as Response
 64 |       );
 65 | 
 66 |       // Assert
 67 |       expect(mockStatus).toHaveBeenCalledWith(400);
 68 |       expect(mockJson).toHaveBeenCalledWith({ error: 'Graph name is required' });
 69 |     });
 70 | 
 71 |     test('should execute query and return results', async () => {
 72 |       // Arrange
 73 |       const mockQueryResult = { records: [{ id: 1, name: 'test' }] };
 74 |       (falkorDBService.executeQuery as jest.Mock).mockResolvedValue(mockQueryResult);
 75 |       
 76 |       mockRequest = {
 77 |         body: {
 78 |           graphName: 'testGraph',
 79 |           query: 'MATCH (n) RETURN n',
 80 |           params: { param1: 'value1' }
 81 |         }
 82 |       };
 83 | 
 84 |       // Act
 85 |       await mcpController.processContextRequest(
 86 |         mockRequest as Request,
 87 |         mockResponse as Response
 88 |       );
 89 | 
 90 |       // Assert
 91 |       expect(falkorDBService.executeQuery).toHaveBeenCalledWith(
 92 |         'testGraph',
 93 |         'MATCH (n) RETURN n',
 94 |         { param1: 'value1' }
 95 |       );
 96 |       expect(mockStatus).toHaveBeenCalledWith(200);
 97 |       expect(mockJson).toHaveBeenCalledWith(expect.objectContaining({
 98 |         data: mockQueryResult,
 99 |         metadata: expect.any(Object)
100 |       }));
101 |     });
102 |   });
103 | 
104 |   describe('listGraphs', () => {
105 |     test('should return list of graphs', async () => {
106 |       // Arrange
107 |       const mockGraphs = ['graph1', 'graph2'];
108 |       (falkorDBService.listGraphs as jest.Mock).mockResolvedValue(mockGraphs);
109 |       
110 |       mockRequest = {};
111 | 
112 |       // Act
113 |       await mcpController.listGraphs(
114 |         mockRequest as Request,
115 |         mockResponse as Response
116 |       );
117 | 
118 |       // Assert
119 |       expect(falkorDBService.listGraphs).toHaveBeenCalled();
120 |       expect(mockStatus).toHaveBeenCalledWith(200);
121 |       expect(mockJson).toHaveBeenCalledWith(expect.objectContaining({
122 |         data: expect.arrayContaining([
123 |           expect.objectContaining({ name: 'graph1' }),
124 |           expect.objectContaining({ name: 'graph2' })
125 |         ]),
126 |         metadata: expect.objectContaining({
127 |           count: 2
128 |         })
129 |       }));
130 |     });
131 |   });
132 | });
```
--------------------------------------------------------------------------------
/src/services/falkordb.service.test.ts:
--------------------------------------------------------------------------------
```typescript
  1 | import { falkorDBService } from './falkordb.service';
  2 | 
  3 | // Mock the FalkorDB library
  4 | jest.mock('falkordb', () => {
  5 |   const mockSelectGraph = jest.fn();
  6 |   const mockQuery = jest.fn();
  7 |   const mockList = jest.fn();
  8 |   const mockClose = jest.fn();
  9 |   const mockPing = jest.fn();
 10 |   
 11 |   return {
 12 |     FalkorDB: {
 13 |       connect: jest.fn().mockResolvedValue({
 14 |         connection: Promise.resolve({
 15 |           ping: mockPing
 16 |         }),
 17 |         selectGraph: mockSelectGraph.mockReturnValue({
 18 |           query: mockQuery
 19 |         }),
 20 |         list: mockList,
 21 |         close: mockClose
 22 |       })
 23 |     },
 24 |     mockSelectGraph,
 25 |     mockQuery,
 26 |     mockList,
 27 |     mockClose,
 28 |     mockPing
 29 |   };
 30 | });
 31 | 
 32 | describe('FalkorDB Service', () => {
 33 |   let mockFalkorDB: any;
 34 |   
 35 |   beforeAll(() => {
 36 |     // Access the mocks
 37 |     mockFalkorDB = require('falkordb');
 38 |   });
 39 |   
 40 |   beforeEach(() => {
 41 |     jest.clearAllMocks();
 42 |   });
 43 |   
 44 |   describe('executeQuery', () => {
 45 |     it('should execute a query on the specified graph', async () => {
 46 |       // Arrange
 47 |       const graphName = 'testGraph';
 48 |       const query = 'MATCH (n) RETURN n';
 49 |       const params = { param1: 'value1' };
 50 |       const expectedResult = { records: [{ id: 1 }] };
 51 |       
 52 |       mockFalkorDB.mockQuery.mockResolvedValue(expectedResult);
 53 |       
 54 |       // Ensure service is initialized (private method, so we need to call a method first)
 55 |       await falkorDBService.executeQuery(graphName, query, params).catch(() => {});
 56 |       
 57 |       // Reset mocks after initialization
 58 |       jest.clearAllMocks();
 59 |       
 60 |       // Force client to be available
 61 |       (falkorDBService as any).client = {
 62 |         selectGraph: mockFalkorDB.mockSelectGraph
 63 |       };
 64 |       
 65 |       // Act
 66 |       const result = await falkorDBService.executeQuery(graphName, query, params);
 67 |       
 68 |       // Assert
 69 |       expect(mockFalkorDB.mockSelectGraph).toHaveBeenCalledWith(graphName);
 70 |       expect(mockFalkorDB.mockQuery).toHaveBeenCalledWith(query, params);
 71 |       expect(result).toEqual(expectedResult);
 72 |     });
 73 |     
 74 |     it('should throw an error if client is not initialized', async () => {
 75 |       // Arrange
 76 |       (falkorDBService as any).client = null;
 77 |       
 78 |       // Act & Assert
 79 |       await expect(falkorDBService.executeQuery('graph', 'query'))
 80 |         .rejects
 81 |         .toThrow('FalkorDB client not initialized');
 82 |     });
 83 |   });
 84 |   
 85 |   describe('listGraphs', () => {
 86 |     it('should return a list of graphs', async () => {
 87 |       // Arrange
 88 |       const expectedGraphs = ['graph1', 'graph2'];
 89 |       mockFalkorDB.mockList.mockResolvedValue(expectedGraphs);
 90 |       
 91 |       // Force client to be available
 92 |       (falkorDBService as any).client = {
 93 |         list: mockFalkorDB.mockList
 94 |       };
 95 |       
 96 |       // Act
 97 |       const result = await falkorDBService.listGraphs();
 98 |       
 99 |       // Assert
100 |       expect(mockFalkorDB.mockList).toHaveBeenCalled();
101 |       expect(result).toEqual(expectedGraphs);
102 |     });
103 |     
104 |     it('should throw an error if client is not initialized', async () => {
105 |       // Arrange
106 |       (falkorDBService as any).client = null;
107 |       
108 |       // Act & Assert
109 |       await expect(falkorDBService.listGraphs())
110 |         .rejects
111 |         .toThrow('FalkorDB client not initialized');
112 |     });
113 |   });
114 |   
115 |   describe('close', () => {
116 |     it('should close the client connection', async () => {
117 |       // Arrange
118 |       (falkorDBService as any).client = {
119 |         close: mockFalkorDB.mockClose
120 |       };
121 |       
122 |       // Act
123 |       await falkorDBService.close();
124 |       
125 |       // Assert
126 |       expect(mockFalkorDB.mockClose).toHaveBeenCalled();
127 |       expect((falkorDBService as any).client).toBeNull();
128 |     });
129 |     
130 |     it('should not throw if client is already null', async () => {
131 |       // Arrange
132 |       (falkorDBService as any).client = null;
133 |       
134 |       // Act & Assert
135 |       await expect(falkorDBService.close()).resolves.not.toThrow();
136 |     });
137 |   });
138 | });
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
  1 | {
  2 |   "compilerOptions": {
  3 |     /* Visit https://aka.ms/tsconfig to read more about this file */
  4 | 
  5 |     /* Projects */
  6 |     // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
  7 |     // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
  8 |     // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
  9 |     // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
 10 |     // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
 11 |     // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */
 12 | 
 13 |     /* Language and Environment */
 14 |     "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
 15 |     // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
 16 |     // "jsx": "preserve",                                /* Specify what JSX code is generated. */
 17 |     // "libReplacement": true,                           /* Enable lib replacement. */
 18 |     // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
 19 |     // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
 20 |     // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
 21 |     // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
 22 |     // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
 23 |     // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
 24 |     // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
 25 |     // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
 26 |     // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */
 27 | 
 28 |     /* Modules */
 29 |     "module": "commonjs",                                /* Specify what module code is generated. */
 30 |     "rootDir": "./src",                                  /* Specify the root folder within your source files. */
 31 |     // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
 32 |     "baseUrl": ".",                                      /* Specify the base directory to resolve non-relative module names. */
 33 |     "paths": {
 34 |       "@/*": ["src/*"]
 35 |     },                                                   /* Specify a set of entries that re-map imports to additional lookup locations. */
 36 |     // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
 37 |     // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
 38 |     // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
 39 |     // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
 40 |     // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
 41 |     // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
 42 |     // "rewriteRelativeImportExtensions": true,          /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
 43 |     // "resolvePackageJsonExports": true,                /* Use the package.json 'exports' field when resolving package imports. */
 44 |     // "resolvePackageJsonImports": true,                /* Use the package.json 'imports' field when resolving imports. */
 45 |     // "customConditions": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
 46 |     // "noUncheckedSideEffectImports": true,             /* Check side effect imports. */
 47 |     "resolveJsonModule": true,                           /* Enable importing .json files. */
 48 |     // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */
 49 |     // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
 50 | 
 51 |     /* JavaScript Support */
 52 |     // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
 53 |     // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
 54 |     // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
 55 | 
 56 |     /* Emit */
 57 |     // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
 58 |     // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
 59 |     // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
 60 |     // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
 61 |     // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
 62 |     // "noEmit": true,                                   /* Disable emitting files from a compilation. */
 63 |     // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
 64 |     "outDir": "./dist",                                   /* Specify an output folder for all emitted files. */
 65 |     // "removeComments": true,                           /* Disable emitting comments. */
 66 |     // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
 67 |     // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
 68 |     // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
 69 |     // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
 70 |     // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
 71 |     // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
 72 |     // "newLine": "crlf",                                /* Set the newline character for emitting files. */
 73 |     // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
 74 |     // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
 75 |     // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
 76 |     // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */
 77 |     // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
 78 | 
 79 |     /* Interop Constraints */
 80 |     // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
 81 |     // "verbatimModuleSyntax": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
 82 |     // "isolatedDeclarations": true,                     /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
 83 |     // "erasableSyntaxOnly": true,                       /* Do not allow runtime constructs that are not part of ECMAScript. */
 84 |     // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
 85 |     "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
 86 |     // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
 87 |     "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */
 88 | 
 89 |     /* Type Checking */
 90 |     "strict": true,                                      /* Enable all strict type-checking options. */
 91 |     // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
 92 |     // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */
 93 |     // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
 94 |     // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
 95 |     // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
 96 |     // "strictBuiltinIteratorReturn": true,              /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
 97 |     // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */
 98 |     // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
 99 |     // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
100 |     // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */
101 |     // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */
102 |     // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
103 |     // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
104 |     // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
105 |     // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */
106 |     // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
107 |     // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
108 |     // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
109 |     // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */
110 | 
111 |     /* Completeness */
112 |     // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
113 |     "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
114 |   },
115 |   "include": ["src/**/*"],
116 |   "exclude": ["node_modules", "dist"]
117 | }
118 | 
```