This is page 7 of 10. Use http://codebase.md/jakedismo/master-mcp-server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .env.example
├── .eslintignore
├── .eslintrc.cjs
├── .eslintrc.js
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .prettierrc.json
├── CHANGELOG.md
├── config
│ ├── default.json
│ ├── development.json
│ ├── production.json
│ └── schema.json
├── config.json
├── CONTRIBUTING.md
├── debug-stdio.cjs
├── debug-stdio.js
├── deploy
│ ├── cloudflare
│ │ ├── .gitkeep
│ │ ├── README.md
│ │ └── wrangler.toml
│ ├── docker
│ │ ├── .gitkeep
│ │ ├── docker-compose.yml
│ │ ├── Dockerfile
│ │ └── entrypoint.sh
│ ├── koyeb
│ │ ├── .gitkeep
│ │ └── koyeb.yaml
│ └── README.md
├── docker-compose.yml
├── Dockerfile
├── docs
│ ├── .DS_Store
│ ├── .vitepress
│ │ ├── cache
│ │ │ └── deps
│ │ │ ├── _metadata.json
│ │ │ ├── chunk-HVR2FF6M.js
│ │ │ ├── chunk-HVR2FF6M.js.map
│ │ │ ├── chunk-P2XGSYO7.js
│ │ │ ├── chunk-P2XGSYO7.js.map
│ │ │ ├── package.json
│ │ │ ├── vitepress___@vue_devtools-api.js
│ │ │ ├── vitepress___@vue_devtools-api.js.map
│ │ │ ├── vitepress___@vueuse_core.js
│ │ │ ├── vitepress___@vueuse_core.js.map
│ │ │ ├── vitepress___@vueuse_integrations_useFocusTrap.js
│ │ │ ├── vitepress___@vueuse_integrations_useFocusTrap.js.map
│ │ │ ├── vitepress___mark__js_src_vanilla__js.js
│ │ │ ├── vitepress___mark__js_src_vanilla__js.js.map
│ │ │ ├── vitepress___minisearch.js
│ │ │ ├── vitepress___minisearch.js.map
│ │ │ ├── vue.js
│ │ │ └── vue.js.map
│ │ ├── config.ts
│ │ ├── dist
│ │ │ ├── 404.html
│ │ │ ├── advanced
│ │ │ │ ├── extensibility.html
│ │ │ │ ├── index.html
│ │ │ │ ├── monitoring.html
│ │ │ │ ├── performance.html
│ │ │ │ └── security.html
│ │ │ ├── api
│ │ │ │ ├── index.html
│ │ │ │ └── README.html
│ │ │ ├── assets
│ │ │ │ ├── advanced_extensibility.md.TrXUn5w5.js
│ │ │ │ ├── advanced_extensibility.md.TrXUn5w5.lean.js
│ │ │ │ ├── advanced_index.md.CPcpUlw_.js
│ │ │ │ ├── advanced_index.md.CPcpUlw_.lean.js
│ │ │ │ ├── advanced_monitoring.md.DTybdNg-.js
│ │ │ │ ├── advanced_monitoring.md.DTybdNg-.lean.js
│ │ │ │ ├── advanced_performance.md.DKmzK0ia.js
│ │ │ │ ├── advanced_performance.md.DKmzK0ia.lean.js
│ │ │ │ ├── advanced_security.md.B-oBD7IB.js
│ │ │ │ ├── advanced_security.md.B-oBD7IB.lean.js
│ │ │ │ ├── api_index.md.Dl1JB08_.js
│ │ │ │ ├── api_index.md.Dl1JB08_.lean.js
│ │ │ │ ├── chunks
│ │ │ │ │ └── framework.CHl2ywxc.js
│ │ │ │ ├── configuration_environment-variables.md.Ddy3P_Wz.js
│ │ │ │ ├── configuration_environment-variables.md.Ddy3P_Wz.lean.js
│ │ │ │ ├── configuration_environment.md.DxcTQ623.js
│ │ │ │ ├── configuration_environment.md.DxcTQ623.lean.js
│ │ │ │ ├── configuration_overview.md.DIkVDv7V.js
│ │ │ │ ├── configuration_overview.md.DIkVDv7V.lean.js
│ │ │ │ ├── configuration_performance.md.DbJdmLrW.js
│ │ │ │ ├── configuration_performance.md.DbJdmLrW.lean.js
│ │ │ │ ├── configuration_reference.md.27IKWqtk.js
│ │ │ │ ├── configuration_reference.md.27IKWqtk.lean.js
│ │ │ │ ├── configuration_security.md.-OOlkzN4.js
│ │ │ │ ├── configuration_security.md.-OOlkzN4.lean.js
│ │ │ │ ├── contributing_dev-setup.md.Ceqh4w-R.js
│ │ │ │ ├── contributing_dev-setup.md.Ceqh4w-R.lean.js
│ │ │ │ ├── contributing_guidelines.md.ZEAX2yVh.js
│ │ │ │ ├── contributing_guidelines.md.ZEAX2yVh.lean.js
│ │ │ │ ├── contributing_index.md.DYq9R6wr.js
│ │ │ │ ├── contributing_index.md.DYq9R6wr.lean.js
│ │ │ │ ├── contributing_maintenance.md.k2bR0IaR.js
│ │ │ │ ├── contributing_maintenance.md.k2bR0IaR.lean.js
│ │ │ │ ├── deployment_cicd.md.Ci2T0UYC.js
│ │ │ │ ├── deployment_cicd.md.Ci2T0UYC.lean.js
│ │ │ │ ├── deployment_cloudflare-workers.md.D2WHsfep.js
│ │ │ │ ├── deployment_cloudflare-workers.md.D2WHsfep.lean.js
│ │ │ │ ├── deployment_docker.md.B8bQDQTo.js
│ │ │ │ ├── deployment_docker.md.B8bQDQTo.lean.js
│ │ │ │ ├── deployment_index.md.ClYeOkpy.js
│ │ │ │ ├── deployment_index.md.ClYeOkpy.lean.js
│ │ │ │ ├── deployment_koyeb.md.B_wJhvF7.js
│ │ │ │ ├── deployment_koyeb.md.B_wJhvF7.lean.js
│ │ │ │ ├── examples_advanced-routing.md.B3CqhLZ7.js
│ │ │ │ ├── examples_advanced-routing.md.B3CqhLZ7.lean.js
│ │ │ │ ├── examples_basic-node.md.CaDZzGlO.js
│ │ │ │ ├── examples_basic-node.md.CaDZzGlO.lean.js
│ │ │ │ ├── examples_cloudflare-worker.md.DwVSz-c7.js
│ │ │ │ ├── examples_cloudflare-worker.md.DwVSz-c7.lean.js
│ │ │ │ ├── examples_index.md.CBF_BLkl.js
│ │ │ │ ├── examples_index.md.CBF_BLkl.lean.js
│ │ │ │ ├── examples_oauth-delegation.md.1hZxoqDl.js
│ │ │ │ ├── examples_oauth-delegation.md.1hZxoqDl.lean.js
│ │ │ │ ├── examples_overview.md.CZN0JbZ7.js
│ │ │ │ ├── examples_overview.md.CZN0JbZ7.lean.js
│ │ │ │ ├── examples_testing.md.Dek4GpNs.js
│ │ │ │ ├── examples_testing.md.Dek4GpNs.lean.js
│ │ │ │ ├── getting-started_concepts.md.D7ON9iGB.js
│ │ │ │ ├── getting-started_concepts.md.D7ON9iGB.lean.js
│ │ │ │ ├── getting-started_installation.md.BKnVqAGg.js
│ │ │ │ ├── getting-started_installation.md.BKnVqAGg.lean.js
│ │ │ │ ├── getting-started_overview.md.DvJDFL2N.js
│ │ │ │ ├── getting-started_overview.md.DvJDFL2N.lean.js
│ │ │ │ ├── getting-started_quickstart-node.md.GOO4aGas.js
│ │ │ │ ├── getting-started_quickstart-node.md.GOO4aGas.lean.js
│ │ │ │ ├── getting-started_quickstart-workers.md.Cpofh8Mj.js
│ │ │ │ ├── getting-started_quickstart-workers.md.Cpofh8Mj.lean.js
│ │ │ │ ├── getting-started.md.DG9ndneo.js
│ │ │ │ ├── getting-started.md.DG9ndneo.lean.js
│ │ │ │ ├── guides_configuration-management.md.B-jwYMbA.js
│ │ │ │ ├── guides_configuration-management.md.B-jwYMbA.lean.js
│ │ │ │ ├── guides_configuration.md.Ci3zYDFA.js
│ │ │ │ ├── guides_configuration.md.Ci3zYDFA.lean.js
│ │ │ │ ├── guides_index.md.CIlq2fmx.js
│ │ │ │ ├── guides_index.md.CIlq2fmx.lean.js
│ │ │ │ ├── guides_module-loading.md.BkJvuRnQ.js
│ │ │ │ ├── guides_module-loading.md.BkJvuRnQ.lean.js
│ │ │ │ ├── guides_oauth-delegation.md.DEOZ-_G0.js
│ │ │ │ ├── guides_oauth-delegation.md.DEOZ-_G0.lean.js
│ │ │ │ ├── guides_request-routing.md.Bdzf0VLg.js
│ │ │ │ ├── guides_request-routing.md.Bdzf0VLg.lean.js
│ │ │ │ ├── guides_testing.md.kYfHqJLu.js
│ │ │ │ ├── guides_testing.md.kYfHqJLu.lean.js
│ │ │ │ ├── inter-italic-cyrillic-ext.r48I6akx.woff2
│ │ │ │ ├── inter-italic-cyrillic.By2_1cv3.woff2
│ │ │ │ ├── inter-italic-greek-ext.1u6EdAuj.woff2
│ │ │ │ ├── inter-italic-greek.DJ8dCoTZ.woff2
│ │ │ │ ├── inter-italic-latin-ext.CN1xVJS-.woff2
│ │ │ │ ├── inter-italic-latin.C2AdPX0b.woff2
│ │ │ │ ├── inter-italic-vietnamese.BSbpV94h.woff2
│ │ │ │ ├── inter-roman-cyrillic-ext.BBPuwvHQ.woff2
│ │ │ │ ├── inter-roman-cyrillic.C5lxZ8CY.woff2
│ │ │ │ ├── inter-roman-greek-ext.CqjqNYQ-.woff2
│ │ │ │ ├── inter-roman-greek.BBVDIX6e.woff2
│ │ │ │ ├── inter-roman-latin-ext.4ZJIpNVo.woff2
│ │ │ │ ├── inter-roman-latin.Di8DUHzh.woff2
│ │ │ │ ├── inter-roman-vietnamese.BjW4sHH5.woff2
│ │ │ │ ├── README.md.BO5r5M9u.js
│ │ │ │ ├── README.md.BO5r5M9u.lean.js
│ │ │ │ ├── style.BQrfSMzK.css
│ │ │ │ ├── troubleshooting_common-issues.md.CScvzWM1.js
│ │ │ │ ├── troubleshooting_common-issues.md.CScvzWM1.lean.js
│ │ │ │ ├── troubleshooting_deployment.md.DUhpqnLE.js
│ │ │ │ ├── troubleshooting_deployment.md.DUhpqnLE.lean.js
│ │ │ │ ├── troubleshooting_errors.md.BSCsEmGc.js
│ │ │ │ ├── troubleshooting_errors.md.BSCsEmGc.lean.js
│ │ │ │ ├── troubleshooting_oauth.md.Cw60Eka3.js
│ │ │ │ ├── troubleshooting_oauth.md.Cw60Eka3.lean.js
│ │ │ │ ├── troubleshooting_performance.md.DxY6LJcT.js
│ │ │ │ ├── troubleshooting_performance.md.DxY6LJcT.lean.js
│ │ │ │ ├── troubleshooting_routing.md.BHN-MDhs.js
│ │ │ │ ├── troubleshooting_routing.md.BHN-MDhs.lean.js
│ │ │ │ ├── troubleshooting_security-best-practices.md.Yiu8E-zt.js
│ │ │ │ ├── troubleshooting_security-best-practices.md.Yiu8E-zt.lean.js
│ │ │ │ ├── tutorials_beginner-getting-started.md.BXObgobW.js
│ │ │ │ ├── tutorials_beginner-getting-started.md.BXObgobW.lean.js
│ │ │ │ ├── tutorials_cloudflare-workers-tutorial.md.MPHsc0aT.js
│ │ │ │ ├── tutorials_cloudflare-workers-tutorial.md.MPHsc0aT.lean.js
│ │ │ │ ├── tutorials_load-balancing-and-resilience.md.Dv9r9jyW.js
│ │ │ │ ├── tutorials_load-balancing-and-resilience.md.Dv9r9jyW.lean.js
│ │ │ │ ├── tutorials_oauth-delegation-github.md.Nq4glqCe.js
│ │ │ │ └── tutorials_oauth-delegation-github.md.Nq4glqCe.lean.js
│ │ │ ├── configuration
│ │ │ │ ├── environment-variables.html
│ │ │ │ ├── environment.html
│ │ │ │ ├── examples.html
│ │ │ │ ├── overview.html
│ │ │ │ ├── performance.html
│ │ │ │ ├── reference.html
│ │ │ │ └── security.html
│ │ │ ├── contributing
│ │ │ │ ├── dev-setup.html
│ │ │ │ ├── guidelines.html
│ │ │ │ ├── index.html
│ │ │ │ └── maintenance.html
│ │ │ ├── deployment
│ │ │ │ ├── cicd.html
│ │ │ │ ├── cloudflare-workers.html
│ │ │ │ ├── docker.html
│ │ │ │ ├── index.html
│ │ │ │ └── koyeb.html
│ │ │ ├── diagrams
│ │ │ │ └── architecture.svg
│ │ │ ├── examples
│ │ │ │ ├── advanced-routing.html
│ │ │ │ ├── basic-node.html
│ │ │ │ ├── cloudflare-worker.html
│ │ │ │ ├── index.html
│ │ │ │ ├── oauth-delegation.html
│ │ │ │ ├── overview.html
│ │ │ │ └── testing.html
│ │ │ ├── getting-started
│ │ │ │ ├── concepts.html
│ │ │ │ ├── installation.html
│ │ │ │ ├── overview.html
│ │ │ │ ├── quick-start.html
│ │ │ │ ├── quickstart-node.html
│ │ │ │ └── quickstart-workers.html
│ │ │ ├── getting-started.html
│ │ │ ├── guides
│ │ │ │ ├── authentication.html
│ │ │ │ ├── client-integration.html
│ │ │ │ ├── configuration-management.html
│ │ │ │ ├── configuration.html
│ │ │ │ ├── index.html
│ │ │ │ ├── module-loading.html
│ │ │ │ ├── oauth-delegation.html
│ │ │ │ ├── request-routing.html
│ │ │ │ ├── server-management.html
│ │ │ │ ├── server-sharing.html
│ │ │ │ └── testing.html
│ │ │ ├── hashmap.json
│ │ │ ├── index.html
│ │ │ ├── logo.svg
│ │ │ ├── README.html
│ │ │ ├── reports
│ │ │ │ └── mcp-compliance-audit.html
│ │ │ ├── troubleshooting
│ │ │ │ ├── common-issues.html
│ │ │ │ ├── deployment.html
│ │ │ │ ├── errors.html
│ │ │ │ ├── index.html
│ │ │ │ ├── oauth.html
│ │ │ │ ├── performance.html
│ │ │ │ ├── routing.html
│ │ │ │ └── security-best-practices.html
│ │ │ ├── tutorials
│ │ │ │ ├── beginner-getting-started.html
│ │ │ │ ├── cloudflare-workers-tutorial.html
│ │ │ │ ├── load-balancing-and-resilience.html
│ │ │ │ └── oauth-delegation-github.html
│ │ │ └── vp-icons.css
│ │ └── theme
│ │ ├── components
│ │ │ ├── ApiPlayground.vue
│ │ │ ├── AuthFlowDemo.vue
│ │ │ ├── CodeTabs.vue
│ │ │ └── ConfigGenerator.vue
│ │ ├── index.ts
│ │ └── style.css
│ ├── advanced
│ │ ├── extensibility.md
│ │ ├── index.md
│ │ ├── monitoring.md
│ │ ├── performance.md
│ │ └── security.md
│ ├── api
│ │ ├── functions
│ │ │ └── createServer.md
│ │ ├── index.md
│ │ ├── interfaces
│ │ │ └── RunningServer.md
│ │ └── README.md
│ ├── architecture
│ │ └── images
│ │ └── mcp_master_architecture.svg
│ ├── configuration
│ │ ├── environment-variables.md
│ │ ├── environment.md
│ │ ├── examples.md
│ │ ├── overview.md
│ │ ├── performance.md
│ │ ├── reference.md
│ │ └── security.md
│ ├── contributing
│ │ ├── dev-setup.md
│ │ ├── guidelines.md
│ │ ├── index.md
│ │ └── maintenance.md
│ ├── deployment
│ │ ├── cicd.md
│ │ ├── cloudflare-workers.md
│ │ ├── docker.md
│ │ ├── docs-site.md
│ │ ├── index.md
│ │ └── koyeb.md
│ ├── examples
│ │ ├── advanced-routing.md
│ │ ├── basic-node.md
│ │ ├── cloudflare-worker.md
│ │ ├── index.md
│ │ ├── oauth-delegation.md
│ │ ├── overview.md
│ │ └── testing.md
│ ├── getting-started
│ │ ├── concepts.md
│ │ ├── installation.md
│ │ ├── overview.md
│ │ ├── quick-start.md
│ │ ├── quickstart-node.md
│ │ └── quickstart-workers.md
│ ├── getting-started.md
│ ├── guides
│ │ ├── authentication.md
│ │ ├── client-integration.md
│ │ ├── configuration-management.md
│ │ ├── configuration.md
│ │ ├── index.md
│ │ ├── module-loading.md
│ │ ├── oauth-delegation.md
│ │ ├── request-routing.md
│ │ ├── server-management.md
│ │ ├── server-sharing.md
│ │ └── testing.md
│ ├── index.html
│ ├── public
│ │ ├── diagrams
│ │ │ └── architecture.svg
│ │ ├── github-social.png
│ │ │ └── image.png
│ │ ├── logo.png
│ │ └── logo.svg
│ ├── README.md
│ ├── stdio-servers.md
│ ├── testing
│ │ └── phase-9-testing-architecture.md
│ ├── troubleshooting
│ │ ├── common-issues.md
│ │ ├── deployment.md
│ │ ├── errors.md
│ │ ├── index.md
│ │ ├── oauth.md
│ │ ├── performance.md
│ │ ├── routing.md
│ │ └── security-best-practices.md
│ └── tutorials
│ ├── beginner-getting-started.md
│ ├── cloudflare-workers-tutorial.md
│ ├── load-balancing-and-resilience.md
│ └── oauth-delegation-github.md
├── examples
│ ├── advanced-routing
│ │ ├── config.yaml
│ │ └── README.md
│ ├── basic-node
│ │ ├── config.yaml
│ │ ├── README.md
│ │ └── server.ts
│ ├── cloudflare-worker
│ │ ├── README.md
│ │ └── worker.ts
│ ├── custom-auth
│ │ ├── config.yaml
│ │ ├── index.ts
│ │ └── README.md
│ ├── multi-server
│ │ ├── config.yaml
│ │ └── README.md
│ ├── oauth-delegation
│ │ └── README.md
│ ├── oauth-node
│ │ ├── config.yaml
│ │ └── README.md
│ ├── performance
│ │ ├── config.yaml
│ │ └── README.md
│ ├── sample-configs
│ │ ├── basic.yaml
│ │ └── simple-setup.yaml
│ ├── security-hardening
│ │ └── README.md
│ ├── stdio-mcp-server.cjs
│ ├── test-mcp-server.js
│ └── test-stdio-server.js
├── LICENSE
├── master-mcp-definition.md
├── package-lock.json
├── package.json
├── README.md
├── reports
│ └── claude_report_20250815_222153.html
├── scripts
│ └── generate-config-docs.ts
├── src
│ ├── auth
│ │ ├── multi-auth-manager.ts
│ │ ├── oauth-providers.ts
│ │ └── token-manager.ts
│ ├── config
│ │ ├── config-loader.ts
│ │ ├── environment-manager.ts
│ │ ├── schema-validator.ts
│ │ └── secret-manager.ts
│ ├── index.ts
│ ├── mcp-server.ts
│ ├── modules
│ │ ├── capability-aggregator.ts
│ │ ├── module-loader.ts
│ │ ├── request-router.ts
│ │ ├── stdio-capability-discovery.ts
│ │ └── stdio-manager.ts
│ ├── oauth
│ │ ├── callback-handler.ts
│ │ ├── flow-controller.ts
│ │ ├── flow-validator.ts
│ │ ├── pkce-manager.ts
│ │ ├── state-manager.ts
│ │ └── web-interface.ts
│ ├── routing
│ │ ├── circuit-breaker.ts
│ │ ├── load-balancer.ts
│ │ ├── retry-handler.ts
│ │ └── route-registry.ts
│ ├── runtime
│ │ ├── node.ts
│ │ └── worker.ts
│ ├── server
│ │ ├── config-manager.ts
│ │ ├── dependency-container.ts
│ │ ├── master-server.ts
│ │ └── protocol-handler.ts
│ ├── types
│ │ ├── auth.ts
│ │ ├── config.ts
│ │ ├── jose-shim.d.ts
│ │ ├── mcp.ts
│ │ └── server.ts
│ └── utils
│ ├── cache.ts
│ ├── crypto.ts
│ ├── dev.ts
│ ├── errors.ts
│ ├── http.ts
│ ├── logger.ts
│ ├── monitoring.ts
│ ├── string.ts
│ ├── time.ts
│ ├── validation.ts
│ └── validators.ts
├── static
│ └── oauth
│ ├── consent.html
│ ├── error.html
│ ├── script.js
│ ├── style.css
│ └── success.html
├── tests
│ ├── _setup
│ │ ├── miniflare.setup.ts
│ │ └── vitest.setup.ts
│ ├── _utils
│ │ ├── log-capture.ts
│ │ ├── mock-fetch.ts
│ │ └── test-server.ts
│ ├── .gitkeep
│ ├── e2e
│ │ ├── flow-controller.express.test.ts
│ │ └── flow-controller.worker.test.ts
│ ├── factories
│ │ ├── configFactory.ts
│ │ ├── mcpFactory.ts
│ │ └── oauthFactory.ts
│ ├── fixtures
│ │ ├── capabilities.json
│ │ └── stdio-server.js
│ ├── integration
│ │ ├── modules.capability-aggregator.test.ts
│ │ ├── modules.module-loader-health.test.ts
│ │ ├── oauth.callback-handler.test.ts
│ │ └── request-router.test.ts
│ ├── mocks
│ │ ├── mcp
│ │ │ └── fake-backend.ts
│ │ └── oauth
│ │ └── mock-oidc-provider.ts
│ ├── perf
│ │ ├── artillery
│ │ │ └── auth-routing.yaml
│ │ └── perf.auth-and-routing.test.ts
│ ├── security
│ │ └── security.oauth-and-input.test.ts
│ ├── servers
│ │ ├── test-auth-simple.js
│ │ ├── test-debug.js
│ │ ├── test-master-mcp.js
│ │ ├── test-mcp-client.js
│ │ ├── test-streaming-both-complete.js
│ │ ├── test-streaming-both-full.js
│ │ ├── test-streaming-both-simple.js
│ │ ├── test-streaming-both.js
│ │ └── test-streaming.js
│ ├── setup
│ │ └── test-setup.ts
│ ├── unit
│ │ ├── auth.multi-auth-manager.test.ts
│ │ ├── auth.token-manager.test.ts
│ │ ├── config.environment-manager.test.ts
│ │ ├── config.schema-validator.test.ts
│ │ ├── config.secret-manager.test.ts
│ │ ├── modules
│ │ │ ├── stdio-capability-discovery.test.ts
│ │ │ └── stdio-manager.test.ts
│ │ ├── modules.route-registry.test.ts
│ │ ├── oauth.pkce-state.test.ts
│ │ ├── routing
│ │ │ └── circuit-breaker.test.ts
│ │ ├── routing.core.test.ts
│ │ ├── stdio-capability-discovery.test.ts
│ │ ├── utils.crypto.test.ts
│ │ ├── utils.logger.test.ts
│ │ └── utils.monitoring.test.ts
│ └── utils
│ ├── fake-express.ts
│ ├── mock-http.ts
│ ├── oauth-mocks.ts
│ └── token-storages.ts
├── tsconfig.base.json
├── tsconfig.json
├── tsconfig.node.json
├── tsconfig.worker.json
├── typedoc.json
├── vitest.config.ts
└── vitest.worker.config.ts
```
# Files
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
```html
1 | <!DOCTYPE html>
2 | <html lang="en">
3 | <head>
4 | <meta charset="UTF-8">
5 | <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 | <title>Master MCP Server - Installation Dashboard</title>
7 | <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
8 | <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
9 | <style>
10 | .step-card {
11 | transition: all 0.3s ease;
12 | border-left: 4px solid #e5e7eb;
13 | }
14 | .step-card.completed {
15 | border-left-color: #10b981;
16 | background-color: #f0fdf4;
17 | }
18 | .step-card.active {
19 | border-left-color: #3b82f6;
20 | background-color: #eff6ff;
21 | }
22 | .copy-btn {
23 | transition: all 0.2s ease;
24 | }
25 | .copy-btn:hover {
26 | transform: scale(1.05);
27 | }
28 | .progress-bar {
29 | transition: width 0.5s ease;
30 | }
31 | .code-block {
32 | background: #1f2937;
33 | color: #f9fafb;
34 | border-radius: 0.5rem;
35 | position: relative;
36 | }
37 | .expandable {
38 | max-height: 0;
39 | overflow: hidden;
40 | transition: max-height 0.3s ease;
41 | }
42 | .expandable.expanded {
43 | max-height: 1000px;
44 | }
45 | .sidebar {
46 | position: fixed;
47 | top: 0;
48 | left: -300px;
49 | width: 300px;
50 | height: 100vh;
51 | background: white;
52 | box-shadow: 2px 0 10px rgba(0,0,0,0.1);
53 | transition: left 0.3s ease;
54 | z-index: 1000;
55 | }
56 | .sidebar.open {
57 | left: 0;
58 | }
59 | .overlay {
60 | position: fixed;
61 | top: 0;
62 | left: 0;
63 | width: 100%;
64 | height: 100%;
65 | background: rgba(0,0,0,0.5);
66 | opacity: 0;
67 | visibility: hidden;
68 | transition: all 0.3s ease;
69 | z-index: 999;
70 | }
71 | .overlay.active {
72 | opacity: 1;
73 | visibility: visible;
74 | }
75 | @media (min-width: 768px) {
76 | .sidebar {
77 | position: fixed;
78 | top: 0;
79 | left: 0;
80 | width: 320px;
81 | height: 100vh;
82 | box-shadow: none;
83 | }
84 | /* Improve anchor scrolling with sticky header */
85 | section { scroll-margin-top: 96px; }
86 | body { margin: 0; }
87 | /* Top tabs styling */
88 | .top-tabs { position: sticky; top: 0; background: #fff; z-index: 40; }
89 | .tab-link { white-space: nowrap; }
90 | .tab-link.active { background: #3b82f6; color: #fff; }
91 |
92 | }
93 | /* Global adjustments for GitHub Pages */
94 | section { scroll-margin-top: 96px; }
95 | body { margin: 0; }
96 | .top-tabs { position: sticky; top: 0; background: #fff; z-index: 40; }
97 | .tab-link { white-space: nowrap; }
98 | .tab-link.active { background: #3b82f6; color: #fff; }
99 |
100 | </style>
101 | </head>
102 | <body class="bg-gray-50 font-sans">
103 | <!-- Mobile Menu Overlay -->
104 | <div class="overlay" id="overlay"></div>
105 |
106 |
107 |
108 | <!-- Main Content -->
109 | <div class="min-h-screen">
110 | <!-- Header -->
111 | <header class="bg-white shadow-sm border-b p-4">
112 | <div class="flex items-center justify-between">
113 | <div class="flex items-center">
114 | <div>
115 | <h1 class="text-2xl font-bold text-gray-800">Master MCP Server</h1>
116 | <p class="text-gray-600">Complete Installation & Setup Guide</p>
117 | </div>
118 | </div>
119 | <div class="flex items-center space-x-4">
120 | <button class="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" id="exportProgress">
121 | <i class="fas fa-download mr-2"></i>Export Progress
122 | </button>
123 | <button class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition-colors" id="resetProgress">
124 | <i class="fas fa-refresh mr-2"></i>Reset Progress
125 | </button>
126 | <a href="https://github.com/your-repo/master-mcp-server" target="_blank" class="text-gray-600 hover:text-gray-800">
127 | <i class="fab fa-github text-xl"></i>
128 | </a>
129 | </div>
130 | </div>
131 | </header>
132 |
133 |
134 |
135 | <!-- Content Area -->
136 | <main class="p-6">
137 | <!-- Welcome Section -->
138 | <div class="bg-gradient-to-r from-blue-500 to-purple-600 text-white p-8 rounded-xl mb-8">
139 | <div class="max-w-4xl">
140 | <h2 class="text-3xl font-bold mb-4">Welcome to Master MCP Server!</h2>
141 | <p class="text-lg mb-6">This interactive guide will walk you through setting up your Master MCP Server - a powerful aggregation server that manages multiple Model Context Protocol servers with advanced authentication, routing, and monitoring capabilities.</p>
142 | <div class="flex flex-wrap gap-4">
143 | <div class="bg-white bg-opacity-20 rounded-lg p-4 flex-1 min-w-48">
144 | <i class="fas fa-shield-alt text-2xl mb-2"></i>
145 | <h3 class="font-semibold">Secure Authentication</h3>
146 | <p class="text-sm opacity-90">OAuth/OIDC with multiple strategies</p>
147 | </div>
148 | <div class="bg-white bg-opacity-20 rounded-lg p-4 flex-1 min-w-48">
149 | <i class="fas fa-route text-2xl mb-2"></i>
150 | <h3 class="font-semibold">Smart Routing</h3>
151 | <p class="text-sm opacity-90">Load balancing & circuit breakers</p>
152 | </div>
153 | <div class="bg-white bg-opacity-20 rounded-lg p-4 flex-1 min-w-48">
154 | <i class="fas fa-chart-line text-2xl mb-2"></i>
155 | <h3 class="font-semibold">Monitoring</h3>
156 | <p class="text-sm opacity-90">Real-time metrics & health checks</p>
157 | </div>
158 | </div>
159 | </div>
160 | </div>
161 |
162 | <!-- Step Content -->
163 | <div class="space-y-8">
164 | <!-- Prerequisites -->
165 | <section id="prerequisites" class="step-card bg-white p-6 rounded-xl shadow-sm">
166 | <div class="flex items-center justify-between mb-4">
167 | <h3 class="text-xl font-semibold flex items-center">
168 | <i class="fas fa-list-check mr-3 text-blue-500"></i>
169 | Step 1: Prerequisites
170 | </h3>
171 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="1">
172 | <i class="fas fa-check mr-2"></i>Mark Complete
173 | </button>
174 | </div>
175 |
176 | <p class="text-gray-600 mb-6">Before we begin, make sure you have the following requirements installed and ready:</p>
177 |
178 | <div class="grid md:grid-cols-2 gap-6">
179 | <div class="space-y-4">
180 | <div class="flex items-start p-4 bg-gray-50 rounded-lg">
181 | <i class="fab fa-node-js text-green-600 text-2xl mr-4 mt-1"></i>
182 | <div>
183 | <h4 class="font-semibold">Node.js 18+</h4>
184 | <p class="text-sm text-gray-600 mb-2">JavaScript runtime for the server</p>
185 | <div class="code-block p-3 text-sm">
186 | <code>node --version</code>
187 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="node --version">
188 | <i class="fas fa-copy"></i>
189 | </button>
190 | </div>
191 | </div>
192 | </div>
193 |
194 | <div class="flex items-start p-4 bg-gray-50 rounded-lg">
195 | <i class="fab fa-npm text-red-600 text-2xl mr-4 mt-1"></i>
196 | <div>
197 | <h4 class="font-semibold">npm or yarn</h4>
198 | <p class="text-sm text-gray-600 mb-2">Package manager for dependencies</p>
199 | <div class="code-block p-3 text-sm">
200 | <code>npm --version</code>
201 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm --version">
202 | <i class="fas fa-copy"></i>
203 | </button>
204 | </div>
205 | </div>
206 | </div>
207 | </div>
208 |
209 | <div class="space-y-4">
210 | <div class="flex items-start p-4 bg-gray-50 rounded-lg">
211 | <i class="fab fa-git-alt text-orange-600 text-2xl mr-4 mt-1"></i>
212 | <div>
213 | <h4 class="font-semibold">Git</h4>
214 | <p class="text-sm text-gray-600 mb-2">Version control for cloning the repository</p>
215 | <div class="code-block p-3 text-sm">
216 | <code>git --version</code>
217 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="git --version">
218 | <i class="fas fa-copy"></i>
219 | </button>
220 | </div>
221 | </div>
222 | </div>
223 |
224 | <div class="flex items-start p-4 bg-gray-50 rounded-lg">
225 | <i class="fab fa-github text-gray-800 text-2xl mr-4 mt-1"></i>
226 | <div>
227 | <h4 class="font-semibold">GitHub Account</h4>
228 | <p class="text-sm text-gray-600 mb-2">Required for OAuth configuration</p>
229 | <a href="https://github.com/signup" target="_blank" class="text-blue-500 hover:text-blue-600 text-sm">Create account →</a>
230 | </div>
231 | </div>
232 | </div>
233 | </div>
234 |
235 | <div class="mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
236 | <h4 class="font-semibold text-blue-800 mb-2">
237 | <i class="fas fa-info-circle mr-2"></i>Optional Tools
238 | </h4>
239 | <ul class="text-sm text-blue-700 space-y-1">
240 | <li>• <strong>Claude Desktop</strong> - For testing the MCP integration</li>
241 | <li>• <strong>VS Code</strong> - Recommended IDE with TypeScript support</li>
242 | <li>• <strong>Docker</strong> - For containerized deployment (optional)</li>
243 | </ul>
244 | </div>
245 | </section>
246 |
247 | <!-- Installation -->
248 | <section id="installation" class="step-card bg-white p-6 rounded-xl shadow-sm">
249 | <div class="flex items-center justify-between mb-4">
250 | <h3 class="text-xl font-semibold flex items-center">
251 | <i class="fas fa-download mr-3 text-blue-500"></i>
252 | Step 2: Installation
253 | </h3>
254 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="2">
255 | <i class="fas fa-check mr-2"></i>Mark Complete
256 | </button>
257 | </div>
258 |
259 | <p class="text-gray-600 mb-6">Let's clone the repository and install all dependencies:</p>
260 |
261 | <div class="space-y-6">
262 | <div>
263 | <h4 class="font-semibold mb-3">1. Clone the Repository</h4>
264 | <div class="code-block p-4 relative">
265 | <pre><code>git clone https://github.com/your-repo/master-mcp-server.git
266 | cd master-mcp-server</code></pre>
267 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="git clone https://github.com/your-repo/master-mcp-server.git
268 | cd master-mcp-server">
269 | <i class="fas fa-copy"></i>
270 | </button>
271 | </div>
272 | </div>
273 |
274 | <div>
275 | <h4 class="font-semibold mb-3">2. Install Dependencies</h4>
276 | <div class="code-block p-4 relative">
277 | <pre><code>npm install</code></pre>
278 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm install">
279 | <i class="fas fa-copy"></i>
280 | </button>
281 | </div>
282 | <p class="text-sm text-gray-600 mt-2">This will install all required dependencies including TypeScript, testing tools, and documentation packages.</p>
283 | </div>
284 |
285 | <div>
286 | <h4 class="font-semibold mb-3">3. Build the Project</h4>
287 | <div class="code-block p-4 relative">
288 | <pre><code>npm run build</code></pre>
289 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm run build">
290 | <i class="fas fa-copy"></i>
291 | </button>
292 | </div>
293 | <p class="text-sm text-gray-600 mt-2">Compiles TypeScript and prepares the application for running.</p>
294 | </div>
295 |
296 | <div>
297 | <h4 class="font-semibold mb-3">4. Verify Installation</h4>
298 | <div class="code-block p-4 relative">
299 | <pre><code>npm test</code></pre>
300 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm test">
301 | <i class="fas fa-copy"></i>
302 | </button>
303 | </div>
304 | <p class="text-sm text-gray-600 mt-2">Runs the test suite to ensure everything is working correctly.</p>
305 | </div>
306 | </div>
307 |
308 | <div class="mt-6 p-4 bg-green-50 border border-green-200 rounded-lg">
309 | <h4 class="font-semibold text-green-800 mb-2">
310 | <i class="fas fa-check-circle mr-2"></i>Success Indicators
311 | </h4>
312 | <ul class="text-sm text-green-700 space-y-1">
313 | <li>• No error messages during npm install</li>
314 | <li>• Build completes without TypeScript errors</li>
315 | <li>• All tests pass successfully</li>
316 | <li>• Dependencies listed in package.json are installed</li>
317 | </ul>
318 | </div>
319 | </section>
320 |
321 | <!-- Documentation -->
322 | <section id="documentation" class="step-card bg-white p-6 rounded-xl shadow-sm">
323 | <div class="flex items-center justify-between mb-4">
324 | <h3 class="text-xl font-semibold flex items-center">
325 | <i class="fas fa-book mr-3 text-blue-500"></i>
326 | Step 3: Documentation Setup
327 | </h3>
328 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="3">
329 | <i class="fas fa-check mr-2"></i>Mark Complete
330 | </button>
331 | </div>
332 |
333 | <p class="text-gray-600 mb-6">Set up the beautiful VitePress documentation site to explore API references and usage guides:</p>
334 |
335 | <div class="space-y-6">
336 | <div>
337 | <h4 class="font-semibold mb-3">1. Install Documentation Dependencies</h4>
338 | <div class="code-block p-4 relative">
339 | <pre><code>npm run docs:install</code></pre>
340 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm run docs:install">
341 | <i class="fas fa-copy"></i>
342 | </button>
343 | </div>
344 | <p class="text-sm text-gray-600 mt-2">Installs VitePress and related documentation tools.</p>
345 | </div>
346 |
347 | <div>
348 | <h4 class="font-semibold mb-3">2. Generate API Documentation</h4>
349 | <div class="code-block p-4 relative">
350 | <pre><code>npm run docs:generate</code></pre>
351 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm run docs:generate">
352 | <i class="fas fa-copy"></i>
353 | </button>
354 | </div>
355 | <p class="text-sm text-gray-600 mt-2">Generates TypeScript API documentation from your source code.</p>
356 | </div>
357 |
358 | <div>
359 | <h4 class="font-semibold mb-3">3. Start Documentation Server</h4>
360 | <div class="code-block p-4 relative">
361 | <pre><code>npm run docs:dev</code></pre>
362 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm run docs:dev">
363 | <i class="fas fa-copy"></i>
364 | </button>
365 | </div>
366 | <p class="text-sm text-gray-600 mt-2">Starts the documentation server on <strong>http://localhost:5173</strong></p>
367 | </div>
368 |
369 | <div>
370 | <h4 class="font-semibold mb-3">4. Explore the Documentation</h4>
371 | <div class="grid md:grid-cols-2 gap-4">
372 | <div class="p-4 bg-gray-50 rounded-lg">
373 | <h5 class="font-semibold text-sm mb-2">📚 Available Sections</h5>
374 | <ul class="text-sm text-gray-600 space-y-1">
375 | <li>• Getting Started Guide</li>
376 | <li>• API Reference</li>
377 | <li>• Configuration Options</li>
378 | <li>• Authentication Strategies</li>
379 | <li>• Deployment Guides</li>
380 | </ul>
381 | </div>
382 | <div class="p-4 bg-blue-50 rounded-lg">
383 | <h5 class="font-semibold text-sm mb-2">🔗 Quick Access</h5>
384 | <div class="space-y-2">
385 | <a href="http://localhost:5173" target="_blank" class="block text-blue-600 hover:text-blue-800 text-sm">
386 | <i class="fas fa-external-link-alt mr-1"></i>Open Documentation
387 | </a>
388 | <a href="http://localhost:5173/api/" target="_blank" class="block text-blue-600 hover:text-blue-800 text-sm">
389 | <i class="fas fa-code mr-1"></i>API Reference
390 | </a>
391 | </div>
392 | </div>
393 | </div>
394 | </div>
395 | </div>
396 | </section>
397 |
398 | <!-- GitHub OAuth Configuration -->
399 | <section id="oauth-config" class="step-card bg-white p-6 rounded-xl shadow-sm">
400 | <div class="flex items-center justify-between mb-4">
401 | <h3 class="text-xl font-semibold flex items-center">
402 | <i class="fas fa-key mr-3 text-blue-500"></i>
403 | Step 4: GitHub OAuth Configuration
404 | </h3>
405 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="4">
406 | <i class="fas fa-check mr-2"></i>Mark Complete
407 | </button>
408 | </div>
409 |
410 | <p class="text-gray-600 mb-6">Set up GitHub OAuth for secure authentication with your Master MCP Server:</p>
411 |
412 | <div class="space-y-6">
413 | <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
414 | <h4 class="font-semibold text-yellow-800 mb-2">
415 | <i class="fas fa-exclamation-triangle mr-2"></i>Important Security Note
416 | </h4>
417 | <p class="text-sm text-yellow-700">Never commit your client secret to version control. Store it securely as an environment variable.</p>
418 | </div>
419 |
420 | <div>
421 | <h4 class="font-semibold mb-3">1. Create GitHub OAuth App</h4>
422 | <ol class="space-y-3 text-sm text-gray-600">
423 | <li class="flex items-start">
424 | <span class="bg-blue-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs mr-3 mt-0.5">1</span>
425 | <div>
426 | <p>Go to <a href="https://github.com/settings/developers" target="_blank" class="text-blue-600 hover:text-blue-800">GitHub Developer Settings</a></p>
427 | </div>
428 | </li>
429 | <li class="flex items-start">
430 | <span class="bg-blue-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs mr-3 mt-0.5">2</span>
431 | <div>
432 | <p>Click <strong>"New OAuth App"</strong></p>
433 | </div>
434 | </li>
435 | <li class="flex items-start">
436 | <span class="bg-blue-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs mr-3 mt-0.5">3</span>
437 | <div>
438 | <p>Fill in the application details:</p>
439 | <div class="mt-2 p-3 bg-gray-50 rounded">
440 | <div class="space-y-2 text-xs">
441 | <div><strong>Application name:</strong> Master MCP Server</div>
442 | <div><strong>Homepage URL:</strong> http://localhost:3005</div>
443 | <div><strong>Authorization callback URL:</strong> http://localhost:3005/oauth/callback</div>
444 | </div>
445 | </div>
446 | </div>
447 | </li>
448 | <li class="flex items-start">
449 | <span class="bg-blue-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs mr-3 mt-0.5">4</span>
450 | <div>
451 | <p>Copy your <strong>Client ID</strong> and generate a <strong>Client Secret</strong></p>
452 | </div>
453 | </li>
454 | </ol>
455 | </div>
456 |
457 | <div>
458 | <h4 class="font-semibold mb-3">2. Configure Environment Variables</h4>
459 | <p class="text-sm text-gray-600 mb-3">Create a <code>.env</code> file in your project root:</p>
460 | <div class="code-block p-4 relative">
461 | <pre><code># GitHub OAuth Configuration
462 | GITHUB_CLIENT_ID=your_client_id_here
463 | GITHUB_CLIENT_SECRET=your_client_secret_here
464 |
465 | # Server Configuration
466 | PORT=3005
467 | BASE_URL=http://localhost:3005</code></pre>
468 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="# GitHub OAuth Configuration
469 | GITHUB_CLIENT_ID=your_client_id_here
470 | GITHUB_CLIENT_SECRET=your_client_secret_here
471 |
472 | # Server Configuration
473 | PORT=3005
474 | BASE_URL=http://localhost:3005">
475 | <i class="fas fa-copy"></i>
476 | </button>
477 | </div>
478 | </div>
479 |
480 | <div>
481 | <h4 class="font-semibold mb-3">3. Update Configuration File</h4>
482 | <p class="text-sm text-gray-600 mb-3">Your <code>config.json</code> should look like this:</p>
483 | <div class="code-block p-4 relative">
484 | <pre><code>{
485 | "hosting": {
486 | "platform": "node",
487 | "port": 3005,
488 | "base_url": "http://localhost:3005"
489 | },
490 | "master_oauth": {
491 | "authorization_endpoint": "https://github.com/login/oauth/authorize",
492 | "token_endpoint": "https://github.com/login/oauth/access_token",
493 | "client_id": "your_client_id_here",
494 | "client_secret": "your_client_secret_here",
495 | "redirect_uri": "http://localhost:3005/oauth/callback",
496 | "scopes": ["read:user", "user:email"]
497 | },
498 | "servers": []
499 | }</code></pre>
500 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy='{
501 | "hosting": {
502 | "platform": "node",
503 | "port": 3005,
504 | "base_url": "http://localhost:3005"
505 | },
506 | "master_oauth": {
507 | "authorization_endpoint": "https://github.com/login/oauth/authorize",
508 | "token_endpoint": "https://github.com/login/oauth/access_token",
509 | "client_id": "your_client_id_here",
510 | "client_secret": "your_client_secret_here",
511 | "redirect_uri": "http://localhost:3005/oauth/callback",
512 | "scopes": ["read:user", "user:email"]
513 | },
514 | "servers": []
515 | }'>
516 | <i class="fas fa-copy"></i>
517 | </button>
518 | </div>
519 | </div>
520 | </div>
521 | </section>
522 |
523 | <!-- Server Configuration -->
524 | <section id="server-config" class="step-card bg-white p-6 rounded-xl shadow-sm">
525 | <div class="flex items-center justify-between mb-4">
526 | <h3 class="text-xl font-semibold flex items-center">
527 | <i class="fas fa-cog mr-3 text-blue-500"></i>
528 | Step 5: Server Configuration
529 | </h3>
530 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="5">
531 | <i class="fas fa-check mr-2"></i>Mark Complete
532 | </button>
533 | </div>
534 |
535 | <p class="text-gray-600 mb-6">Configure your Master MCP Server with the proper settings and security:</p>
536 |
537 | <div class="space-y-6">
538 | <div>
539 | <h4 class="font-semibold mb-3">Configuration Options</h4>
540 | <div class="grid md:grid-cols-2 gap-6">
541 | <div class="space-y-4">
542 | <div class="p-4 bg-gray-50 rounded-lg">
543 | <h5 class="font-semibold text-sm mb-2">🏠 Hosting Configuration</h5>
544 | <ul class="text-xs text-gray-600 space-y-1">
545 | <li><strong>platform:</strong> node | cloudflare-workers | koyeb | docker</li>
546 | <li><strong>port:</strong> Server port (default: 3000)</li>
547 | <li><strong>base_url:</strong> Public URL for callbacks</li>
548 | </ul>
549 | </div>
550 |
551 | <div class="p-4 bg-gray-50 rounded-lg">
552 | <h5 class="font-semibold text-sm mb-2">🔐 Authentication</h5>
553 | <ul class="text-xs text-gray-600 space-y-1">
554 | <li><strong>authorization_endpoint:</strong> OAuth auth URL</li>
555 | <li><strong>token_endpoint:</strong> OAuth token URL</li>
556 | <li><strong>scopes:</strong> Requested permissions</li>
557 | </ul>
558 | </div>
559 | </div>
560 |
561 | <div class="space-y-4">
562 | <div class="p-4 bg-blue-50 rounded-lg">
563 | <h5 class="font-semibold text-sm mb-2">⚡ Advanced Features</h5>
564 | <ul class="text-xs text-gray-600 space-y-1">
565 | <li><strong>Load Balancing:</strong> round_robin | weighted | health</li>
566 | <li><strong>Circuit Breaker:</strong> Failure protection</li>
567 | <li><strong>Retry Policies:</strong> Automatic retry logic</li>
568 | </ul>
569 | </div>
570 |
571 | <div class="p-4 bg-green-50 rounded-lg">
572 | <h5 class="font-semibold text-sm mb-2">📊 Monitoring</h5>
573 | <ul class="text-xs text-gray-600 space-y-1">
574 | <li><strong>Health Checks:</strong> Server status monitoring</li>
575 | <li><strong>Metrics:</strong> Performance tracking</li>
576 | <li><strong>Logging:</strong> debug | info | warn | error</li>
577 | </ul>
578 | </div>
579 | </div>
580 | </div>
581 | </div>
582 |
583 | <div>
584 | <h4 class="font-semibold mb-3">Environment-Based Configuration</h4>
585 | <p class="text-sm text-gray-600 mb-3">You can override config values using environment variables:</p>
586 | <div class="code-block p-4 relative">
587 | <pre><code># Override hosting settings
588 | MASTER_MCP_HOSTING_PORT=3005
589 | MASTER_MCP_HOSTING_BASE_URL=http://localhost:3005
590 |
591 | # Override OAuth settings
592 | MASTER_MCP_MASTER_OAUTH_CLIENT_ID=your_client_id
593 | MASTER_MCP_MASTER_OAUTH_CLIENT_SECRET=your_secret
594 |
595 | # Logging level
596 | MASTER_MCP_LOGGING_LEVEL=debug</code></pre>
597 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="# Override hosting settings
598 | MASTER_MCP_HOSTING_PORT=3005
599 | MASTER_MCP_HOSTING_BASE_URL=http://localhost:3005
600 |
601 | # Override OAuth settings
602 | MASTER_MCP_MASTER_OAUTH_CLIENT_ID=your_client_id
603 | MASTER_MCP_MASTER_OAUTH_CLIENT_SECRET=your_secret
604 |
605 | # Logging level
606 | MASTER_MCP_LOGGING_LEVEL=debug">
607 | <i class="fas fa-copy"></i>
608 | </button>
609 | </div>
610 | </div>
611 |
612 | <div>
613 | <h4 class="font-semibold mb-3">Validate Configuration</h4>
614 | <div class="code-block p-4 relative">
615 | <pre><code>npm run config:validate</code></pre>
616 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="npm run config:validate">
617 | <i class="fas fa-copy"></i>
618 | </button>
619 | </div>
620 | <p class="text-sm text-gray-600 mt-2">Validates your configuration against the JSON schema.</p>
621 | </div>
622 | </div>
623 | </section>
624 |
625 | <!-- Server Startup -->
626 | <section id="server-startup" class="step-card bg-white p-6 rounded-xl shadow-sm">
627 | <div class="flex items-center justify-between mb-4">
628 | <h3 class="text-xl font-semibold flex items-center">
629 | <i class="fas fa-play mr-3 text-blue-500"></i>
630 | Step 6: Server Startup & Testing
631 | </h3>
632 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="6">
633 | <i class="fas fa-check mr-2"></i>Mark Complete
634 | </button>
635 | </div>
636 |
637 | <p class="text-gray-600 mb-6">Start your Master MCP Server and verify it's working correctly:</p>
638 |
639 | <div class="space-y-6">
640 | <div>
641 | <h4 class="font-semibold mb-3">1. Start the Server</h4>
642 | <div class="grid md:grid-cols-2 gap-4">
643 | <div>
644 | <h5 class="text-sm font-semibold mb-2">Development Mode</h5>
645 | <div class="code-block p-3 relative">
646 | <pre><code>npm run dev</code></pre>
647 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="npm run dev">
648 | <i class="fas fa-copy"></i>
649 | </button>
650 | </div>
651 | <p class="text-xs text-gray-600 mt-1">Auto-reloads on file changes</p>
652 | </div>
653 | <div>
654 | <h5 class="text-sm font-semibold mb-2">Production Mode</h5>
655 | <div class="code-block p-3 relative">
656 | <pre><code>npm start</code></pre>
657 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="npm start">
658 | <i class="fas fa-copy"></i>
659 | </button>
660 | </div>
661 | <p class="text-xs text-gray-600 mt-1">Optimized for production</p>
662 | </div>
663 | </div>
664 | </div>
665 |
666 | <div>
667 | <h4 class="font-semibold mb-3">2. Verify Server Status</h4>
668 | <div class="space-y-3">
669 | <div>
670 | <h5 class="text-sm font-semibold mb-2">Health Check</h5>
671 | <div class="flex items-center space-x-4">
672 | <div class="code-block p-3 flex-1 relative">
673 | <code>curl http://localhost:3005/health</code>
674 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="curl http://localhost:3005/health">
675 | <i class="fas fa-copy"></i>
676 | </button>
677 | </div>
678 | <a href="http://localhost:3005/health" target="_blank" class="bg-blue-500 text-white px-3 py-2 rounded text-sm hover:bg-blue-600">
679 | <i class="fas fa-external-link-alt mr-1"></i>Test
680 | </a>
681 | </div>
682 | </div>
683 |
684 | <div>
685 | <h5 class="text-sm font-semibold mb-2">OAuth Endpoints</h5>
686 | <div class="flex items-center space-x-4">
687 | <div class="code-block p-3 flex-1 relative">
688 | <code>curl http://localhost:3005/oauth/authorize</code>
689 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="curl http://localhost:3005/oauth/authorize">
690 | <i class="fas fa-copy"></i>
691 | </button>
692 | </div>
693 | <a href="http://localhost:3005/oauth/authorize" target="_blank" class="bg-blue-500 text-white px-3 py-2 rounded text-sm hover:bg-blue-600">
694 | <i class="fas fa-external-link-alt mr-1"></i>Test
695 | </a>
696 | </div>
697 | </div>
698 |
699 | <div>
700 | <h5 class="text-sm font-semibold mb-2">Server Info</h5>
701 | <div class="flex items-center space-x-4">
702 | <div class="code-block p-3 flex-1 relative">
703 | <code>curl http://localhost:3005/info</code>
704 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="curl http://localhost:3005/info">
705 | <i class="fas fa-copy"></i>
706 | </button>
707 | </div>
708 | <a href="http://localhost:3005/info" target="_blank" class="bg-blue-500 text-white px-3 py-2 rounded text-sm hover:bg-blue-600">
709 | <i class="fas fa-external-link-alt mr-1"></i>Test
710 | </a>
711 | </div>
712 | </div>
713 | </div>
714 | </div>
715 |
716 | <div>
717 | <h4 class="font-semibold mb-3">3. Expected Server Output</h4>
718 | <div class="code-block p-4">
719 | <pre class="text-sm"><code>🚀 Master MCP Server starting...
720 | 📋 Configuration loaded: 0 servers, platform: node
721 | 🔐 OAuth configured: GitHub (scopes: read:user, user:email)
722 | 🌐 Server listening on http://localhost:3005
723 | ✅ Health check endpoint: http://localhost:3005/health
724 | 🔑 OAuth authorize: http://localhost:3005/oauth/authorize
725 | 📊 Server info: http://localhost:3005/info</code></pre>
726 | </div>
727 | </div>
728 |
729 | <div class="bg-green-50 border border-green-200 rounded-lg p-4">
730 | <h4 class="font-semibold text-green-800 mb-2">
731 | <i class="fas fa-check-circle mr-2"></i>Success Indicators
732 | </h4>
733 | <ul class="text-sm text-green-700 space-y-1">
734 | <li>• Server starts without errors</li>
735 | <li>• Health endpoint returns status 200</li>
736 | <li>• OAuth authorization redirects to GitHub</li>
737 | <li>• Server info shows correct configuration</li>
738 | <li>• No configuration validation errors</li>
739 | </ul>
740 | </div>
741 | </div>
742 | </section>
743 |
744 | <!-- Claude Desktop Integration -->
745 | <section id="claude-integration" class="step-card bg-white p-6 rounded-xl shadow-sm">
746 | <div class="flex items-center justify-between mb-4">
747 | <h3 class="text-xl font-semibold flex items-center">
748 | <i class="fas fa-robot mr-3 text-blue-500"></i>
749 | Step 7: Claude Desktop Integration
750 | </h3>
751 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="7">
752 | <i class="fas fa-check mr-2"></i>Mark Complete
753 | </button>
754 | </div>
755 |
756 | <p class="text-gray-600 mb-6">Connect your Master MCP Server to Claude Desktop for seamless AI interactions:</p>
757 |
758 | <div class="space-y-6">
759 | <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
760 | <h4 class="font-semibold text-blue-800 mb-2">
761 | <i class="fas fa-info-circle mr-2"></i>What is Claude Desktop?
762 | </h4>
763 | <p class="text-sm text-blue-700">Claude Desktop is a desktop application that allows you to interact with Claude AI while having access to your local files, tools, and MCP servers for enhanced functionality.</p>
764 | </div>
765 |
766 | <div>
767 | <h4 class="font-semibold mb-3">1. Install Claude Desktop</h4>
768 | <div class="grid md:grid-cols-2 gap-4">
769 | <div class="p-4 bg-gray-50 rounded-lg">
770 | <h5 class="font-semibold text-sm mb-2">🍎 macOS</h5>
771 | <a href="https://claude.ai/download" target="_blank" class="text-blue-600 hover:text-blue-800 text-sm">
772 | <i class="fas fa-download mr-1"></i>Download for macOS
773 | </a>
774 | <p class="text-xs text-gray-600 mt-2">Requires macOS 11.0 or later</p>
775 | </div>
776 | <div class="p-4 bg-gray-50 rounded-lg">
777 | <h5 class="font-semibold text-sm mb-2">🪟 Windows</h5>
778 | <a href="https://claude.ai/download" target="_blank" class="text-blue-600 hover:text-blue-800 text-sm">
779 | <i class="fas fa-download mr-1"></i>Download for Windows
780 | </a>
781 | <p class="text-xs text-gray-600 mt-2">Requires Windows 10 or later</p>
782 | </div>
783 | </div>
784 | </div>
785 |
786 | <div>
787 | <h4 class="font-semibold mb-3">2. Configure Claude Desktop</h4>
788 | <p class="text-sm text-gray-600 mb-3">Add your Master MCP Server to Claude Desktop's configuration:</p>
789 |
790 | <div class="space-y-4">
791 | <div>
792 | <h5 class="text-sm font-semibold mb-2">Find Configuration File</h5>
793 | <div class="grid md:grid-cols-2 gap-4">
794 | <div>
795 | <p class="text-xs text-gray-600 mb-2">macOS Location:</p>
796 | <div class="code-block p-3 relative">
797 | <code class="text-xs">~/Library/Application Support/Claude/claude_desktop_config.json</code>
798 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-xs" data-copy="~/Library/Application Support/Claude/claude_desktop_config.json">
799 | <i class="fas fa-copy"></i>
800 | </button>
801 | </div>
802 | </div>
803 | <div>
804 | <p class="text-xs text-gray-600 mb-2">Windows Location:</p>
805 | <div class="code-block p-3 relative">
806 | <code class="text-xs">%APPDATA%\Claude\claude_desktop_config.json</code>
807 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-xs" data-copy="%APPDATA%\Claude\claude_desktop_config.json">
808 | <i class="fas fa-copy"></i>
809 | </button>
810 | </div>
811 | </div>
812 | </div>
813 | </div>
814 |
815 | <div>
816 | <h5 class="text-sm font-semibold mb-2">Configuration Content</h5>
817 | <div class="code-block p-4 relative">
818 | <pre><code>{
819 | "mcpServers": {
820 | "master-mcp-server": {
821 | "command": "node",
822 | "args": [
823 | "path/to/master-mcp-server/dist/index.js"
824 | ],
825 | "env": {
826 | "MASTER_CONFIG_PATH": "path/to/master-mcp-server/config.json"
827 | }
828 | }
829 | }
830 | }</code></pre>
831 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy='{
832 | "mcpServers": {
833 | "master-mcp-server": {
834 | "command": "node",
835 | "args": [
836 | "path/to/master-mcp-server/dist/index.js"
837 | ],
838 | "env": {
839 | "MASTER_CONFIG_PATH": "path/to/master-mcp-server/config.json"
840 | }
841 | }
842 | }
843 | }'>
844 | <i class="fas fa-copy"></i>
845 | </button>
846 | </div>
847 | <p class="text-xs text-gray-600 mt-2">Replace <code>path/to/master-mcp-server</code> with your actual project path</p>
848 | </div>
849 | </div>
850 | </div>
851 |
852 | <div>
853 | <h4 class="font-semibold mb-3">3. Alternative: Direct Protocol Connection</h4>
854 | <p class="text-sm text-gray-600 mb-3">For development or advanced use, connect directly via stdio:</p>
855 | <div class="code-block p-4 relative">
856 | <pre><code>{
857 | "mcpServers": {
858 | "master-mcp-server": {
859 | "command": "npm",
860 | "args": ["run", "mcp"],
861 | "cwd": "path/to/master-mcp-server"
862 | }
863 | }
864 | }</code></pre>
865 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy='{
866 | "mcpServers": {
867 | "master-mcp-server": {
868 | "command": "npm",
869 | "args": ["run", "mcp"],
870 | "cwd": "path/to/master-mcp-server"
871 | }
872 | }
873 | }'>
874 | <i class="fas fa-copy"></i>
875 | </button>
876 | </div>
877 | </div>
878 |
879 | <div>
880 | <h4 class="font-semibold mb-3">4. Test the Integration</h4>
881 | <div class="space-y-3">
882 | <div class="p-4 bg-green-50 rounded-lg">
883 | <h5 class="font-semibold text-green-800 text-sm mb-2">✅ Verification Steps</h5>
884 | <ol class="text-sm text-green-700 space-y-1">
885 | <li>1. Restart Claude Desktop</li>
886 | <li>2. Start a new conversation</li>
887 | <li>3. Look for MCP server connection in the status bar</li>
888 | <li>4. Try using tools and resources from your server</li>
889 | </ol>
890 | </div>
891 |
892 | <div class="p-4 bg-yellow-50 rounded-lg">
893 | <h5 class="font-semibold text-yellow-800 text-sm mb-2">🔧 Troubleshooting</h5>
894 | <ul class="text-sm text-yellow-700 space-y-1">
895 | <li>• Check Claude Desktop logs for connection errors</li>
896 | <li>• Verify file paths are absolute and correct</li>
897 | <li>• Ensure Master MCP Server is built (npm run build)</li>
898 | <li>• Check that config.json exists and is valid</li>
899 | </ul>
900 | </div>
901 | </div>
902 | </div>
903 | </div>
904 | </section>
905 |
906 | <!-- Backend Server Configuration -->
907 | <section id="backend-servers" class="step-card bg-white p-6 rounded-xl shadow-sm">
908 | <div class="flex items-center justify-between mb-4">
909 | <h3 class="text-xl font-semibold flex items-center">
910 | <i class="fas fa-server mr-3 text-blue-500"></i>
911 | Step 8: Adding Backend MCP Servers
912 | </h3>
913 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="8">
914 | <i class="fas fa-check mr-2"></i>Mark Complete
915 | </button>
916 | </div>
917 |
918 | <p class="text-gray-600 mb-6">Configure your Master MCP Server to manage and route to multiple backend MCP servers:</p>
919 |
920 | <div class="space-y-6">
921 | <div class="bg-purple-50 border border-purple-200 rounded-lg p-4">
922 | <h4 class="font-semibold text-purple-800 mb-2">
923 | <i class="fas fa-lightbulb mr-2"></i>Server Aggregation
924 | </h4>
925 | <p class="text-sm text-purple-700">Your Master MCP Server acts as a central hub, aggregating capabilities from multiple backend servers and presenting them as a unified interface to Claude.</p>
926 | </div>
927 |
928 | <div>
929 | <h4 class="font-semibold mb-3">1. Server Configuration Structure</h4>
930 | <p class="text-sm text-gray-600 mb-3">Add servers to your <code>config.json</code> file:</p>
931 | <div class="code-block p-4 relative">
932 | <pre><code>{
933 | "hosting": { /* ... */ },
934 | "master_oauth": { /* ... */ },
935 | "servers": [
936 | {
937 | "id": "filesystem-server",
938 | "type": "npm",
939 | "package": "@modelcontextprotocol/server-filesystem",
940 | "version": "latest",
941 | "auth_strategy": "bypass_auth",
942 | "config": {
943 | "environment": {
944 | "ALLOWED_DIRECTORIES": "/Users/username/Documents"
945 | },
946 | "args": ["--port", "3001"]
947 | }
948 | },
949 | {
950 | "id": "git-server",
951 | "type": "git",
952 | "url": "https://github.com/modelcontextprotocol/server-git.git",
953 | "branch": "main",
954 | "auth_strategy": "master_oauth",
955 | "config": {
956 | "environment": {
957 | "GIT_REPO_PATH": "/path/to/repo"
958 | }
959 | }
960 | }
961 | ]
962 | }</code></pre>
963 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy='{
964 | "hosting": {},
965 | "master_oauth": {},
966 | "servers": [
967 | {
968 | "id": "filesystem-server",
969 | "type": "npm",
970 | "package": "@modelcontextprotocol/server-filesystem",
971 | "version": "latest",
972 | "auth_strategy": "bypass_auth",
973 | "config": {
974 | "environment": {
975 | "ALLOWED_DIRECTORIES": "/Users/username/Documents"
976 | },
977 | "args": ["--port", "3001"]
978 | }
979 | },
980 | {
981 | "id": "git-server",
982 | "type": "git",
983 | "url": "https://github.com/modelcontextprotocol/server-git.git",
984 | "branch": "main",
985 | "auth_strategy": "master_oauth",
986 | "config": {
987 | "environment": {
988 | "GIT_REPO_PATH": "/path/to/repo"
989 | }
990 | }
991 | }
992 | ]
993 | }'>
994 | <i class="fas fa-copy"></i>
995 | </button>
996 | </div>
997 | </div>
998 |
999 | <div>
1000 | <h4 class="font-semibold mb-3">2. Server Types & Sources</h4>
1001 | <div class="grid md:grid-cols-2 gap-6">
1002 | <div class="space-y-4">
1003 | <div class="p-4 bg-blue-50 rounded-lg">
1004 | <h5 class="font-semibold text-sm mb-2">📦 NPM Packages</h5>
1005 | <div class="text-xs space-y-1">
1006 | <div><strong>type:</strong> "npm"</div>
1007 | <div><strong>package:</strong> Package name</div>
1008 | <div><strong>version:</strong> Version or "latest"</div>
1009 | </div>
1010 | <div class="code-block p-2 mt-2 text-xs">
1011 | <code>"package": "@modelcontextprotocol/server-filesystem"</code>
1012 | </div>
1013 | </div>
1014 |
1015 | <div class="p-4 bg-green-50 rounded-lg">
1016 | <h5 class="font-semibold text-sm mb-2">🐙 Git Repositories</h5>
1017 | <div class="text-xs space-y-1">
1018 | <div><strong>type:</strong> "git"</div>
1019 | <div><strong>url:</strong> Repository URL</div>
1020 | <div><strong>branch:</strong> Branch name</div>
1021 | </div>
1022 | <div class="code-block p-2 mt-2 text-xs">
1023 | <code>"url": "https://github.com/user/mcp-server.git"</code>
1024 | </div>
1025 | </div>
1026 | </div>
1027 |
1028 | <div class="space-y-4">
1029 | <div class="p-4 bg-orange-50 rounded-lg">
1030 | <h5 class="font-semibold text-sm mb-2">🐍 Python Packages</h5>
1031 | <div class="text-xs space-y-1">
1032 | <div><strong>type:</strong> "pypi"</div>
1033 | <div><strong>package:</strong> PyPI package name</div>
1034 | <div><strong>version:</strong> Version or "latest"</div>
1035 | </div>
1036 | <div class="code-block p-2 mt-2 text-xs">
1037 | <code>"package": "mcp-server-sqlite"</code>
1038 | </div>
1039 | </div>
1040 |
1041 | <div class="p-4 bg-purple-50 rounded-lg">
1042 | <h5 class="font-semibold text-sm mb-2">📁 Local Servers</h5>
1043 | <div class="text-xs space-y-1">
1044 | <div><strong>type:</strong> "local"</div>
1045 | <div><strong>url:</strong> Local file path</div>
1046 | <div><strong>config:</strong> Local environment</div>
1047 | </div>
1048 | <div class="code-block p-2 mt-2 text-xs">
1049 | <code>"url": "/path/to/local/server"</code>
1050 | </div>
1051 | </div>
1052 | </div>
1053 | </div>
1054 | </div>
1055 |
1056 | <div>
1057 | <h4 class="font-semibold mb-3">3. Authentication Strategies</h4>
1058 | <div class="grid md:grid-cols-2 gap-4">
1059 | <div class="space-y-3">
1060 | <div class="p-3 bg-gray-50 rounded">
1061 | <h5 class="font-semibold text-xs mb-1">🔐 master_oauth</h5>
1062 | <p class="text-xs text-gray-600">Use Master server's OAuth token</p>
1063 | </div>
1064 | <div class="p-3 bg-gray-50 rounded">
1065 | <h5 class="font-semibold text-xs mb-1">🔄 delegate_oauth</h5>
1066 | <p class="text-xs text-gray-600">Backend handles its own OAuth</p>
1067 | </div>
1068 | </div>
1069 | <div class="space-y-3">
1070 | <div class="p-3 bg-gray-50 rounded">
1071 | <h5 class="font-semibold text-xs mb-1">🚫 bypass_auth</h5>
1072 | <p class="text-xs text-gray-600">No authentication required</p>
1073 | </div>
1074 | <div class="p-3 bg-gray-50 rounded">
1075 | <h5 class="font-semibold text-xs mb-1">🔗 proxy_oauth</h5>
1076 | <p class="text-xs text-gray-600">Forward OAuth from client</p>
1077 | </div>
1078 | </div>
1079 | </div>
1080 | </div>
1081 |
1082 | <div>
1083 | <h4 class="font-semibold mb-3">4. Test Server Configuration</h4>
1084 | <div class="space-y-3">
1085 | <div class="code-block p-4 relative">
1086 | <pre><code># Validate configuration
1087 | npm run config:validate
1088 |
1089 | # Test server loading
1090 | npm run test:servers
1091 |
1092 | # Start with verbose logging
1093 | npm run dev -- --log-level debug</code></pre>
1094 | <button class="copy-btn absolute top-2 right-2 text-gray-400 hover:text-white" data-copy="# Validate configuration
1095 | npm run config:validate
1096 |
1097 | # Test server loading
1098 | npm run test:servers
1099 |
1100 | # Start with verbose logging
1101 | npm run dev -- --log-level debug">
1102 | <i class="fas fa-copy"></i>
1103 | </button>
1104 | </div>
1105 |
1106 | <div class="p-4 bg-green-50 border border-green-200 rounded">
1107 | <h5 class="font-semibold text-green-800 text-sm mb-2">Expected Output</h5>
1108 | <div class="text-xs text-green-700 space-y-1">
1109 | <div>• All servers load successfully</div>
1110 | <div>• Health checks pass for each server</div>
1111 | <div>• Capabilities are properly aggregated</div>
1112 | <div>• No authentication or loading errors</div>
1113 | </div>
1114 | </div>
1115 | </div>
1116 | </div>
1117 | </div>
1118 | </section>
1119 |
1120 | <!-- Troubleshooting -->
1121 | <section id="troubleshooting" class="step-card bg-white p-6 rounded-xl shadow-sm">
1122 | <div class="flex items-center justify-between mb-4">
1123 | <h3 class="text-xl font-semibold flex items-center">
1124 | <i class="fas fa-tools mr-3 text-blue-500"></i>
1125 | Step 9: Troubleshooting
1126 | </h3>
1127 | <button class="mark-complete bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors" data-step="9">
1128 | <i class="fas fa-check mr-2"></i>Mark Complete
1129 | </button>
1130 | </div>
1131 |
1132 | <p class="text-gray-600 mb-6">Common issues and their solutions to get your Master MCP Server running smoothly:</p>
1133 |
1134 | <div class="space-y-6">
1135 | <div class="grid md:grid-cols-2 gap-6">
1136 | <div>
1137 | <h4 class="font-semibold mb-3 text-red-600">🚨 Common Issues</h4>
1138 | <div class="space-y-4">
1139 | <div class="border border-red-200 rounded-lg p-4">
1140 | <h5 class="font-semibold text-sm mb-2 text-red-700">Server Won't Start</h5>
1141 | <ul class="text-xs text-red-600 space-y-1">
1142 | <li>• Port already in use (change port in config)</li>
1143 | <li>• Invalid configuration file</li>
1144 | <li>• Missing dependencies</li>
1145 | <li>• TypeScript compilation errors</li>
1146 | </ul>
1147 | </div>
1148 |
1149 | <div class="border border-red-200 rounded-lg p-4">
1150 | <h5 class="font-semibold text-sm mb-2 text-red-700">OAuth Issues</h5>
1151 | <ul class="text-xs text-red-600 space-y-1">
1152 | <li>• Invalid client ID or secret</li>
1153 | <li>• Incorrect redirect URI</li>
1154 | <li>• GitHub app not configured</li>
1155 | <li>• Environment variables not set</li>
1156 | </ul>
1157 | </div>
1158 |
1159 | <div class="border border-red-200 rounded-lg p-4">
1160 | <h5 class="font-semibold text-sm mb-2 text-red-700">Backend Server Loading</h5>
1161 | <ul class="text-xs text-red-600 space-y-1">
1162 | <li>• Server package not found</li>
1163 | <li>• Authentication failures</li>
1164 | <li>• Network connectivity issues</li>
1165 | <li>• Invalid server configuration</li>
1166 | </ul>
1167 | </div>
1168 | </div>
1169 | </div>
1170 |
1171 | <div>
1172 | <h4 class="font-semibold mb-3 text-green-600">✅ Solutions</h4>
1173 | <div class="space-y-4">
1174 | <div class="border border-green-200 rounded-lg p-4">
1175 | <h5 class="font-semibold text-sm mb-2 text-green-700">Server Startup</h5>
1176 | <div class="code-block p-2 mb-2">
1177 | <code class="text-xs"># Check port usage
1178 | lsof -i :3005
1179 |
1180 | # Validate config
1181 | npm run config:validate
1182 |
1183 | # Clean rebuild
1184 | npm run clean && npm run build</code>
1185 | </div>
1186 | </div>
1187 |
1188 | <div class="border border-green-200 rounded-lg p-4">
1189 | <h5 class="font-semibold text-sm mb-2 text-green-700">OAuth Debug</h5>
1190 | <div class="code-block p-2 mb-2">
1191 | <code class="text-xs"># Test OAuth endpoints
1192 | curl http://localhost:3005/oauth/authorize
1193 |
1194 | # Check environment
1195 | echo $GITHUB_CLIENT_ID</code>
1196 | </div>
1197 | </div>
1198 |
1199 | <div class="border border-green-200 rounded-lg p-4">
1200 | <h5 class="font-semibold text-sm mb-2 text-green-700">Server Loading</h5>
1201 | <div class="code-block p-2 mb-2">
1202 | <code class="text-xs"># Test individual servers
1203 | npm run test:servers
1204 |
1205 | # Debug server loading
1206 | npm run dev -- --debug-servers</code>
1207 | </div>
1208 | </div>
1209 | </div>
1210 | </div>
1211 | </div>
1212 |
1213 | <div>
1214 | <h4 class="font-semibold mb-3">Diagnostic Commands</h4>
1215 | <div class="grid md:grid-cols-2 gap-4">
1216 | <div>
1217 | <h5 class="text-sm font-semibold mb-2">Health Checks</h5>
1218 | <div class="code-block p-3 relative">
1219 | <pre><code># Server health
1220 | curl http://localhost:3005/health
1221 |
1222 | # Configuration status
1223 | curl http://localhost:3005/config/status
1224 |
1225 | # Server list
1226 | curl http://localhost:3005/servers</code></pre>
1227 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="# Server health
1228 | curl http://localhost:3005/health
1229 |
1230 | # Configuration status
1231 | curl http://localhost:3005/config/status
1232 |
1233 | # Server list
1234 | curl http://localhost:3005/servers">
1235 | <i class="fas fa-copy"></i>
1236 | </button>
1237 | </div>
1238 | </div>
1239 |
1240 | <div>
1241 | <h5 class="text-sm font-semibold mb-2">Logging & Debug</h5>
1242 | <div class="code-block p-3 relative">
1243 | <pre><code># Enable debug logging
1244 | export MASTER_MCP_LOGGING_LEVEL=debug
1245 |
1246 | # Check logs
1247 | tail -f logs/master-mcp.log
1248 |
1249 | # Verbose startup
1250 | npm run dev -- --verbose</code></pre>
1251 | <button class="copy-btn absolute top-1 right-1 text-gray-400 hover:text-white text-sm" data-copy="# Enable debug logging
1252 | export MASTER_MCP_LOGGING_LEVEL=debug
1253 |
1254 | # Check logs
1255 | tail -f logs/master-mcp.log
1256 |
1257 | # Verbose startup
1258 | npm run dev -- --verbose">
1259 | <i class="fas fa-copy"></i>
1260 | </button>
1261 | </div>
1262 | </div>
1263 | </div>
1264 | </div>
1265 |
1266 | <div>
1267 | <h4 class="font-semibold mb-3">Getting Help</h4>
1268 | <div class="grid md:grid-cols-3 gap-4">
1269 | <div class="p-4 bg-blue-50 rounded-lg text-center">
1270 | <i class="fab fa-github text-2xl text-blue-600 mb-2"></i>
1271 | <h5 class="font-semibold text-sm mb-1">GitHub Issues</h5>
1272 | <a href="https://github.com/your-repo/master-mcp-server/issues" target="_blank" class="text-blue-600 hover:text-blue-800 text-xs">
1273 | Report a bug →
1274 | </a>
1275 | </div>
1276 | <div class="p-4 bg-purple-50 rounded-lg text-center">
1277 | <i class="fas fa-book text-2xl text-purple-600 mb-2"></i>
1278 | <h5 class="font-semibold text-sm mb-1">Documentation</h5>
1279 | <a href="http://localhost:5173" target="_blank" class="text-purple-600 hover:text-purple-800 text-xs">
1280 | Browse docs →
1281 | </a>
1282 | </div>
1283 | <div class="p-4 bg-green-50 rounded-lg text-center">
1284 | <i class="fas fa-comments text-2xl text-green-600 mb-2"></i>
1285 | <h5 class="font-semibold text-sm mb-1">Community</h5>
1286 | <a href="https://discord.gg/mcp" target="_blank" class="text-green-600 hover:text-green-800 text-xs">
1287 | Join Discord →
1288 | </a>
1289 | </div>
1290 | </div>
1291 | </div>
1292 |
1293 | <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
1294 | <h4 class="font-semibold text-yellow-800 mb-2">
1295 | <i class="fas fa-lightbulb mr-2"></i>Pro Tips
1296 | </h4>
1297 | <ul class="text-sm text-yellow-700 space-y-1">
1298 |
1299 | <li>• Always validate configuration before starting the server</li>
1300 | <li>• Use debug logging when troubleshooting issues</li>
1301 | <li>• Test individual servers before adding them to the master config</li>
1302 | <li>• Keep your OAuth secrets secure and never commit them</li>
1303 | <li>• Monitor server health and performance regularly</li>
1304 | </ul>
1305 | </div>
1306 | </div>
1307 | </section>
1308 |
1309 | <!-- Completion Section -->
1310 | <section class="bg-gradient-to-r from-green-500 to-blue-600 text-white p-8 rounded-xl">
1311 | <div class="text-center">
1312 | <i class="fas fa-trophy text-4xl mb-4"></i>
1313 | <h2 class="text-2xl font-bold mb-4">Congratulations! 🎉</h2>
1314 | <p class="text-lg mb-6">You've successfully set up your Master MCP Server! Your server is now ready to aggregate multiple MCP servers and provide seamless AI interactions.</p>
1315 |
1316 | <div class="grid md:grid-cols-3 gap-4 mb-6">
1317 | <div class="bg-white bg-opacity-20 rounded-lg p-4">
1318 | <i class="fas fa-server text-2xl mb-2"></i>
1319 | <h3 class="font-semibold">Server Running</h3>
1320 | <p class="text-sm opacity-90">Your Master MCP Server is active</p>
1321 | </div>
1322 | <div class="bg-white bg-opacity-20 rounded-lg p-4">
1323 | <i class="fas fa-shield-alt text-2xl mb-2"></i>
1324 | <h3 class="font-semibold">OAuth Configured</h3>
1325 | <p class="text-sm opacity-90">Secure authentication is ready</p>
1326 | </div>
1327 | <div class="bg-white bg-opacity-20 rounded-lg p-4">
1328 | <i class="fas fa-robot text-2xl mb-2"></i>
1329 | <h3 class="font-semibold">Claude Connected</h3>
1330 | <p class="text-sm opacity-90">Ready for AI interactions</p>
1331 | </div>
1332 | </div>
1333 |
1334 | <div class="space-y-4">
1335 | <h3 class="text-xl font-semibold">Next Steps</h3>
1336 | <div class="flex flex-wrap justify-center gap-4">
1337 | <a href="http://localhost:3005/health" target="_blank" class="bg-white text-blue-600 px-4 py-2 rounded-lg hover:bg-gray-100 transition-colors">
1338 | <i class="fas fa-heartbeat mr-2"></i>Check Server Health
1339 | </a>
1340 | <a href="http://localhost:5173" target="_blank" class="bg-white text-purple-600 px-4 py-2 rounded-lg hover:bg-gray-100 transition-colors">
1341 | <i class="fas fa-book mr-2"></i>Browse Documentation
1342 | </a>
1343 | <a href="https://github.com/your-repo/master-mcp-server" target="_blank" class="bg-white text-gray-800 px-4 py-2 rounded-lg hover:bg-gray-100 transition-colors">
1344 | <i class="fab fa-github mr-2"></i>View Source Code
1345 | </a>
1346 | </div>
1347 | </div>
1348 | </div>
1349 | </section>
1350 | </div>
1351 | </main>
1352 | </div>
1353 |
1354 | <script>
1355 | // Dashboard functionality
1356 | class InstallationDashboard {
1357 | constructor() {
1358 | this.completedSteps = new Set(this.loadProgress());
1359 | this.totalSteps = 9;
1360 | this.init();
1361 | }
1362 |
1363 | init() {
1364 | this.setupEventListeners();
1365 | this.updateProgress();
1366 | this.setupCopyButtons();
1367 | // Sidebar removed in simplified layout
1368 | this.setupValidationUtils();
1369 | this.setupTestButtons();
1370 | }
1371 |
1372 | setupEventListeners() {
1373 | // Mark complete buttons
1374 | document.querySelectorAll('.mark-complete').forEach(btn => {
1375 | btn.addEventListener('click', (e) => {
1376 | const step = parseInt(e.target.dataset.step);
1377 | this.markStepComplete(step);
1378 | });
1379 | });
1380 |
1381 | // Top tabs: click to scroll and mark active
1382 | document.querySelectorAll('.tab-link').forEach(tab => {
1383 | tab.addEventListener('click', (e) => {
1384 | e.preventDefault();
1385 | const targetSel = tab.getAttribute('href');
1386 | const target = document.querySelector(targetSel);
1387 | if (target) {
1388 | target.scrollIntoView({ behavior: 'smooth' });
1389 | }
1390 | });
1391 | });
1392 |
1393 | // Highlight active tab on scroll
1394 | const sections = Array.from(document.querySelectorAll('main section'));
1395 | const tabs = Array.from(document.querySelectorAll('.tab-link'));
1396 | const io = new IntersectionObserver((entries) => {
1397 | entries.forEach(entry => {
1398 | if (entry.isIntersecting) {
1399 | const id = `#${entry.target.id}`;
1400 | tabs.forEach(t => t.classList.toggle('active', t.getAttribute('href') === id));
1401 | }
1402 | });
1403 | }, { rootMargin: '-60% 0px -35% 0px', threshold: 0.01 });
1404 | sections.forEach(sec => io.observe(sec));
1405 |
1406 | // Reset progress button
1407 | document.getElementById('resetProgress').addEventListener('click', () => {
1408 | this.resetProgress();
1409 | });
1410 |
1411 | // Export progress button
1412 | document.getElementById('exportProgress').addEventListener('click', () => {
1413 | this.exportProgress();
1414 | });
1415 |
1416 | // Navigation links
1417 | document.querySelectorAll('.nav-link').forEach(link => {
1418 | link.addEventListener('click', (e) => {
1419 | e.preventDefault();
1420 | const target = e.currentTarget.getAttribute('href');
1421 | document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
1422 | if (window.innerWidth < 768) {
1423 | this.closeSidebar();
1424 | }
1425 | });
1426 | });
1427 | }
1428 |
1429 | setupCopyButtons() {
1430 | document.querySelectorAll('.copy-btn').forEach(btn => {
1431 | btn.addEventListener('click', async (e) => {
1432 | const text = e.target.dataset.copy || e.target.closest('button').dataset.copy;
1433 | try {
1434 | await navigator.clipboard.writeText(text);
1435 | const icon = btn.querySelector('i');
1436 | icon.className = 'fas fa-check';
1437 | setTimeout(() => {
1438 | icon.className = 'fas fa-copy';
1439 | }, 2000);
1440 | } catch (err) {
1441 | console.error('Failed to copy text: ', err);
1442 | }
1443 | });
1444 | });
1445 | }
1446 |
1447 | // Sidebar methods removed in simplified layout
1448 | setupSidebar() {}
1449 | openSidebar() {}
1450 | closeSidebar() {}
1451 |
1452 | markStepComplete(step) {
1453 | this.completedSteps.add(step);
1454 | this.saveProgress();
1455 | this.updateProgress();
1456 | this.updateStepUI(step);
1457 | }
1458 |
1459 | updateStepUI(step) {
1460 | // Update step card
1461 | const stepCard = document.querySelector(`section[id*="step-${step}"], section:nth-of-type(${step})`);
1462 | if (stepCard) {
1463 | stepCard.classList.add('completed');
1464 | const button = stepCard.querySelector('.mark-complete');
1465 | if (button) {
1466 | button.innerHTML = '<i class="fas fa-check-circle mr-2"></i>Completed';
1467 | button.classList.remove('bg-green-500', 'hover:bg-green-600');
1468 | button.classList.add('bg-gray-500');
1469 | button.disabled = true;
1470 | }
1471 | }
1472 |
1473 | // Update sidebar navigation
1474 | const navLink = document.querySelector(`[data-step="${step}"]`);
1475 | if (navLink) {
1476 | navLink.querySelector('.check-icon').classList.remove('hidden');
1477 | }
1478 | }
1479 |
1480 | updateProgress() {
1481 | const progress = (this.completedSteps.size / this.totalSteps) * 100;
1482 | document.getElementById('progressBar').style.width = `${progress}%`;
1483 | document.getElementById('progressText').textContent = `${this.completedSteps.size}/${this.totalSteps} Steps`;
1484 |
1485 | // Update completed steps UI
1486 | this.completedSteps.forEach(step => this.updateStepUI(step));
1487 | }
1488 |
1489 | resetProgress() {
1490 | if (confirm('Are you sure you want to reset all progress?')) {
1491 | this.completedSteps.clear();
1492 | localStorage.removeItem('installation-progress');
1493 | location.reload();
1494 | }
1495 | }
1496 |
1497 | saveProgress() {
1498 | localStorage.setItem('installation-progress', JSON.stringify([...this.completedSteps]));
1499 | }
1500 |
1501 | loadProgress() {
1502 | const saved = localStorage.getItem('installation-progress');
1503 | return saved ? JSON.parse(saved) : [];
1504 | }
1505 |
1506 | setupValidationUtils() {
1507 | // Add validation indicators to various sections
1508 | this.addValidationIndicators();
1509 | }
1510 |
1511 | setupTestButtons() {
1512 | // Enhance test buttons with actual functionality
1513 | document.querySelectorAll('a[href*="localhost:3005"]').forEach(link => {
1514 | if (link.textContent.includes('Test')) {
1515 | link.addEventListener('click', (e) => {
1516 | e.preventDefault();
1517 | this.testEndpoint(link.href, link);
1518 | });
1519 | }
1520 | });
1521 | }
1522 |
1523 | addValidationIndicators() {
1524 | // Add real-time validation for configuration sections
1525 | const sections = [
1526 | { id: 'prerequisites', validator: this.validatePrerequisites },
1527 | { id: 'installation', validator: this.validateInstallation },
1528 | { id: 'oauth-config', validator: this.validateOAuthConfig },
1529 | { id: 'server-config', validator: this.validateServerConfig }
1530 | ];
1531 |
1532 | sections.forEach(({ id, validator }) => {
1533 | const section = document.getElementById(id);
1534 | if (section) {
1535 | this.addValidationBadge(section, validator.bind(this));
1536 | }
1537 | });
1538 | }
1539 |
1540 | addValidationBadge(section, validator) {
1541 | const header = section.querySelector('h3');
1542 | if (header) {
1543 | const badge = document.createElement('span');
1544 | badge.className = 'validation-badge ml-2 px-2 py-1 text-xs rounded-full bg-gray-200 text-gray-600';
1545 | badge.textContent = 'Validating...';
1546 | header.appendChild(badge);
1547 |
1548 | // Run validation
1549 | setTimeout(() => {
1550 | const isValid = validator();
1551 | badge.className = isValid
1552 | ? 'validation-badge ml-2 px-2 py-1 text-xs rounded-full bg-green-200 text-green-800'
1553 | : 'validation-badge ml-2 px-2 py-1 text-xs rounded-full bg-yellow-200 text-yellow-800';
1554 | badge.textContent = isValid ? 'Ready' : 'Check setup';
1555 | }, 1000);
1556 | }
1557 | }
1558 |
1559 | validatePrerequisites() {
1560 | // Simple validation - check if common tools might be available
1561 | return true; // Assume prerequisites are met for demo
1562 | }
1563 |
1564 | validateInstallation() {
1565 | // Check if we're likely in a Node.js project directory
1566 | return window.location.protocol === 'file:' || window.location.hostname === 'localhost';
1567 | }
1568 |
1569 | validateOAuthConfig() {
1570 | // Basic validation for OAuth configuration
1571 | return document.querySelector('code')?.textContent?.includes('github.com');
1572 | }
1573 |
1574 | validateServerConfig() {
1575 | // Check if configuration examples are visible
1576 | return document.querySelector('code')?.textContent?.includes('config.json');
1577 | }
1578 |
1579 | async testEndpoint(url, button) {
1580 | const originalText = button.innerHTML;
1581 | button.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Testing...';
1582 | button.classList.add('opacity-50', 'pointer-events-none');
1583 |
1584 | try {
1585 | const response = await fetch(url, {
1586 | method: 'GET',
1587 | mode: 'no-cors' // Handle CORS issues
1588 | });
1589 |
1590 | // Since we're using no-cors, we can't read the response
1591 | // But we can detect if the request went through
1592 | this.showTestResult(button, 'success', 'Connection successful!');
1593 | } catch (error) {
1594 | // Check if it's a network error or CORS issue
1595 | if (error.message.includes('Failed to fetch')) {
1596 | this.showTestResult(button, 'warning', 'Server might be down. Check if it\'s running.');
1597 | } else {
1598 | this.showTestResult(button, 'error', 'Connection failed: ' + error.message);
1599 | }
1600 | } finally {
1601 | setTimeout(() => {
1602 | button.innerHTML = originalText;
1603 | button.classList.remove('opacity-50', 'pointer-events-none');
1604 | }, 3000);
1605 | }
1606 | }
1607 |
1608 | showTestResult(button, type, message) {
1609 | const resultDiv = document.createElement('div');
1610 | resultDiv.className = `test-result mt-2 p-2 rounded text-sm ${
1611 | type === 'success' ? 'bg-green-100 text-green-800' :
1612 | type === 'warning' ? 'bg-yellow-100 text-yellow-800' :
1613 | 'bg-red-100 text-red-800'
1614 | }`;
1615 | resultDiv.innerHTML = `<i class="fas fa-${
1616 | type === 'success' ? 'check-circle' :
1617 | type === 'warning' ? 'exclamation-triangle' : 'times-circle'
1618 | } mr-1"></i>${message}`;
1619 |
1620 | // Remove any existing result
1621 | const existingResult = button.parentNode.querySelector('.test-result');
1622 | if (existingResult) existingResult.remove();
1623 |
1624 | button.parentNode.appendChild(resultDiv);
1625 |
1626 | // Auto-remove after 5 seconds
1627 | setTimeout(() => {
1628 | if (resultDiv.parentNode) {
1629 | resultDiv.remove();
1630 | }
1631 | }, 5000);
1632 | }
1633 |
1634 | // Advanced features
1635 | showNotification(message, type = 'info') {
1636 | const notification = document.createElement('div');
1637 | notification.className = `fixed top-4 right-4 p-4 rounded-lg shadow-lg z-50 ${
1638 | type === 'success' ? 'bg-green-500 text-white' :
1639 | type === 'error' ? 'bg-red-500 text-white' :
1640 | type === 'warning' ? 'bg-yellow-500 text-white' :
1641 | 'bg-blue-500 text-white'
1642 | }`;
1643 | notification.innerHTML = `<i class="fas fa-${
1644 | type === 'success' ? 'check' :
1645 | type === 'error' ? 'times' :
1646 | type === 'warning' ? 'exclamation' : 'info'
1647 | } mr-2"></i>${message}`;
1648 |
1649 | document.body.appendChild(notification);
1650 |
1651 | // Animate in
1652 | notification.style.transform = 'translateX(100%)';
1653 | setTimeout(() => {
1654 | notification.style.transform = 'translateX(0)';
1655 | notification.style.transition = 'transform 0.3s ease';
1656 | }, 10);
1657 |
1658 | // Auto-remove
1659 | setTimeout(() => {
1660 | notification.style.transform = 'translateX(100%)';
1661 | setTimeout(() => notification.remove(), 300);
1662 | }, 4000);
1663 | }
1664 |
1665 | exportProgress() {
1666 | const progress = {
1667 | completedSteps: [...this.completedSteps],
1668 | timestamp: new Date().toISOString(),
1669 | totalSteps: this.totalSteps
1670 | };
1671 |
1672 | const blob = new Blob([JSON.stringify(progress, null, 2)], { type: 'application/json' });
1673 | const url = URL.createObjectURL(blob);
1674 | const a = document.createElement('a');
1675 | a.href = url;
1676 | a.download = 'master-mcp-server-progress.json';
1677 | a.click();
1678 | URL.revokeObjectURL(url);
1679 |
1680 | this.showNotification('Progress exported successfully!', 'success');
1681 | }
1682 | }
1683 |
1684 | // Initialize dashboard when DOM is loaded
1685 | document.addEventListener('DOMContentLoaded', () => {
1686 | new InstallationDashboard();
1687 | });
1688 | </script>
1689 | </body>
1690 | </html>
```