@treedy/lsp-mcp 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,6 +97,7 @@ Replace `{lang}` with `python` or `typescript`.
97
97
  |------|-------------|
98
98
  | `list_backends` | List available backends and their status |
99
99
  | `start_backend` | Install and start a backend (downloads if needed) |
100
+ | `update_backend` | Update a backend to the latest version |
100
101
  | `status` | Overall server and backend status with versions |
101
102
  | `check_versions` | Detailed version info for server and all backends |
102
103
  | `switch_python_backend` | Switch Python provider |
@@ -120,6 +121,11 @@ Replace `{lang}` with `python` or `typescript`.
120
121
  typescript_definition file=/path/to/file.ts line=15 column=10
121
122
  ```
122
123
 
124
+ 4. **Update a backend** (when new version is available):
125
+ ```
126
+ update_backend language=python
127
+ ```
128
+
123
129
  ## Available Prompts (Skills)
124
130
 
125
131
  The server exposes skill documentation as MCP prompts that agents can request:
package/dist/index.js CHANGED
@@ -19843,7 +19843,9 @@ function loadConfig() {
19843
19843
  const pythonEnabled = getEnvBool("LSP_MCP_PYTHON_ENABLED", true);
19844
19844
  const pythonProvider = getEnvString("LSP_MCP_PYTHON_PROVIDER", "python-lsp-mcp");
19845
19845
  const typescriptEnabled = getEnvBool("LSP_MCP_TYPESCRIPT_ENABLED", true);
19846
+ const vueEnabled = getEnvBool("LSP_MCP_VUE_ENABLED", true);
19846
19847
  const autoUpdate = getEnvBool("LSP_MCP_AUTO_UPDATE", true);
19848
+ const eagerStart = getEnvBool("LSP_MCP_EAGER_START", false);
19847
19849
  return {
19848
19850
  python: {
19849
19851
  enabled: pythonEnabled,
@@ -19852,7 +19854,11 @@ function loadConfig() {
19852
19854
  typescript: {
19853
19855
  enabled: typescriptEnabled
19854
19856
  },
19855
- autoUpdate
19857
+ vue: {
19858
+ enabled: vueEnabled
19859
+ },
19860
+ autoUpdate,
19861
+ eagerStart
19856
19862
  };
19857
19863
  }
19858
19864
  function getEnvBool(name, defaultValue) {
@@ -19890,6 +19896,14 @@ function getBackendCommand(language, config2) {
19890
19896
  command: "npx",
19891
19897
  args: autoUpdate ? ["--yes", "@treedy/typescript-lsp-mcp@latest"] : ["@treedy/typescript-lsp-mcp@latest"]
19892
19898
  };
19899
+ } else if (language === "vue") {
19900
+ if (!config2.vue.enabled)
19901
+ return null;
19902
+ return {
19903
+ enabled: true,
19904
+ command: "npx",
19905
+ args: autoUpdate ? ["--yes", "@treedy/vue-lsp-mcp@latest"] : ["@treedy/vue-lsp-mcp@latest"]
19906
+ };
19893
19907
  }
19894
19908
  return null;
19895
19909
  }
@@ -20673,6 +20687,8 @@ class BackendManager {
20673
20687
  languages.push("python");
20674
20688
  if (this.config.typescript.enabled)
20675
20689
  languages.push("typescript");
20690
+ if (this.config.vue.enabled)
20691
+ languages.push("vue");
20676
20692
  await Promise.all(languages.map(async (lang) => {
20677
20693
  try {
20678
20694
  const tools = await this.getTools(lang);
@@ -20702,6 +20718,9 @@ class BackendManager {
20702
20718
  if (this.config.typescript.enabled && !this.backends.has("typescript")) {
20703
20719
  status["typescript"] = { status: "not_started", tools: 0, restartCount: 0 };
20704
20720
  }
20721
+ if (this.config.vue.enabled && !this.backends.has("vue")) {
20722
+ status["vue"] = { status: "not_started", tools: 0, restartCount: 0 };
20723
+ }
20705
20724
  return status;
20706
20725
  }
20707
20726
  getVersions() {
@@ -20711,6 +20730,8 @@ class BackendManager {
20711
20730
  languages.push("python");
20712
20731
  if (this.config.typescript.enabled)
20713
20732
  languages.push("typescript");
20733
+ if (this.config.vue.enabled)
20734
+ languages.push("vue");
20714
20735
  for (const lang of languages) {
20715
20736
  const backendConfig = getBackendCommand(lang, this.config);
20716
20737
  const state = this.backends.get(lang);
@@ -20724,6 +20745,24 @@ class BackendManager {
20724
20745
  }
20725
20746
  return versions2;
20726
20747
  }
20748
+ async restartBackend(language) {
20749
+ const existing = this.backends.get(language);
20750
+ const oldVersion = existing?.serverInfo?.version ?? null;
20751
+ if (existing) {
20752
+ console.error(`[BackendManager] Stopping ${language} for update...`);
20753
+ try {
20754
+ await existing.transport.close();
20755
+ await existing.client.close();
20756
+ } catch (error2) {
20757
+ console.error(`[BackendManager] Error closing ${language}:`, error2);
20758
+ }
20759
+ this.backends.delete(language);
20760
+ }
20761
+ console.error(`[BackendManager] Starting fresh ${language} backend...`);
20762
+ const state = await this.startBackend(language);
20763
+ const newVersion = state.serverInfo?.version ?? null;
20764
+ return { oldVersion, newVersion };
20765
+ }
20727
20766
  async shutdown() {
20728
20767
  console.error("[BackendManager] Shutting down all backends...");
20729
20768
  const shutdownPromises = Array.from(this.backends.entries()).map(async ([lang, state]) => {
@@ -20767,6 +20806,9 @@ async function status(backendManager, config2) {
20767
20806
  typescript: {
20768
20807
  enabled: config2.typescript.enabled
20769
20808
  },
20809
+ vue: {
20810
+ enabled: config2.vue.enabled
20811
+ },
20770
20812
  autoUpdate: config2.autoUpdate
20771
20813
  },
20772
20814
  backends: backendStatus,
@@ -20824,6 +20866,13 @@ async function checkVersions(backendManager, config2) {
20824
20866
  registry: "npm",
20825
20867
  command: "npx --yes @treedy/typescript-lsp-mcp@latest"
20826
20868
  }
20869
+ },
20870
+ vue: {
20871
+ "vue-lsp-mcp": {
20872
+ registry: "npm",
20873
+ command: "npx --yes @treedy/vue-lsp-mcp@latest",
20874
+ description: "Vue SFC support via Volar"
20875
+ }
20827
20876
  }
20828
20877
  },
20829
20878
  howToUpdate: config2.autoUpdate ? "Restart the server to fetch latest backend versions automatically." : "Set LSP_MCP_AUTO_UPDATE=true and restart, or manually update with commands above."
@@ -20866,13 +20915,21 @@ async function listBackends(backendManager, config2) {
20866
20915
  tools: backendStatus.typescript?.tools || 0,
20867
20916
  description: "TypeScript/JavaScript code intelligence",
20868
20917
  startCommand: "Use start_backend tool with language='typescript'"
20918
+ },
20919
+ {
20920
+ name: "vue",
20921
+ enabled: config2.vue.enabled,
20922
+ status: backendStatus.vue?.status || "not_started",
20923
+ tools: backendStatus.vue?.tools || 0,
20924
+ description: "Vue Single File Component (.vue) code intelligence via Volar",
20925
+ startCommand: "Use start_backend tool with language='vue'"
20869
20926
  }
20870
20927
  ];
20871
20928
  const result = {
20872
20929
  backends,
20873
20930
  usage: {
20874
- start: "Call start_backend with language='python' or 'typescript' to install and start a backend",
20875
- tools: "Once started, backend tools will be available as {language}_{tool} (e.g., python_hover)"
20931
+ start: "Call start_backend with language='python', 'typescript', or 'vue' to install and start a backend",
20932
+ tools: "Once started, backend tools will be available as {language}_{tool} (e.g., python_hover, vue_hover)"
20876
20933
  }
20877
20934
  };
20878
20935
  return {
@@ -20880,7 +20937,7 @@ async function listBackends(backendManager, config2) {
20880
20937
  };
20881
20938
  }
20882
20939
  var startBackendSchema = {
20883
- language: exports_external.enum(["python", "typescript"]).describe("The backend to start")
20940
+ language: exports_external.enum(["python", "typescript", "vue"]).describe("The backend to start")
20884
20941
  };
20885
20942
  async function startBackend(language, backendManager, config2, registerToolsCallback) {
20886
20943
  if (language === "python" && !config2.python.enabled) {
@@ -20907,6 +20964,18 @@ async function startBackend(language, backendManager, config2, registerToolsCall
20907
20964
  }]
20908
20965
  };
20909
20966
  }
20967
+ if (language === "vue" && !config2.vue.enabled) {
20968
+ return {
20969
+ content: [{
20970
+ type: "text",
20971
+ text: JSON.stringify({
20972
+ success: false,
20973
+ error: "Vue backend is disabled",
20974
+ hint: "Set LSP_MCP_VUE_ENABLED=true to enable"
20975
+ }, null, 2)
20976
+ }]
20977
+ };
20978
+ }
20910
20979
  try {
20911
20980
  const toolCount = await registerToolsCallback(language);
20912
20981
  const backendStatus = backendManager.getStatus();
@@ -20940,6 +21009,80 @@ async function startBackend(language, backendManager, config2, registerToolsCall
20940
21009
  };
20941
21010
  }
20942
21011
  }
21012
+ var updateBackendSchema = {
21013
+ language: exports_external.enum(["python", "typescript", "vue"]).describe("The backend to update")
21014
+ };
21015
+ async function updateBackend(language, backendManager, config2, updateCallback) {
21016
+ if (language === "python" && !config2.python.enabled) {
21017
+ return {
21018
+ content: [{
21019
+ type: "text",
21020
+ text: JSON.stringify({
21021
+ success: false,
21022
+ error: "Python backend is disabled",
21023
+ hint: "Set LSP_MCP_PYTHON_ENABLED=true to enable"
21024
+ }, null, 2)
21025
+ }]
21026
+ };
21027
+ }
21028
+ if (language === "typescript" && !config2.typescript.enabled) {
21029
+ return {
21030
+ content: [{
21031
+ type: "text",
21032
+ text: JSON.stringify({
21033
+ success: false,
21034
+ error: "TypeScript backend is disabled",
21035
+ hint: "Set LSP_MCP_TYPESCRIPT_ENABLED=true to enable"
21036
+ }, null, 2)
21037
+ }]
21038
+ };
21039
+ }
21040
+ if (language === "vue" && !config2.vue.enabled) {
21041
+ return {
21042
+ content: [{
21043
+ type: "text",
21044
+ text: JSON.stringify({
21045
+ success: false,
21046
+ error: "Vue backend is disabled",
21047
+ hint: "Set LSP_MCP_VUE_ENABLED=true to enable"
21048
+ }, null, 2)
21049
+ }]
21050
+ };
21051
+ }
21052
+ try {
21053
+ const { oldVersion, newVersion } = await updateCallback(language);
21054
+ const backendStatus = backendManager.getStatus();
21055
+ const status2 = backendStatus[language];
21056
+ const updated = oldVersion !== newVersion;
21057
+ return {
21058
+ content: [{
21059
+ type: "text",
21060
+ text: JSON.stringify({
21061
+ success: true,
21062
+ language,
21063
+ updated,
21064
+ oldVersion,
21065
+ newVersion,
21066
+ serverName: status2?.serverName,
21067
+ tools: status2?.tools,
21068
+ message: updated ? `${language} backend updated from ${oldVersion} to ${newVersion}.` : `${language} backend is already at the latest version (${newVersion}).`
21069
+ }, null, 2)
21070
+ }]
21071
+ };
21072
+ } catch (error2) {
21073
+ return {
21074
+ content: [{
21075
+ type: "text",
21076
+ text: JSON.stringify({
21077
+ success: false,
21078
+ language,
21079
+ error: String(error2),
21080
+ hint: "Check network connection and try again"
21081
+ }, null, 2)
21082
+ }]
21083
+ };
21084
+ }
21085
+ }
20943
21086
 
20944
21087
  // src/prompts.ts
20945
21088
  var skillsContent = {
@@ -21520,6 +21663,7 @@ function registerBackendTools(language, tools) {
21520
21663
  console.error(`[lsp-mcp] Registered ${namespacedName}`);
21521
21664
  count++;
21522
21665
  }
21666
+ server.sendToolListChanged();
21523
21667
  return count;
21524
21668
  }
21525
21669
  async function startAndRegisterBackend(language) {
@@ -21540,6 +21684,19 @@ async function startAndRegisterBackend(language) {
21540
21684
  throw error2;
21541
21685
  }
21542
21686
  }
21687
+ async function updateAndRestartBackend(language) {
21688
+ console.error(`[lsp-mcp] Updating ${language} backend...`);
21689
+ const result = await backendManager.restartBackend(language);
21690
+ if (startedBackends.has(language)) {
21691
+ console.error(`[lsp-mcp] ${language} backend updated, tools still available`);
21692
+ } else {
21693
+ const tools = await backendManager.getTools(language);
21694
+ registerBackendTools(language, tools);
21695
+ startedBackends.add(language);
21696
+ console.error(`[lsp-mcp] ${language} backend updated and ${tools.length} tools registered`);
21697
+ }
21698
+ return result;
21699
+ }
21543
21700
  server.registerTool("status", { description: "Get status of all LSP backends and server configuration" }, async () => status(backendManager, config2));
21544
21701
  server.registerTool("check_versions", { description: "Check versions of all backends and server. Shows installed versions and how to check for updates." }, async () => checkVersions(backendManager, config2));
21545
21702
  server.registerTool("switch_python_backend", {
@@ -21553,6 +21710,10 @@ server.registerTool("start_backend", {
21553
21710
  description: "Start a backend and register its tools. This will download and install the backend if needed, then make its tools available.",
21554
21711
  inputSchema: startBackendSchema
21555
21712
  }, async ({ language }) => startBackend(language, backendManager, config2, startAndRegisterBackend));
21713
+ server.registerTool("update_backend", {
21714
+ description: "Update a backend to the latest version. This will restart the backend with the newest version available.",
21715
+ inputSchema: updateBackendSchema
21716
+ }, async ({ language }) => updateBackend(language, backendManager, config2, updateAndRestartBackend));
21556
21717
  async function gracefulShutdown(signal) {
21557
21718
  console.error(`
21558
21719
  [lsp-mcp] Received ${signal}, shutting down gracefully...`);
@@ -21573,15 +21734,42 @@ async function main() {
21573
21734
  console.error(` Version: ${packageJson.version}`);
21574
21735
  console.error(" Python:", config2.python.enabled ? `enabled (${config2.python.provider})` : "disabled");
21575
21736
  console.error(" TypeScript:", config2.typescript.enabled ? "enabled" : "disabled");
21576
- console.error("");
21577
- console.error("Backends are loaded on-demand. Use these tools to get started:");
21578
- console.error(" - list_backends: See available backends and their status");
21579
- console.error(" - start_backend: Install and start a backend (e.g., start_backend language=python)");
21580
- console.error("");
21581
- console.error("Prompts available: code-navigation, refactoring, code-analysis, lsp-rules, lsp-quick-start");
21737
+ console.error(" Vue:", config2.vue.enabled ? "enabled" : "disabled");
21738
+ console.error(" Eager Start:", config2.eagerStart ? "enabled" : "disabled");
21582
21739
  console.error("");
21583
21740
  const transport = new StdioServerTransport;
21584
21741
  await server.connect(transport);
21742
+ if (config2.eagerStart) {
21743
+ console.error("Starting all enabled backends...");
21744
+ const languages = [];
21745
+ if (config2.python.enabled)
21746
+ languages.push("python");
21747
+ if (config2.typescript.enabled)
21748
+ languages.push("typescript");
21749
+ if (config2.vue.enabled)
21750
+ languages.push("vue");
21751
+ const results = await Promise.allSettled(languages.map(async (lang) => {
21752
+ try {
21753
+ const count = await startAndRegisterBackend(lang);
21754
+ return { lang, count };
21755
+ } catch (error2) {
21756
+ console.error(`[lsp-mcp] Failed to start ${lang}:`, error2);
21757
+ return { lang, error: error2 };
21758
+ }
21759
+ }));
21760
+ for (const result of results) {
21761
+ if (result.status === "fulfilled" && "count" in result.value) {
21762
+ console.error(` ${result.value.lang}: ${result.value.count} tools registered`);
21763
+ } else if (result.status === "fulfilled" && "error" in result.value) {
21764
+ console.error(` ${result.value.lang}: failed to start`);
21765
+ }
21766
+ }
21767
+ } else {
21768
+ console.error("Backends are loaded on-demand. Use these tools to get started:");
21769
+ console.error(" - list_backends: See available backends and their status");
21770
+ console.error(" - start_backend: Install and start a backend (e.g., start_backend language=python)");
21771
+ }
21772
+ console.error("");
21585
21773
  console.error("Ready");
21586
21774
  }
21587
21775
  main().catch((error2) => {
@@ -21589,4 +21777,4 @@ main().catch((error2) => {
21589
21777
  process.exit(1);
21590
21778
  });
21591
21779
 
21592
- //# debugId=A15518B7EDCDD67064756E2164756E21
21780
+ //# debugId=93725E95ED75445864756E2164756E21