Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>RouterOS LSPNew to Visual Studio Code? Get it now.
RouterOS LSP

RouterOS LSP

TIKOCI

|
891 installs
| (1) | Free
| Sponsor
Language Server Protocol (LSP) for MikroTik RouterOS
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

RouterOS LSP

LSP running VSCode GIF

RouterOS LSP is a language server that provides syntax highlighting, code completion, diagnostics, and other intelligent language features for RouterOS scripts (.rsc files) in most LSP-capable editors. By querying a live RouterOS device via the REST API, the LSP ensures syntax always matches your RouterOS version.

Supported Features

RouterOS LSP supports:

  • Completion — code suggestions and tab completion
  • Diagnostics — real-time syntax error reporting
  • Semantic Tokens — syntax highlighting that matches RouterOS CLI colors
  • Hover Information — help and variable inspection (Work in Progress)
  • Document Symbols — navigate variables and commands (Work in Progress)
  • References — find usages
  • Definition Lookup — jump to definitions
  • VSCode Commands — additional actions via Command Palette (VSCode only)
  • Walkthrough — guided setup wizard (VSCode only)

The LSP activates automatically for .rsc files or when language is set to routeros. In most editors, you can manually set the file language to routeros to enable LSP features.

✅ RouterOS LSP requires a HTTP/REST connection to a RouterOS device. The LSP obtains all syntax data and command definitions by querying RouterOS's /console/inspect API.

⚠️ Without a RouterOS connection, the LSP cannot function. Credentials can be provided in editor's LSP configuration, see Configuration section.

𝌡 For known issues, changelog, and feature tracking, see CHANGELOG.md.

Installation

Visual Studio Code (VSCode)

Install RouterOS LSP from VSCode Marketplace

By selecting the "Install" button, you will be prompted by your browser to install the extension.

❤️ Also check out TikBook, which integrates with RouterOS LSP and adds a notebook interface for RouterOS scripts. Installing TikBook will automatically install RouterOS LSP, if missing.

Alternative VSCode Installation Methods

Install from within VSCode
  1. Open VSCode and go to Extensions (or press ⌘ + Shift + X on Mac, Ctrl + Shift + X on Windows/Linux)
  2. Search for "TIKOCI", and select "RouterOS LSP"
  3. Click Install
Install via VSIX File

If you prefer not to use the Marketplace, you can install from a VSIX file from [GitHub Releases](https://github.com/tikoci/lsp-routeros-ts/blob/HEAD/https:/github.com/tikoci/> lsp-routeros-ts/releases) and code --install-extension lsp-routeros-ts-*.vsix from Terminal. To remove, code --uninstall-extension tikoci.lsp-routeros-ts

Other Editors and LSP Clients

For editors other than VSCode, download the LSP server binary from GitHub Releases.

LSP running in NeoVim

🛟 Limited testing has been done with NeoVim. Other LSP manager plugins are not tested. Contributions welcome!

NeoVim Install

  1. Download the NeoVim LSP server for your platform from GitHub Releases and place it in ~/.bin/ (or adjust the path in step 3)

  2. Edit your NeoVim init.lua (typically at ~/.config/nvim/init.lua) and add:

    dofile(os.getenv('HOME') .. '/.config/nvim/nvim-routeros-lsp-init.lua')
    
  3. Download nvim-routeros-lsp-init.lua to ~/.config/nvim/nvim-routeros-lsp-init.lua

  4. Edit nvim-routeros-lsp-init.lua from GitHub Releases and set your RouterOS credentials and connection details at the top of the file. See NeoVim Configuration below for details.

  5. On macOS only, If the downloaded server binary is blocked, remove the quarantine flag:

    xattr -d com.apple.quarantine ~/.bin/lsp-routeros-server-darwin-arm64
    
  6. Open a .rsc file in NeoVim and the LSP should load. You'll see a confirmation message at the bottom of the editor.

  7. To trigger code completion, use Ctrl + Z followed by Ctrl + O (omni-complete) while in INSERT mode.

Configuration

All RouterOS LSP configuration is controlled through the LSP workspace/configuration capability. The following settings are available:

Properties

interface LspSettings {
  baseUrl: string;                              // "http://192.168.88.1" or "https://router.lan"
  username: string;                             // RouterOS user name
  password: string;                             // RouterOS user password
  apiTimeout: number;                           // Seconds to wait for RouterOS (default: 15)
  allowClientProvidedCredentials: boolean;      // Allow other extensions to override credentials (default: true)
  checkCertificates: boolean;                   // Verify HTTPS certificates (default: false, ignored in VSCode Web)
}

RouterOS Connection Setup

For the LSP to function, the REST API must be enabled in your RouterOS device and accessible from your editor's computer. A valid RouterOS account must be provided to the RouterOS LSP as well (see Configuration section) .

Theoretically, you may not need any setup in RouterOS...as by default, HTTP is enabled on port 80, and reachable from default LAN; and, any RouterOS account (with sufficient rights, like admin with full rights) can be used in RouterOS LSP for login via REST API.

However, it recommended to use HTTPS with valid certificate, and an account with more limited rights to RouterOS configurations. For example, write policy is not required for core LSP operations since only /console/inspect data is read.

Enabling HTTPS with Let's Encrypt certificate

/certificate/enable-ssl-certificate
/ip/service enable www-ssl

🔐 When using HTTPS, your RouterOS's TLS certificate should be trusted by your system (installed in the system keychain/certificate store). Self-signed certificates are not directly supported by the LSP. Although in some editors, you can disable certificate checking, but this often complex and not recommended._

Creating a Limited RouterOS User

It's recommended to create a dedicated RouterOS user with minimal permissions for the LSP, rather than using a full admin account:

/user/group add name=lsp policy=read,api,rest-api
/user add name=lsp password=<strong-password> group=lsp

VS Code Settings

After installing, configure your RouterOS connection:

  1. Open Settings (press ⌘ + , on Mac or Ctrl + , on Windows/Linux)
  2. Go to Extensions > RouterOS LSP
  3. Set the following required fields:
    • Base URL: Protocol and host (e.g., http://192.168.88.1 or https://my-router.local) — without trailing slash
    • Username: RouterOS user with read, api, and rest-api policy access
    • Password: RouterOS user password
    • API Timeout: How long (in seconds) to wait for RouterOS responses (default: 15 seconds)

VSCode Settings Example

Alternatively, use the Command Palette (⌘ + Shift + P on Mac or Ctrl + Shift + P on Windows/Linux), search for "RouterOS LSP: Show Settings", and select it. In VS Code's settings.json, all setting uses the routeroslsp.* prefix.

NeoVim Configuration

Edit the configuration section at the top of nvim-routeros-lsp-init.lua with your RouterOS connection details:

local settings = {
  routeroslsp = {
    baseUrl = "http://192.168.88.1",  -- Change to your router or https://
    username = "lsp",                  -- Change to your RouterOS user
    password = "changeme",             -- Change to your RouterOS password
    hotlock = true
  }
}

Also verify the platform is correct in the local lspexec variable. For example, on macOS with Apple Silicon:

local lspexec = { os.getenv("HOME") .. "/.bin/lsp-routeros-server-darwin-arm64", "--stdio" }

Adjust the filename for your platform: darwin-x64 (Intel Mac), linux-x64, linux-arm64, windows-x64.exe, etc.

Other LSP Clients

Other LSP clients should work if they support the workspace/configuration capability, which is the standard way LSP clients receive configuration. RouterOS connection settings must be provided somehow to the LSP client. Both NeoVim and VSCode support this; most modern LSP-capable editors do as well.

Troubleshooting

VS Code

Syntax Highlighting (Semantic Tokens)

RouterOS LSP uses semantic tokens for syntax highlighting that matches RouterOS CLI colors by default. If colors don't appear or seem incorrect:

  1. Open the Command Palette and search for "Refresh Semantic Tokens"
  2. Select RouterOS LSP: Refresh Semantic Tokens (Syntax Colors)

To customize token colors, use the Command Palette and select "Apply Semantic Color Overrides to Settings" to add token color mappings to your settings.json.

Check Output Logs

If the LSP doesn't work:

  1. Open the Output view: Shift + ⌘ + U (Mac) or Shift + Ctrl + U (Windows/Linux)
  2. Select "RouterOS LSP" from the dropdown to view detailed logs
  3. Check that your RouterOS credentials are correct and the device is accessible
  4. Use the Command Palette and select "RouterOS LSP: Test RouterOS Connection" to verify connectivity

Unicode and Character Encoding

For proper syntax checking and colorization, RouterOS LSP converts non-ASCII characters to underscores when querying RouterOS's /console/inspect API. This keeps character indexes aligned between RouterOS (Windows1252 encoding) and VSCode (UTF-16 internally), despite HTTP using UTF-8.

Important: Non-ASCII characters cannot appear in syntax elements (commands, paths, attributes); they can only appear in comments and strings. The LSP safely replaces them with underscores during syntax analysis without affecting the actual file content. Your script files preserve all encoding and are never modified by the LSP.

If syntax highlighting becomes misaligned with these characters, use "Refresh Semantic Tokens" command. If issues persist, please report them with the problematic script attached.

Visual Studio Code Specific Features

VSCodeLspCommands

RouterOS LSP provides several commands accessible via the Command Palette (⌘ + Shift + P on Mac or Ctrl + Shift + P on Windows/Linux):

  • Test RouterOS Connection — Verifies the LSP can successfully connect to RouterOS with current credentials
  • Refresh Semantic Tokens (Syntax Colors) — Forces recalculation of semantic tokens for open documents
  • Show Logs (Output) — Opens the Output pane and selects the RouterOS LSP log channel
  • Show Settings — Opens RouterOS LSP extension settings
  • Apply Semantic Color Overrides to Settings — Adds custom semantic token color mappings to settings.json for further customization

Implementation and Development

The RouterOS LSP is built with Microsoft's vscode-languageserver-node library and can run on VSCode, NeoVim, or any LSP-capable editor.

Key Design: The LSP communicates with a running RouterOS device via its /console/inspect REST API. This means:

  • Syntax definitions always match the connected RouterOS version
  • New commands and attributes are available immediately after a RouterOS upgrade
  • The LSP requires a live RouterOS device; it cannot work offline

Building from Source

All builds use Bun:

  1. Clone the repository: git clone https://github.com/tikoci/lsp-routeros-ts.git
  2. Install dependencies: bun install
  3. Build: bun run compile

The compiled LSP server is available at ./server/dist/server.js and can be executed with Node.

Packaging Options

VSCode Extension (VSIX):

bun run vsix:package    # Creates lsp-routeros-ts-*.vsix
code --install-extension lsp-routeros-ts-*.vsix

Standalone Server (for NeoVim and other editors):

bun run bun:exe    # Creates lsp-routeros-server binary for your platform
cp ./lsp-routeros-server ~/.bin/

The standalone server supports these transport options:

  • --stdio — Standard input/output (used by NeoVim and most LSP clients)
  • --node-ipc — Node IPC (used by VSCode)
  • --socket=<port> — TCP socket (experimental)

Developing with VSCode

  1. Clone and open the repository in VSCode
  2. Run bun run watch:node in a terminal to rebuild on changes
  3. Press F5 to launch the "Extension Development Host"
  4. Open a .rsc file and test LSP features

For detailed extension debugging, see the VSCode Extension Debugging Guide.

Project Structure

Source:

client/src/          — VSCode extension client code
server/src/          — LSP server implementation
  controller.ts      — LSP protocol handler  
  server.ts          — Main LSP entry point
  model.ts           — RouterOS data model
  routeros.ts        — RouterOS HTTP API client

Build Outputs:

client/dist/         — Compiled VSCode extension
server/dist/         — Compiled LSP server
lsp-routeros-server* — Standalone binaries (various platforms)
*.vsix               — VSCode extension package

Developer Scripts

The LSP uses bun run scripts defined in package.json:

  • compile — Build all components
  • watch:node — Rebuild server on file changes
  • vsix:package — Package VSCode extension
  • bun:exe — Build standalone server binary
  • lint — Run ESLint on code

For new LSP features, add handlers to server/src/controller.ts. Refer to the LSP Protocol Specification for complete details.

ID Fields

In many places some "id" field is used, to clarify naming:

  • lsp-routeros-ts is generally used to refer to the entire project, the -ts refers that the LSP is implemented in TypeScript – as it possible to implement the LSP in other languages

  • lsp-routeros-server-* refers to just the actual LSP server code or build products

  • vscode-lsp-routeros refers to the VSCode-specific "language extension" that "binds" the LSP server with VSCode extension ecosystem, but largely "proxies" VSCode requests into the LSP server code.

  • routeroslsp is used when - is cannot be used for name, like configuration ("settings") and also the "server" package.json to ensure alignment with configuration.

Understanding LSP Protocol

There are a few dozen APIs that make up an LSP Server. The ones implemented by RouterOS LSP are listed at top of page. For a richer experience (i.e. more "help" from LSP in editor), additional protocols could be implemented. This section attempts to catalog from LSP protocol to implementation to "real features".

LSP Specification

The official LSP specification is what really defines possible language features:

  • Go to Declaration
  • Go to Definition
  • Go to Type Definition
  • Go to Implementation
  • Find References
  • Prepare Call Hierarchy
  • Call Hierarchy Incoming Calls
  • Call Hierarchy Outgoing Calls
  • Prepare Type Hierarchy
  • Type Hierarchy Super Types
  • Type Hierarchy Sub Types
  • Document Highlight
  • Document Link
  • Document Link Resolve
  • Hover
  • Code Lens
  • Code Lens Refresh
  • Folding Range
  • Selection Range
  • Document Symbols
  • Semantic Tokens
  • Inline Value
  • Inline Value Refresh
  • Inlay Hint
  • Inlay Hint Resolve
  • Inlay Hint Refresh
  • Moniker
  • Completion Proposals
  • Completion Item Resolve
  • Publish Diagnostics
  • Pull Diagnostics
  • Signature Help
  • Code Action
  • Code Action Resolve
  • Document Color
  • Color Presentation
  • Formatting
  • Range Formatting
  • On type Formatting
  • Rename
  • Prepare Rename
  • Linked Editing Range

The spec is pretty abstract, since LSP servers support a few transports, so how to implement them depends on the library – but the list above gives the "full menu" of LSP language features.

langserver.org

https://langserver.org tracks supported protocols against LSPs, with an LSP "declaring" their support ("Implemented", "WIP", "Not implemented", "Not applicable"). Classifying RouterOS LSP in this scheme:

  • ✅ Implemented - Code completion - could be improved but functional
  • 💡 WIP* - Hover - only shows highlight "syntax" codes but does "something"
  • 🚫 Not implemented - Jump to def - somewhat possible but need complex multi-step process and still be lossy and error prone
  • ❓ WIP - Workspace symbols - semantic tokens supported, unsure if same
  • 🚫 Not implemented - Find references - similar to "Jump to def"
  • ✅ Implemented - Diagnostics - could be improved, but do flag the first error found

langserver.org also tracks "Additional capabilities" like

  • Automatic dependency management - Not applicable - Language servers that support this feature are able to resolve / install a project's 3rd-party dependencies without the need for a user to manually intervene.
  • No arbitrary code execution - Implemented - Language servers that support this feature don't execute arbitrary code (some language servers do this when running build scripts, analyzing the project, etc.).
  • Tree View Protocol - Not implemented - Language servers that support this feature are able to render tree views. See this link for more information.
  • Decoration Protocol - Not implemented - Language servers that support this feature are able to provide text to be displayed as "non-editable" text in the text editor. See this link for more information.

Microsoft's vscode-languageserver

The RouterOS LSP implementation uses Microsoft's vscode-languageserver Node library, and the documentation describes many of the LSP protocols and using with the library. The following tables is from the VSCode docs on Language Extensions, which gives a sense of the possibilities:

VS Code API LSP method
createDiagnosticCollection PublishDiagnostics
registerCompletionItemProvider Completion & Completion Resolve
registerHoverProvider Hover
registerSignatureHelpProvider SignatureHelp
registerDefinitionProvider Definition
registerTypeDefinitionProvider TypeDefinition
registerImplementationProvider Implementation
registerReferenceProvider References
registerDocumentHighlightProvider DocumentHighlight
registerDocumentSymbolProvider DocumentSymbol
registerCodeActionsProvider CodeAction
registerCodeLensProvider CodeLens & CodeLens Resolve
registerDocumentLinkProvider DocumentLink & DocumentLink Resolve
registerColorProvider DocumentColor & Color Presentation
registerDocumentFormattingEditProvider Formatting
registerDocumentRangeFormattingEditProvider RangeFormatting
registerOnTypeFormattingEditProvider OnTypeFormatting
registerRenameProvider Rename & Prepare Rename
registerFoldingRangeProvider FoldingRange

Microsoft Sample LSP Code

See https://github.com/microsoft/vscode-extension-sample, for example "Code Actions"

Implementation "Tips and Tricks"

Some various notes that are not obvious from docs or specific to RouterOS

Position vs Offset

The vscode-languageserver library provides a "position" generally, which is line and char position. But for programmatic use the "index" into an array with code is often more useful, this is called "offset" in the library. The "offset" is more useful with /console/inspect. To handle this, the TextDocument object supports an offsetAt() and positionAt() to enable conversion from the two forms.

/console/inspect request=syntax

Not currently used — but be useful. It's not used since it requires "tricks" to get useful information for completions and other things. For example, to get useful data, stuff like a space or = may need to be added to input= — even though it does not exist in loaded script/config.

For now, just documenting how /console/inspect with request=syntax works in various cases:

"TEXT" in output could provide a "description" to some LSP data for a "dir"
> /console/inspect request=syntax input="/ip/route add" 
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL   SYMBOL-TYPE  NESTED  NONORM  TEXT                                                                    
syntax           collection        0  yes                                                                             
syntax  ..       explanation       1  no      go up to ip                                                             
syntax  add      explanation       1  no      Create a new item                                                       
syntax  check    explanation       1  no                                                                              
syntax  comment  explanation       1  no      Set static route comment                                                
syntax  disable  explanation       1  no      Disable route                                                           
syntax  edit     explanation       1  no                                                                              
syntax  enable   explanation       1  no      Enable route                                                            
syntax  export   explanation       1  no      Print or save an export script that can be used to restore configuration
syntax  find     explanation       1  no      Find items by value                                                     
syntax  get      explanation       1  no      Gets value of item's property                                           
syntax  print    explanation       1  no      Print values of item properties                                         
syntax  remove   explanation       1  no      Remove route                                                            
syntax  reset    explanation       1  no                                                                              
syntax  set      explanation       1  no      Change item properties                                                  
syntax  unset    explanation       1  no         
Adding a fake space to input gets "arg"'s for a "cmd"
> /console/inspect request=syntax input="/ip/route add "
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL               SYMBOL-TYPE  N  NON  TEXT                                                                                                            
syntax                       collection   0  yes                                                                                                                  
syntax  blackhole            explanation  1  no                                                                                                                   
syntax  check-gateway        explanation  1  no   Whether all nexthops of this route are checking reachability of gateway by sending arp requests every 10 seconds
syntax  comment              explanation  1  no   Short description of the item                                                                                   
syntax  copy-from            explanation  1  no   Item number                                                                                                     
syntax  disabled             explanation  1  no   Defines whether item is ignored or used                                                                         
syntax  distance             explanation  1  no   Administrative distance of the route                                                                            
syntax  dst-address          explanation  1  no   Destination address                                                                                             
syntax  gateway              explanation  1  no                                                                                                                   
syntax  pref-src             explanation  1  no                                                                                                                   
syntax  routing-table        explanation  1  no                                                                                                                   
syntax  scope                explanation  1  no                                                                                                                   
syntax  suppress-hw-offload  explanation  1  no                                                                                                                   
syntax  target-scope         explanation  1  no                                                                                                                   
syntax  vrf-interface        explanation  1  no                 
Adding a fake = to input gets some "definition"
> /console/inspect request=syntax input="/ip/route add check-gateway="
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL        SYMBOL-TYPE  NESTED  NONORM  TEXT             
syntax  CheckGateway  definition        0  no                       
syntax                definition        1  no      arp | none | ping

The issue here being the TEXT is not always well-formed – why request=completion is used to retrieve value like above. Like for num types there is an expression that shows the range allowed:

> /console/inspect request=syntax input="/ip/service set port="
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL  SYMBOL-TYPE  NESTED  NONORM  TEXT                        
syntax  Port    definition        0  no      Num                         
syntax  Num     definition        1  no      1..65535    (integer number)

Point being the format of TEXT varies a good bit – and requires parsing to make it actionable in LSP - and all without any documentation on /console/inspect.


Disclaimers

Not affiliated, associated, authorized, endorsed by, or in any way officially connected with MikroTik Any trademarks and/or copyrights remain the property of their respective holders unless specifically noted otherwise. Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark. Naming of particular products or brands should not be seen as endorsements. MikroTik is a trademark of Mikrotikls SIA. Apple and macOS are trademarks of Apple Inc., registered in the U.S. and other countries and regions. UNIX is a registered trademark of The Open Group. No liability can be accepted. No representation or warranty of any kind, express or implied, regarding the accuracy, adequacy, validity, reliability, availability, or completeness of any information is offered. Use the concepts, code, examples, and other content at your own risk. There may be errors and inaccuracies, that may of course be damaging to your system. Although this is highly unlikely, you should proceed with caution. The author(s) do not accept any responsibility for any damage incurred.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft