Lsp Assist

v1.1.2

Language Server Protocol integration for OpenClaw agents. Enables precise code navigation: go-to-definition, find-references, hover type info, diagnostics, a...

0· 151·0 current·0 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for zgjq/lsp-assist.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Lsp Assist" (zgjq/lsp-assist) from ClawHub.
Skill page: https://clawhub.ai/zgjq/lsp-assist
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install lsp-assist

ClawHub CLI

Package manager switcher

npx clawhub@latest install lsp-assist
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name/description match the provided code and SKILL.md. The script spawns language servers (typescript-language-server, pyright) and implements LSP queries (goto, refs, hover, diag, symbols) — exactly what an LSP assist tool should do. No unrelated credentials, binaries, or config paths are requested.
Instruction Scope
Runtime instructions and the code restrict network binding to localhost and enforce project-root containment for file reads. The daemon exposes HTTP endpoints (including /shutdown) and accepts an optional Bearer token; by default no token is required, which makes the API accessible to any local process. This behaviour is expected for a local LSP daemon but is worth noting because local processes can query it without additional authorization unless you start with --token.
Install Mechanism
No install spec (instruction-only) and included Python script uses only the standard library. It relies on externally installed language-server binaries (npm/pip) as documented — expected for this purpose and lower-risk than arbitrary downloads.
Credentials
The skill requests no environment variables, credentials, or unusual config paths. The optional --token is a local auth mechanism documented in SKILL.md; nothing requests unrelated secrets.
Persistence & Privilege
The skill is not always: true and uses normal daemon/one-shot modes. It does not require persistent system privileges or modify other skills. Autonomous invocation by the agent is allowed by default (platform normal), and does not combine with other red flags here.
Assessment
This skill appears to do what it says: run local LSP servers and expose query endpoints on 127.0.0.1. Before installing/using: (1) ensure you install the declared language servers (typescript-language-server, pyright) from trusted sources; (2) run the daemon with --token if you want to prevent other local users/processes from using it; (3) run it with --root set to the intended project directory (the client enforces containment, but verify the path you pass is correct); (4) avoid binding to non-loopback interfaces or running this in environments where 127.0.0.1 may be reachable from other tenants (multi-tenant containers, reverse proxies) unless you understand the exposure. If you need higher assurance, review the full lsp_client.py file locally or run it in an isolated dev container.

Like a lobster shell, security has layers — review code before you run it.

latestvk973v56y6d92e8wxt0naws4d8h840w1f
151downloads
0stars
6versions
Updated 3w ago
v1.1.2
MIT-0

LSP Assist

Precise code navigation via Language Server Protocol.

Modes

ModeHowWhen to use
Daemon (recommended)daemon --port 9876 then HTTP queriesMultiple queries in a session (start once, query many)
One-shotgoto/refs/hover/diag/symbols directlySingle quick query, or scripting

Requirements

  • Runtime: Python 3.10+ (standard library only)
  • OS: Linux, macOS
  • Language servers (install separately):
    • TypeScript: npm i -g typescript-language-server typescript
    • Python: pip install pyright
  • Project config:
    • TypeScript: tsconfig.json in project root
    • Python: pyproject.toml or pyrightconfig.json

Security

Binding

Daemon binds to 127.0.0.1 only — no external/remote access:

server = HTTPServer(("127.0.0.1", port), DaemonHandler)

File Access Control

All file reads go through _open_file(), which enforces project-root containment:

def _open_file(self, filepath: str):
    path = Path(filepath).resolve()          # resolve symlinks, .., etc.
    if str(path) in self._opened_files:
        return                               # skip duplicate opens
    common = os.path.commonpath([str(path), self.root_path])
    if common != self.root_path:             # must be direct ancestor of root
        raise ValueError(f"File outside project root: {path}")
    # Only then: read file content and send didOpen to language server
  • Path.resolve() canonicalizes the path (resolves symlinks, .., ~)
  • os.path.commonpath rejects sibling dirs (e.g. /root/openclaw-backup/ when root is /root/openclaw)
  • Tested against: symlink escape, .. traversal, trailing-slash differences, sibling-prefix collision

Auth Token (optional)

When --token <secret> is passed, every HTTP request must include Authorization: Bearer <secret>:

def _check_auth(self) -> bool:
    expected = getattr(self.server, "auth_token", None)
    if expected is None:
        return True                          # no token required
    header = self.headers.get("Authorization", "")
    if header == f"Bearer {expected}":
        return True
    self._respond({"error": "unauthorized"}, 401)
    return False
  • Checked in both do_GET and do_POST before any handler logic
  • Without --token, daemon is open on localhost (intended for local single-user use)

Shutdown Handling

elif self.path == "/shutdown":
    self._respond({"status": "shutting down"})
    threading.Thread(target=lambda: (time.sleep(0.5), os._exit(0)), daemon=True).start()

Responds first, then exits after 0.5s delay to ensure the HTTP response is flushed.

Process Isolation

  • One-shot mode: fresh server per query, auto-terminates (15s timeout)
  • Daemon mode: persistent server, but is_alive() check returns 503 if the language server crashes
  • Language server communication is local stdio only

Quick Reference

Daemon Mode (recommended for multi-query)

# Start daemon (blocks, run in background or separate terminal)
python3 scripts/lsp_client.py daemon --lang typescript --root /path/to/project --port 9876

# Start with auth token (requests need Bearer token)
python3 scripts/lsp_client.py daemon --lang typescript --root /path/to/project --port 9876 --token mysecret

# Query via HTTP (all output JSON)
curl -s http://127.0.0.1:9876/goto   -d '{"file":"src/main.ts","line":10,"col":5}'
curl -s http://127.0.0.1:9876/refs   -d '{"file":"src/main.ts","line":10,"col":5}'
curl -s http://127.0.0.1:9876/hover  -d '{"file":"src/main.ts","line":10,"col":5}'
curl -s http://127.0.0.1:9876/diag   -d '{"file":"src/main.ts"}'
curl -s http://127.0.0.1:9876/symbols -d '{"query":"UserService"}'
curl -s http://127.0.0.1:9876/shutdown
curl -s http://127.0.0.1:9876/ping   # health check

# With auth token
curl -s -H "Authorization: Bearer mysecret" http://127.0.0.1:9876/ping

One-shot Mode

ActionCommand
Go to definitionpython3 scripts/lsp_client.py --lang ts --root <dir> goto --file <f> --line <n> --col <n>
Find referencespython3 scripts/lsp_client.py --lang ts --root <dir> refs --file <f> --line <n> --col <n>
Hover type infopython3 scripts/lsp_client.py --lang ts --root <dir> hover --file <f> --line <n> --col <n>
Diagnosticspython3 scripts/lsp_client.py --lang ts --root <dir> diag --file <f>
Symbol searchpython3 scripts/lsp_client.py --lang ts --root <dir> symbols [--query <text>]

Language shorthand: --lang typescript or --lang ts or --lang python.

Output Format

All commands output JSON for structured consumption:

// goto / refs
[{"file": "/path/to/file.ts", "line": 42, "col": 10}]

// hover
"function foo(bar: string): number"

// diag
[{"severity": "ERROR", "line": 10, "message": "Cannot find name 'x'"}]

// symbols
[{"name": "UserService", "kind": 5, "file": "/path/to/file.ts", "line": 12, "container": "models"}]

When to Use vs Grep

ScenarioUse
"Where is this function defined?"LSP goto
"Who calls this function?"LSP refs
"What type is this variable?"LSP hover
"Any compile errors?"LSP diag
"Find all classes matching X"LSP symbols
"Search for text pattern 'TODO'"grep
"Find all .json files"glob
"Search across non-code files"grep

Supported Languages

LanguageServerInstall
TypeScript/JavaScripttypescript-language-servernpm i -g typescript-language-server typescript
Pythonpyrightpip install pyright

Adding a language: edit SERVERS dict in lsp_client.py — add the server command and file extensions.

Comments

Loading comments...