Bifrost: Multi-Language LSP & MCP Server
VS Code extension for Bifrost, Brokk's tree-sitter-backed multi-language code
intelligence server. The extension starts Bifrost in LSP mode and exposes
definitions, references, symbols, hierarchy, rename, diagnostics, completion,
hover, and related editor features.
Requirements
- VS Code 1.90+
- A supported platform for extension-managed downloads, or a
bifrost-lsp binary
available through one of the launch modes below
Cursor
Cursor uses the Open VSX Registry for VS Code-compatible extensions. In
Cursor's Extensions view, search for brokk.bifrost-vscode, install it, and
open a supported source workspace. The extension starts a Bifrost LSP process
for editor-native definitions, references, hover, rename, symbols, and
diagnostics.
This extension is separate from the Bifrost Cursor agent plugin. The extension
starts its managed bifrost-lsp server with --lsp; the agent plugin uses a
separate bifrost CLI process with --mcp. Install either integration for its own surface, or install both,
but do not point an MCP host at the extension's LSP process.
With the default auto launch mode, accept the managed-binary installation
prompt when it appears. In Output > Bifrost, confirm that the expected
release was downloaded and installed in Cursor's extension global storage.
The installer verifies both the archive checksum published with the GitHub
Release and the SHA-256 pinned into this extension package before extracting
the binary; it also checks bifrost-lsp --version before starting the server.
For the full installation, upgrade, troubleshooting, and exact-workspace smoke
procedure, see the Cursor integration guide.
Configuration
| Setting |
Description |
bifrost.launchMode |
How to start Bifrost: auto, bundled, or path. |
bifrost.serverPath |
Path to the bifrost-lsp binary, or command name on PATH. |
bifrost.debug |
Enable verbose LSP request and notification tracing. |
bifrost.slowRequestMs |
Log LSP handlers that take at least this many milliseconds. |
bifrost.extraArgs |
Extra command-line arguments appended to the LSP server launch. |
bifrost.roots |
Workspace-relative or absolute directories to index instead of the full VS Code workspace. |
bifrost.exclude |
Workspace-relative or absolute files or directories to exclude from indexing and LSP lookups. |
Launch mode behavior:
auto: use bifrost.serverPath when explicitly configured, then the
exact preferred extension-managed binary, then the newest compatible cached
patch, then a preferred binary accepted for installation, then a
local development build under target/, then
bifrost-lsp on PATH.
bundled: require a compatible extension-managed binary for this platform
and prompt to install the preferred binary only when none is cached.
path: use bifrost.serverPath as the exact executable path or command.
The managed server range uses independent extension package metadata:
bifrost.serverVersion, bifrost.minimumServerVersion, and
bifrost.allowPrerelease, with expected archive hashes in
bifrost.archiveSha256. A compatible cached patch is reused without a network
or install prompt. The extension downloads only the exact preferred GitHub Release
archives (.tar.gz on macOS/Linux and .zip on Windows), verifies each
archive against the package-pinned SHA-256 and the release .sha256 sidecar,
extracts the bifrost-lsp executable into VS Code global storage at
binaries/<version>/<platform>-<arch>/, and removes only versions outside the
declared compatible range after a successful install. Managed binaries are checked with
bifrost-lsp --version before the language server starts.
Open semantic packs
Before starting the language server, the extension runs
pack-engine-profile on the selected server binary. A supported profile is
passed unchanged to the shared open-pack cache helper, which selects and
verifies public packs and supplies the native bundle, policy-pack, and
semantic-cache roots to the server. After initialization, the extension checks
that the profile's engine version matches the structured engine identity
negotiated by the server. It never derives pack schemas or capabilities from
--version.
Server binaries without pack-engine-profile continue to start with their
existing behavior. The Output > Bifrost channel reports that open semantic
packs are unavailable for that engine. The managed standalone server provides the profile command and selected-pack
cache facade. A pending pack qualification, missing compatible
release, or unavailable release service also leaves the server running without
pack environment variables. Profile execution or validation failures,
malformed manifests, unsupported manifest schemas, and cache-integrity failures
are reported as startup errors.
The canonical helper and release schema are kept as external files in
out/open-packs.mjs and out/pack-release.schema.json. The extension imports
the helper as native ESM so its schema lookup via import.meta.url remains
valid in the CommonJS extension bundle.
Set BIFROST_OPEN_PACKS_OFFLINE=1 in the VS Code process environment to use cached
content only, or BIFROST_OPEN_PACKS_REFRESH=1 to refresh the cached selection.
After LSP initialization, the extension also requires the server to advertise
capabilities.experimental.bifrost.protocolVersion equal to 1 and a
three-component engineVersion inside bifrost.engineCompatibility (>=0.13.0 <0.14.0 for this release). Missing,
malformed, unsupported, or out-of-range identities stop the client; the
extension never infers compatibility from display text.
Commands
Bifrost: Start Language Server
Bifrost: Stop Language Server
Bifrost: Restart Language Server
Bifrost: Open MCP Setup
Bifrost: Copy MCP Config
Bifrost: Show Output
The status bar item shows the current server state and can start or restart the
language server.
Development
Build the Bifrost server from the repository root:
cargo build --locked --bin bifrost-lsp
Install and compile the extension:
cd editors/vscode
npm ci
npm run compile
npm test
npm test is the complete editor-package quality gate: it checks Prettier
formatting, TypeScript types (including tests and build configuration), ESLint,
the production bundle, and unit tests. Use npm run format to apply the
repository formatting rules and npm run lint:fix for safe ESLint fixes.
Open editors/vscode in VS Code, run the extension in an Extension
Development Host, and open a workspace with a supported source file. For local
development, either rely on the auto-detected target/debug/bifrost-lsp binary or
set:
{
"bifrost.launchMode": "path",
"bifrost.serverPath": "/path/to/bifrost-lsp/target/debug/bifrost-lsp"
}
The extension associates .rql files with Bifrost RQL, provides syntax
highlighting, and shows a play button in the RQL editor title. The button runs
the current editor text, including unsaved edits, through the active Bifrost
language server and displays typed structural-match, declaration, or file
results in the Bifrost Query Results Explorer view. Results are grouped by
file; select one to open it and, when the result has a source range, highlight
that range. It searches
every root currently indexed by that LSP session (all workspace folders by
default, or the scope configured by bifrost.roots). The server must already
be running and indexed; the button does not start or wait for it.
The extension starts Bifrost with:
bifrost-lsp --root <workspace-root> --lsp
--root is the fallback root. VS Code still sends active workspace folders
during LSP initialization, including multi-root workspaces.
The extension also associates .rune files with Bifrost Rune IR. Running
Bifrost: Show Rune IR from a supported source editor opens its preview in
that language mode, with canonical normalized kinds, roles, metadata, spans,
strings, and comments highlighted. The preview headings begin with ;, so
saved previews remain valid Rune IR documents.
VS Code's Format Document command uses the Bifrost LSP formatter for both
.rql and saved .rune files. S-expressions stay compact while they fit within
120 columns; longer forms put their entries on indented lines and keep
:property value pairs together when they fit. Incomplete expressions are left
unchanged.
For large repositories, scope indexing before starting the server:
{
"bifrost.roots": ["src", "tests"],
"bifrost.exclude": ["target", "vendor/generated"]
}
After changing these settings, run Bifrost: Restart Language Server or accept
the restart prompt. The extension sends the resolved paths as LSP
initializationOptions, so excluded files should disappear from workspace
symbol results and document-level LSP lookups.
MCP Setup
Run Bifrost: Open MCP Setup from the Command Palette to choose a setup action:
copy generic mcp.json, copy a Codex CLI command, copy a Claude Code command,
or open the Bifrost MCP docs. Bifrost: Copy MCP Config remains available when
you only want the generic JSON entry.
These commands are manual. The extension does not open MCP setup on activation,
does not mutate external host configuration, and does not prompt again after a
dismissal.
The MCP setup commands use bifrost.mcpServerPath to resolve a separately
installed Bifrost CLI. Its default is bifrost on PATH. Install the CLI or
configure this path before copying MCP setup.
The copied entry uses the current workspace root and starts a separate Bifrost
MCP process:
{
"mcpServers": {
"bifrost": {
"command": "/path/to/bifrost",
"args": ["--root", "/path/to/workspace", "--mcp", "searchtools"]
}
}
}
Do not point MCP hosts at the VS Code LSP process. The extension and MCP hosts
launch separate stdio processes using their respective server binaries.
Packaging
The extension uses esbuild to bundle runtime dependencies into
out/extension.js.
npm run compile
npx vsce package
The tag-driven release workflow publishes this same validated VSIX, including
the binary compatibility range above, to the GitHub Release, the Visual Studio
Marketplace, and Open VSX. Open VSX
publication uses the pinned ovsx dependency and requires:
- the verified
brokk Open VSX namespace;
- an access token with publishing rights stored as
OVSX_PAT in the protected
GitHub release environment; and
- the publisher's Open VSX account to have signed the current Publisher
Agreement.
The publisher checks the exact Open VSX version before uploading. A rerun is
successful only when the registry's advertised VSIX SHA-256 matches the
validated artifact; an existing version with different bytes fails closed.
After upload, the workflow waits for registry visibility and verifies the same
checksum again.
The .vscodeignore file excludes TypeScript sources and package manager
artifacts from the VSIX; run npm run compile before packaging.
Before publishing the VSIX, ensure:
package.json has bifrost.serverVersion set to the standalone server release version
without the leading v.
package.json has a compatible bifrost.minimumServerVersion and explicit
bifrost.allowPrerelease policy.
package.json has bifrost.archiveSha256 entries for every supported
extension target. These hashes are the VSIX trust anchor for downloaded
archives.
- The matching GitHub Release contains archive assets named
bifrost-lsp-v<version>-<target>.tar.gz on macOS/Linux and
bifrost-lsp-v<version>-<target>.zip on Windows.
- Each archive has a matching
.sha256 asset with the same filename plus
.sha256.
- The release workflow has completed for macOS universal, Linux x64/arm64, and
Windows x64/arm64 targets.
Debugging
The extension pipes Bifrost stderr into Output > Bifrost.
Useful settings:
{
"bifrost.debug": true,
"bifrost.slowRequestMs": 1000
}
bifrost.debug logs every LSP request/notification start and finish.
bifrost.slowRequestMs logs requests or notifications that take longer than
the configured threshold. Handler errors and panics are always logged with LSP
method context.
Managed server versions
This extension selects standalone server 0.1.0, linked to Bifrost 0.13.0.
Server, extension, and engine versions are independent. The engine is part of
the server binary; a server update replaces the engine pairing as a unit.
Managed binaries live in editor global storage by server version and platform.
A compatible cached server can start offline while the preferred release is
prepared. Update deferral and disabling automatic updates are respected.
The MCP setup commands use a separately installed bifrost CLI, configured
with bifrost.mcpServerPath. The managed bifrost-lsp binary supports LSP only.