refactor(mcp): migrate mcp_service/index.js from JavaScript to TypeScript - #22
shayanshafii wants to merge 2 commits into
Conversation
…ript - Convert index.js to index.ts with proper interfaces and types - Add SupersetMCPServerOptions and ResolvedOptions interfaces - Add tsconfig.json for TypeScript compilation - Update package.json: main points to dist/index.js, add types field, add build script, add typescript and @types/node devDependencies - Add .gitignore for node_modules/ and dist/ Co-Authored-By: shayan <shayan@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| start(): void { | ||
| require('./bin/superset-mcp.js'); | ||
| } |
There was a problem hiding this comment.
🔴 Server stop method can never work because the start method never captures the spawned process
The server's child process reference is never assigned during startup (require('../bin/superset-mcp.js') at superset/mcp_service/index.ts:66), so the stop method's kill call is always skipped.
Impact: Callers who use this class to manage the MCP server lifecycle cannot programmatically stop it — the spawned Python process keeps running.
start() never populates this.process, making stop() dead code
The start() method at superset/mcp_service/index.ts:65-67 calls require('../bin/superset-mcp.js') which internally runs main() in superset/mcp_service/bin/superset-mcp.js:201-278. That main() function calls spawn() at line 250, creating a child process, but the process handle is local to main() and never returned or exported.
Meanwhile, this.process is initialized to null at superset/mcp_service/index.ts:62 and is never reassigned. The stop() method at lines 69-73 checks if (this.process) which is always null, so this.process.kill() is never reached.
The old JS code at index.js:43-46 had the same bug. The TypeScript conversion faithfully preserved the broken lifecycle management.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
This is a pre-existing issue in the original JS code — start() never captured the process handle there either. Intentionally not fixing it in this migration PR to keep the scope to a JS→TS conversion, but it would be a good follow-up.
| "module": "commonjs", | ||
| "lib": ["ES2020"], | ||
| "outDir": "./dist", | ||
| "rootDir": ".", |
There was a problem hiding this comment.
📝 Info: tsconfig rootDir includes package.json, which may produce unexpected dist/ structure
tsconfig.json:7 sets rootDir: "." but include at line 18 only lists index.ts. While this means only index.ts is compiled, resolveJsonModule: true (line 15) combined with rootDir: "." means if any future TS file imports package.json, TypeScript would try to preserve the directory structure relative to . in dist/. For now this is benign since only index.ts is compiled and it doesn't import JSON, but it's a fragile setup if the project grows.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Acknowledged — benign for the current single-file setup. If more .ts files are added that import JSON, rootDir can be narrowed to "./src" at that point.
…ompat
- require('./bin/superset-mcp.js') -> require('../bin/superset-mcp.js') since compiled output lives in dist/
- Replace dual export default + module.exports with export= for clean CJS semantics
Co-Authored-By: shayan <shayan@cognition.ai>
| } | ||
|
|
||
| start(): void { | ||
| require('../bin/superset-mcp.js'); |
There was a problem hiding this comment.
📝 Info: Require path adjusted correctly for dist/ output directory
The old index.js used require('./bin/superset-mcp.js') which resolved from superset/mcp_service/ to superset/mcp_service/bin/superset-mcp.js. The new index.ts uses require('../bin/superset-mcp.js') (superset/mcp_service/index.ts:66). Since tsconfig.json sets outDir: "./dist", the compiled output lands at superset/mcp_service/dist/index.js, and from there ../bin/superset-mcp.js correctly resolves back to superset/mcp_service/bin/superset-mcp.js. The path change is mechanically correct.
Was this helpful? React with 👍 or 👎 to provide feedback.
| constructor(options: SupersetMCPServerOptions = {}) { | ||
| this.options = { | ||
| transport: options.transport ?? 'http', | ||
| host: options.host ?? '127.0.0.1', | ||
| port: options.port ?? 5008, | ||
| debug: options.debug ?? false, | ||
| pythonPath: options.pythonPath ?? null, | ||
| supersetRoot: options.supersetRoot ?? null, | ||
| configPath: options.configPath ?? null, | ||
| }; | ||
| this.process = null; | ||
| } |
There was a problem hiding this comment.
🚩 Constructor options are stored but never consumed
The options property (transport, host, port, debug, etc.) is carefully resolved and stored at superset/mcp_service/index.ts:53-61, but the start() method at line 65-67 simply calls require('../bin/superset-mcp.js') which parses its own CLI args and environment variables independently (superset/mcp_service/bin/superset-mcp.js:67-74). None of the stored options are forwarded. This means constructing new SupersetMCPServer({ port: 9000 }) has no effect on the actual server behavior. This is a pre-existing design gap (the old JS code had the same issue), but worth noting since the TypeScript conversion would have been a natural time to address it.
Was this helpful? React with 👍 or 👎 to provide feedback.
SUMMARY
Migrates
superset/mcp_service/index.jsto TypeScript (index.ts).Changes:
index.js→index.tswith typed interfaces:SupersetMCPServerOptions(input, all fields optional)ResolvedOptions(internal, all fields required with defaults applied)ChildProcess | nullfor theprocessfieldtsconfig.jsonadded targeting ES2020/CommonJS with strict mode, outputting todist/package.jsonupdated:main→dist/index.js, addedtypes,build/prebuildscripts,typescript+@types/nodedevDeps.gitignoreadded fornode_modules/anddist/require('./bin/superset-mcp.js')→require('../bin/superset-mcp.js')to resolve correctly fromdist/export = SupersetMCPServerfor clean CJS semantics (matching originalmodule.exports)BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — no UI changes.
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION
Link to Devin session: https://app.devin.ai/sessions/ef0439e5c59a4eaca3a30a2997df2113
Requested by: @shayanshafii
Devin Review