Skip to content

Add "headless" mode#116

Open
rickbatka wants to merge 7 commits intoisaacphi:mainfrom
rickbatka:rbatka/headless
Open

Add "headless" mode#116
rickbatka wants to merge 7 commits intoisaacphi:mainfrom
rickbatka:rbatka/headless

Conversation

@rickbatka
Copy link

Adds "headless" mode, allowing the MCP to talk to an already-running LSP, such as one running in your IDE. Does not set up file watchers in this mode (handled better by the IDE's LSP integration), which has the nice bonus of working around the "too many open files" bug in very large repos.

Integration tests updated for Go, which is the only one I can reliably test on my machine.

Instructions

  1. Add the necessary arguments to Gopls to tell it to listen over http. For example, in VSCode / Cursor in .vscode/settings.json:
...(snip)...
    "go.useLanguageServer": true,
    "go.languageServerFlags": [
        "-remote=localhost:6061"
    ],
...(snip)...
  1. Launch mcp-language-server with the new arg --lsp-connect=localhost:6061 (using whatever hostname:port combo you used to start your Gopls session)

Benefits

In headless mode, the Gopls server that's already running in your IDE can also be used to power the MCP, instead of starting another one in parallel. This can simplify your setup: If you've configured the language server to your liking in your IDE, then your MCP will be sure to use the same LSP as you use in your IDE.

In VSCode / Cursos, you may want to ignore some folders to get better performance for your LSP:

    "gopls": {
        "build.directoryFilters": [
            // this speeds up Go static analysis significantly
            // add/remove the stuff you do/don't care about
            "-",
            "-**/node_modules",
...snip...

When you connect to your already-running LSP, you get the same settings applied in your MCP-LSP session, and can benefit from speedups like directory ignore filters.

Testing

Integrations tests for Go were updated to run in both headless and regular mode. Other languages each require different approaches to getting LSPs running in the background, which may be worth the effort if folks using those languages could add their implementations.

I had to update the snapshot files for the Go integration tests, but this might be due to Go version mismatches. I'm happy to revert those files if it makes this easier to merge; I just wanted to get it all running locally so I could make sure I updated the tests properly.

I also tested in a separate project that previously was hitting the "too many open files" bug; it works around that bug and now the MCP server works great! I have Claude / Cursor using the LSP for renaming and it seems to work quite well!

{"source":"codelens"}

[2] Location: Lines 1-1
Title: Run govulncheck
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why my local finds 7 codelenses as opposed to 6 - happy to revert this file if it messes with CI, this is just what I needed to get it to pass on my machine.

@@ -1,5 +1,5 @@
```go
type SharedStruct struct { // size=56 (0x38)
type SharedStruct struct { // size=56 (0x38), class=64 (0x40)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as other snapshot - this is what the LSP returns on my machine; happy to revert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments