@@ -182,9 +182,11 @@ Deepnote maintains forks of well-established LSP servers:
182182
183183#### sql-language-server
184184
185- - Provides SQL-specific intelligence
186- - Understands database schemas
187- - Offers query optimization suggestions
185+ - Provides SQL-specific intelligence for SQL cells in Deepnote notebooks
186+ - Runs locally as a separate process using stdio communication
187+ - Integrates with configured database integrations (PostgreSQL, MySQL, BigQuery)
188+ - Offers autocomplete, error detection, and schema awareness
189+ - Uses the [ @deepnote/sql-language-server ] ( https://github.com/deepnote/sql-language-server ) package
188190
189191## Benefits for Users
190192
@@ -334,48 +336,66 @@ When you open a `.deepnote` file in VS Code:
3343361 . ** Environment Creation** : The extension creates a dedicated virtual environment for the notebook
3353372 . ** Toolkit Installation** : Installs ` deepnote-toolkit ` and ` python-lsp-server[all] ` in the venv
3363383 . ** Kernel Launch** : Starts the Deepnote kernel using the toolkit
337- 4 . ** LSP Activation** : Automatically starts the LSP client for code intelligence
339+ 4 . ** LSP Activation** : Automatically starts LSP clients for code intelligence
340+ - ** Python** : Uses python-lsp-server for Python code intelligence
341+ - ** SQL** : Uses sql-language-server for SQL code intelligence
338342
339343#### 2. LSP Client Management
340344
341345The ` DeepnoteLspClientManager ` (in ` src/kernels/deepnote/deepnoteLspClientManager.node.ts ` ) handles:
342346
343347#### Client Lifecycle
348+
344349``` typescript
345350// When kernel starts
346351await lspClientManager .startLspClients (
347- serverInfo , // Deepnote server connection info
348- notebookUri , // Notebook file URI
349- interpreter // Python environment from venv
352+ serverInfo , // Deepnote server connection info
353+ notebookUri , // Notebook file URI
354+ interpreter // Python environment from venv
350355);
351356
352357// When notebook closes
353358await lspClientManager .stopLspClients (notebookUri );
354359```
355360
356361#### Per-Notebook Isolation
362+
357363- Each notebook gets its own LSP client instance
358364- Clients are isolated to prevent conflicts
359365- Automatic cleanup when notebooks close
360366
361367#### Duplicate Prevention
368+
362369- Prevents multiple clients for the same notebook
363370- Reuses existing clients when possible
364371- Graceful handling of client errors
365372
366373#### 3. Language Server Process
367374
368- The extension uses ` python-lsp-server ` in stdio mode:
375+ The extension runs dedicated language servers for both Python and SQL:
376+
377+ ** Python LSP:**
378+
379+ ``` typescript
380+ const serverOptions: Executable = {
381+ command: pythonPath , // Python from venv
382+ args: [' -m' , ' pylsp' ], // Start python-lsp-server
383+ options: { env: { ... process .env } }
384+ };
385+ ```
386+
387+ ** SQL LSP:**
369388
370389``` typescript
371390const serverOptions: Executable = {
372- command: pythonPath , // Python from venv
373- args: [' -m ' , ' pylsp ' ], // Start python-lsp-server
374- options: { env: { ... process .env } }
391+ command: sqlLspPath , // Path to sql-language-server binary
392+ args: [' up ' , ' --method ' , ' stdio ' ],
393+ options: { env: { ... process .env } }
375394};
376395```
377396
378397** Why stdio instead of TCP:**
398+
379399- Simpler process management
380400- Better isolation
381401- Standard LSP pattern
@@ -387,38 +407,42 @@ The LSP client is configured to provide intelligence for Python cells in Deepnot
387407
388408``` typescript
389409documentSelector : [
390- {
391- scheme: ' vscode-notebook-cell' , // Notebook cells
392- language: ' python' ,
393- pattern: ' **/*.deepnote'
394- },
395- {
396- scheme: ' file' ,
397- language: ' python' ,
398- pattern: ' **/*.deepnote'
399- }
400- ]
410+ {
411+ scheme: ' vscode-notebook-cell' , // Notebook cells
412+ language: ' python' ,
413+ pattern: ' **/*.deepnote'
414+ },
415+ {
416+ scheme: ' file' ,
417+ language: ' python' ,
418+ pattern: ' **/*.deepnote'
419+ }
420+ ];
401421```
402422
403423This ensures code intelligence works in:
424+
404425- Interactive notebook cells
405426- Cell outputs
406427- Notebook file contexts
407428
408429### Features Provided
409430
410431#### Real-Time Code Intelligence
432+
411433- Autocomplete as you type in notebook cells
412434- Hover documentation for functions and variables
413435- Signature help for function parameters
414436- Error detection before execution
415437
416438#### Context Awareness
439+
417440- Understands imports and dependencies from the venv
418441- Knows about variables defined in earlier cells
419442- Provides relevant suggestions based on cell context
420443
421444#### Integration with Kernel
445+
422446- LSP runs alongside the Deepnote kernel
423447- Both share the same Python environment
424448- Consistent experience between static analysis and execution
@@ -431,10 +455,7 @@ The LSP client manager is registered as a singleton service:
431455
432456``` typescript
433457// In src/notebooks/serviceRegistry.node.ts
434- serviceManager .addSingleton <IDeepnoteLspClientManager >(
435- IDeepnoteLspClientManager ,
436- DeepnoteLspClientManager
437- );
458+ serviceManager .addSingleton <IDeepnoteLspClientManager >(IDeepnoteLspClientManager , DeepnoteLspClientManager );
438459```
439460
440461#### Kernel Lifecycle Integration
@@ -455,6 +476,7 @@ await this.lspClientManager.startLspClients(
455476#### Error Handling
456477
457478The implementation gracefully handles:
479+
458480- Missing ` python-lsp-server ` installation
459481- LSP server crashes
460482- Connection failures
@@ -463,16 +485,19 @@ The implementation gracefully handles:
463485### User Experience
464486
465487#### Transparent Operation
488+
466489- No manual configuration required
467490- Automatically starts with notebooks
468491- Seamlessly integrates with VS Code features
469492
470493#### Performance
494+
471495- Lightweight per-notebook clients
472496- Fast response times for code intelligence
473497- Minimal impact on notebook execution
474498
475499#### Reliability
500+
476501- Robust error handling
477502- Automatic reconnection on failures
478503- Clean shutdown on notebook close
@@ -491,21 +516,95 @@ The extension includes comprehensive integration tests:
491516```
492517
493518Tests run in a real VS Code environment to ensure:
519+
494520- ` vscode-languageclient ` works correctly
495521- LanguageClient lifecycle is properly managed
496522- Integration with VS Code APIs functions as expected
497523
524+ ### SQL LSP Integration
525+
526+ The extension also provides SQL language intelligence using the ` sql-language-server ` package.
527+
528+ #### How SQL LSP Works
529+
530+ ** Local Process Approach:**
531+
532+ - SQL LSP runs as a separate local process (similar to Python LSP)
533+ - Uses stdio communication mode for simplicity and consistency
534+ - Automatically starts when notebooks are opened
535+ - No external server or port configuration required
536+
537+ ** Database Integration:**
538+
539+ ``` typescript
540+ // SQL LSP automatically discovers database integrations
541+ const connections = await integrationStorage .getAll ();
542+
543+ // Converts extension's integration configs to sql-language-server format
544+ const sqlConnections = connections
545+ .filter ((config ) => isSupportedType (config .type ))
546+ .map ((config ) => convertToSqlLspConnection (config ));
547+
548+ // Passes connections to SQL LSP via initializationOptions
549+ initializationOptions : {
550+ connections : sqlConnections ;
551+ }
552+ ```
553+
554+ ** Supported Database Types:**
555+
556+ - PostgreSQL (` pgsql ` )
557+ - MySQL (` mysql ` )
558+ - BigQuery (` big-query ` )
559+
560+ ** Features:**
561+
562+ - SQL autocomplete with table and column suggestions
563+ - Schema-aware query validation
564+ - Error detection for syntax and semantic issues
565+ - Hover information for database objects
566+ - Works with configured database integrations from extension storage
567+
568+ ** Configuration:**
569+
570+ - No manual configuration required
571+ - Automatically uses database integrations configured in the extension
572+ - Credentials are passed securely from integration storage
573+ - Falls back gracefully if no integrations are configured
574+
575+ #### SQL LSP Startup Flow
576+
577+ 1 . ** Notebook Opens** : User opens a ` .deepnote ` file
578+ 2 . ** Kernel Selection** : DeepnoteKernelAutoSelector starts the kernel
579+ 3 . ** Python LSP Start** : Python LSP client starts for Python cells
580+ 4 . ** SQL LSP Start** : SQL LSP client starts for SQL cells
581+ - Gets path to ` sql-language-server ` binary from ` node_modules `
582+ - Retrieves configured database integrations from storage
583+ - Converts integration configs to sql-language-server format
584+ - Starts server with ` ['up', '--method', 'stdio'] ` args
585+ - Passes database connections via initialization options
586+ 5 . ** Ready** : Both Python and SQL intelligence available
587+
588+ #### Error Handling
589+
590+ The SQL LSP implementation handles errors gracefully:
591+
592+ - If ` sql-language-server ` binary is missing, logs warning and continues
593+ - If no database integrations are configured, SQL LSP still starts (but has no schemas)
594+ - If integration conversion fails, logs error and skips that integration
595+ - Python LSP is never affected by SQL LSP failures
596+
498597### Differences from Toolkit LSP
499598
500599The extension's LSP integration differs from the toolkit's in key ways:
501600
502- | Aspect | Toolkit (Server-Side) | VS Code Extension (Client-Side) |
503- | --------| ----------------------| ----------------------------------|
504- | ** Scope** | Multiple editors/clients | Single VS Code instance |
505- | ** Lifecycle** | Runs continuously with server | Per-notebook, on-demand |
506- | ** Transport** | WebSocket/TCP (multi-client) | stdio (process-based) |
507- | ** Management** | Toolkit manages all processes | Extension manages per-notebook |
508- | ** Use Case** | JupyterLab, web interfaces | VS Code editor integration |
601+ | Aspect | Toolkit (Server-Side) | VS Code Extension (Client-Side) |
602+ | -------------- | ----------------------------- | ------------------------------- |
603+ | ** Scope** | Multiple editors/clients | Single VS Code instance |
604+ | ** Lifecycle** | Runs continuously with server | Per-notebook, on-demand |
605+ | ** Transport** | WebSocket/TCP (multi-client) | stdio (process-based) |
606+ | ** Management** | Toolkit manages all processes | Extension manages per-notebook |
607+ | ** Use Case** | JupyterLab, web interfaces | VS Code editor integration |
509608
510609Both approaches are complementary—the toolkit provides server infrastructure while the extension provides client integration.
511610
@@ -518,8 +617,8 @@ The LSP integration opens up many possibilities:
518617- ** Team Features** : Shared language server configurations
519618- ** Custom Servers** : Domain-specific intelligence for specialized workflows
520619- ** Enhanced Debugging** : Inline variable inspection and breakpoints
521- - ** SQL LSP Integration** : Extend support to SQL cells in notebooks (planned)
522620- ** Multi-Language Support** : Add LSP clients for R, JavaScript, and other languages
621+ - ** Enhanced SQL Support** : Add support for more database types beyond current MySQL, PostgreSQL, BigQuery
523622
524623## Resources
525624
0 commit comments