@treedy/lsp-mcp 0.1.2 → 0.1.4

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/dist/index.js CHANGED
@@ -19843,6 +19843,7 @@ 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);
19847
19848
  return {
19848
19849
  python: {
@@ -19852,6 +19853,9 @@ function loadConfig() {
19852
19853
  typescript: {
19853
19854
  enabled: typescriptEnabled
19854
19855
  },
19856
+ vue: {
19857
+ enabled: vueEnabled
19858
+ },
19855
19859
  autoUpdate
19856
19860
  };
19857
19861
  }
@@ -19890,6 +19894,14 @@ function getBackendCommand(language, config2) {
19890
19894
  command: "npx",
19891
19895
  args: autoUpdate ? ["--yes", "@treedy/typescript-lsp-mcp@latest"] : ["@treedy/typescript-lsp-mcp@latest"]
19892
19896
  };
19897
+ } else if (language === "vue") {
19898
+ if (!config2.vue.enabled)
19899
+ return null;
19900
+ return {
19901
+ enabled: true,
19902
+ command: "npx",
19903
+ args: autoUpdate ? ["--yes", "@treedy/vue-lsp-mcp@latest"] : ["@treedy/vue-lsp-mcp@latest"]
19904
+ };
19893
19905
  }
19894
19906
  return null;
19895
19907
  }
@@ -20673,6 +20685,8 @@ class BackendManager {
20673
20685
  languages.push("python");
20674
20686
  if (this.config.typescript.enabled)
20675
20687
  languages.push("typescript");
20688
+ if (this.config.vue.enabled)
20689
+ languages.push("vue");
20676
20690
  await Promise.all(languages.map(async (lang) => {
20677
20691
  try {
20678
20692
  const tools = await this.getTools(lang);
@@ -20702,6 +20716,9 @@ class BackendManager {
20702
20716
  if (this.config.typescript.enabled && !this.backends.has("typescript")) {
20703
20717
  status["typescript"] = { status: "not_started", tools: 0, restartCount: 0 };
20704
20718
  }
20719
+ if (this.config.vue.enabled && !this.backends.has("vue")) {
20720
+ status["vue"] = { status: "not_started", tools: 0, restartCount: 0 };
20721
+ }
20705
20722
  return status;
20706
20723
  }
20707
20724
  getVersions() {
@@ -20711,6 +20728,8 @@ class BackendManager {
20711
20728
  languages.push("python");
20712
20729
  if (this.config.typescript.enabled)
20713
20730
  languages.push("typescript");
20731
+ if (this.config.vue.enabled)
20732
+ languages.push("vue");
20714
20733
  for (const lang of languages) {
20715
20734
  const backendConfig = getBackendCommand(lang, this.config);
20716
20735
  const state = this.backends.get(lang);
@@ -20724,6 +20743,24 @@ class BackendManager {
20724
20743
  }
20725
20744
  return versions2;
20726
20745
  }
20746
+ async restartBackend(language) {
20747
+ const existing = this.backends.get(language);
20748
+ const oldVersion = existing?.serverInfo?.version ?? null;
20749
+ if (existing) {
20750
+ console.error(`[BackendManager] Stopping ${language} for update...`);
20751
+ try {
20752
+ await existing.transport.close();
20753
+ await existing.client.close();
20754
+ } catch (error2) {
20755
+ console.error(`[BackendManager] Error closing ${language}:`, error2);
20756
+ }
20757
+ this.backends.delete(language);
20758
+ }
20759
+ console.error(`[BackendManager] Starting fresh ${language} backend...`);
20760
+ const state = await this.startBackend(language);
20761
+ const newVersion = state.serverInfo?.version ?? null;
20762
+ return { oldVersion, newVersion };
20763
+ }
20727
20764
  async shutdown() {
20728
20765
  console.error("[BackendManager] Shutting down all backends...");
20729
20766
  const shutdownPromises = Array.from(this.backends.entries()).map(async ([lang, state]) => {
@@ -20742,84 +20779,6 @@ class BackendManager {
20742
20779
  }
20743
20780
  }
20744
20781
 
20745
- // src/backends/python.ts
20746
- var pythonPositionSchema = {
20747
- file: exports_external.string().describe("Absolute path to the Python file"),
20748
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
20749
- column: exports_external.number().int().positive().describe("Column number (1-based)")
20750
- };
20751
- var pythonToolDescriptions = {
20752
- hover: "Get type information and documentation at a specific position in a Python file",
20753
- definition: "Go to definition of a symbol at a specific position in a Python file",
20754
- references: "Find all references to a symbol at a specific position in a Python file",
20755
- completions: "Get code completion suggestions at a specific position in a Python file",
20756
- diagnostics: "Get type errors and warnings for a Python file or directory",
20757
- symbols: "Extract symbols (classes, functions, methods, variables) from a Python file",
20758
- rename: "Rename a symbol and update all references in Python files",
20759
- search: "Search for a regex pattern in Python files",
20760
- signature_help: "Get function signature help at a specific position in a Python file",
20761
- update_document: "Update file content for incremental analysis in Python",
20762
- status: "Check Python/Pyright environment status",
20763
- move: "Move a function or class to another Python module",
20764
- change_signature: "Change the signature of a Python function",
20765
- function_signature: "Get the current signature of a Python function",
20766
- set_backend: "Set the backend (rope/pyright) for Python code analysis",
20767
- set_python_path: "Set the Python interpreter path for code analysis"
20768
- };
20769
-
20770
- // src/backends/typescript.ts
20771
- var typescriptPositionSchema = {
20772
- file: exports_external.string().describe("Absolute path to the TypeScript/JavaScript file"),
20773
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
20774
- column: exports_external.number().int().positive().describe("Column number (1-based)")
20775
- };
20776
- var typescriptToolDescriptions = {
20777
- hover: "Get type information and documentation at a specific position in a TypeScript/JavaScript file",
20778
- definition: "Go to definition of a symbol at a specific position",
20779
- references: "Find all references to a symbol at a specific position",
20780
- completions: "Get code completion suggestions at a specific position",
20781
- diagnostics: "Get type errors and warnings for a TypeScript/JavaScript file",
20782
- symbols: "Extract symbols (classes, functions, methods, variables) from a file",
20783
- rename: "Preview renaming a symbol (shows all locations that would be renamed)",
20784
- search: "Search for a regex pattern in TypeScript/JavaScript files",
20785
- signature_help: "Get function signature help at a specific position",
20786
- update_document: "Update file content for incremental analysis",
20787
- status: "Check TypeScript environment status for a project"
20788
- };
20789
-
20790
- // src/tools/schemas.ts
20791
- var positionArgs = {
20792
- file: exports_external.string().describe("Absolute path to the file"),
20793
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
20794
- column: exports_external.number().int().positive().describe("Column number (1-based)")
20795
- };
20796
- var searchArgs = {
20797
- pattern: exports_external.string().describe("The regex pattern to search for"),
20798
- path: exports_external.string().optional().describe("Directory or file to search in"),
20799
- glob: exports_external.string().optional().describe("Glob pattern to filter files"),
20800
- caseSensitive: exports_external.boolean().default(true).describe("Whether the search is case sensitive"),
20801
- maxResults: exports_external.number().int().positive().default(50).describe("Maximum number of results")
20802
- };
20803
- var diagnosticsArgs = {
20804
- path: exports_external.string().describe("Path to a file or directory to check")
20805
- };
20806
- var renameArgs = {
20807
- ...positionArgs,
20808
- newName: exports_external.string().describe("New name for the symbol")
20809
- };
20810
- var symbolsArgs = {
20811
- file: exports_external.string().describe("Absolute path to the file"),
20812
- query: exports_external.string().optional().describe("Optional filter query for symbol names")
20813
- };
20814
- var updateDocumentArgs = {
20815
- file: exports_external.string().describe("Absolute path to the file"),
20816
- content: exports_external.string().describe("New content for the file")
20817
- };
20818
- var completionsArgs = {
20819
- ...positionArgs,
20820
- limit: exports_external.number().int().positive().default(20).describe("Maximum number of completions to return")
20821
- };
20822
-
20823
20782
  // src/tools/meta.ts
20824
20783
  import { readFileSync } from "fs";
20825
20784
  import { dirname, join } from "path";
@@ -20845,6 +20804,9 @@ async function status(backendManager, config2) {
20845
20804
  typescript: {
20846
20805
  enabled: config2.typescript.enabled
20847
20806
  },
20807
+ vue: {
20808
+ enabled: config2.vue.enabled
20809
+ },
20848
20810
  autoUpdate: config2.autoUpdate
20849
20811
  },
20850
20812
  backends: backendStatus,
@@ -20855,8 +20817,9 @@ async function status(backendManager, config2) {
20855
20817
  status: v.status
20856
20818
  })),
20857
20819
  usage: {
20858
- namespaced: "Use python/hover or typescript/hover to specify language",
20859
- auto_infer: "Or provide a file path and language will be inferred from extension"
20820
+ list: "Use list_backends to see available backends",
20821
+ start: "Use start_backend to install and start a backend",
20822
+ tools: "Once started, tools are available as python_hover, typescript_definition, etc."
20860
20823
  }
20861
20824
  };
20862
20825
  return {
@@ -20901,6 +20864,13 @@ async function checkVersions(backendManager, config2) {
20901
20864
  registry: "npm",
20902
20865
  command: "npx --yes @treedy/typescript-lsp-mcp@latest"
20903
20866
  }
20867
+ },
20868
+ vue: {
20869
+ "vue-lsp-mcp": {
20870
+ registry: "npm",
20871
+ command: "npx --yes @treedy/vue-lsp-mcp@latest",
20872
+ description: "Vue SFC support via Volar"
20873
+ }
20904
20874
  }
20905
20875
  },
20906
20876
  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."
@@ -20924,6 +20894,193 @@ function switchPythonBackend(provider) {
20924
20894
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
20925
20895
  };
20926
20896
  }
20897
+ async function listBackends(backendManager, config2) {
20898
+ const backendStatus = backendManager.getStatus();
20899
+ const backends = [
20900
+ {
20901
+ name: "python",
20902
+ enabled: config2.python.enabled,
20903
+ provider: config2.python.provider,
20904
+ status: backendStatus.python?.status || "not_started",
20905
+ tools: backendStatus.python?.tools || 0,
20906
+ description: "Python code intelligence (hover, definition, references, refactoring)",
20907
+ startCommand: "Use start_backend tool with language='python'"
20908
+ },
20909
+ {
20910
+ name: "typescript",
20911
+ enabled: config2.typescript.enabled,
20912
+ status: backendStatus.typescript?.status || "not_started",
20913
+ tools: backendStatus.typescript?.tools || 0,
20914
+ description: "TypeScript/JavaScript code intelligence",
20915
+ startCommand: "Use start_backend tool with language='typescript'"
20916
+ },
20917
+ {
20918
+ name: "vue",
20919
+ enabled: config2.vue.enabled,
20920
+ status: backendStatus.vue?.status || "not_started",
20921
+ tools: backendStatus.vue?.tools || 0,
20922
+ description: "Vue Single File Component (.vue) code intelligence via Volar",
20923
+ startCommand: "Use start_backend tool with language='vue'"
20924
+ }
20925
+ ];
20926
+ const result = {
20927
+ backends,
20928
+ usage: {
20929
+ start: "Call start_backend with language='python', 'typescript', or 'vue' to install and start a backend",
20930
+ tools: "Once started, backend tools will be available as {language}_{tool} (e.g., python_hover, vue_hover)"
20931
+ }
20932
+ };
20933
+ return {
20934
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
20935
+ };
20936
+ }
20937
+ var startBackendSchema = {
20938
+ language: exports_external.enum(["python", "typescript", "vue"]).describe("The backend to start")
20939
+ };
20940
+ async function startBackend(language, backendManager, config2, registerToolsCallback) {
20941
+ if (language === "python" && !config2.python.enabled) {
20942
+ return {
20943
+ content: [{
20944
+ type: "text",
20945
+ text: JSON.stringify({
20946
+ success: false,
20947
+ error: "Python backend is disabled",
20948
+ hint: "Set LSP_MCP_PYTHON_ENABLED=true to enable"
20949
+ }, null, 2)
20950
+ }]
20951
+ };
20952
+ }
20953
+ if (language === "typescript" && !config2.typescript.enabled) {
20954
+ return {
20955
+ content: [{
20956
+ type: "text",
20957
+ text: JSON.stringify({
20958
+ success: false,
20959
+ error: "TypeScript backend is disabled",
20960
+ hint: "Set LSP_MCP_TYPESCRIPT_ENABLED=true to enable"
20961
+ }, null, 2)
20962
+ }]
20963
+ };
20964
+ }
20965
+ if (language === "vue" && !config2.vue.enabled) {
20966
+ return {
20967
+ content: [{
20968
+ type: "text",
20969
+ text: JSON.stringify({
20970
+ success: false,
20971
+ error: "Vue backend is disabled",
20972
+ hint: "Set LSP_MCP_VUE_ENABLED=true to enable"
20973
+ }, null, 2)
20974
+ }]
20975
+ };
20976
+ }
20977
+ try {
20978
+ const toolCount = await registerToolsCallback(language);
20979
+ const backendStatus = backendManager.getStatus();
20980
+ const status2 = backendStatus[language];
20981
+ return {
20982
+ content: [{
20983
+ type: "text",
20984
+ text: JSON.stringify({
20985
+ success: true,
20986
+ language,
20987
+ status: status2?.status,
20988
+ serverName: status2?.serverName,
20989
+ version: status2?.version,
20990
+ toolsRegistered: toolCount,
20991
+ message: `${language} backend started successfully. ${toolCount} tools are now available.`,
20992
+ usage: `Tools are available as ${language}_hover, ${language}_definition, etc.`
20993
+ }, null, 2)
20994
+ }]
20995
+ };
20996
+ } catch (error2) {
20997
+ return {
20998
+ content: [{
20999
+ type: "text",
21000
+ text: JSON.stringify({
21001
+ success: false,
21002
+ language,
21003
+ error: String(error2),
21004
+ hint: "Check if the backend package is available and network connection is working"
21005
+ }, null, 2)
21006
+ }]
21007
+ };
21008
+ }
21009
+ }
21010
+ var updateBackendSchema = {
21011
+ language: exports_external.enum(["python", "typescript", "vue"]).describe("The backend to update")
21012
+ };
21013
+ async function updateBackend(language, backendManager, config2, updateCallback) {
21014
+ if (language === "python" && !config2.python.enabled) {
21015
+ return {
21016
+ content: [{
21017
+ type: "text",
21018
+ text: JSON.stringify({
21019
+ success: false,
21020
+ error: "Python backend is disabled",
21021
+ hint: "Set LSP_MCP_PYTHON_ENABLED=true to enable"
21022
+ }, null, 2)
21023
+ }]
21024
+ };
21025
+ }
21026
+ if (language === "typescript" && !config2.typescript.enabled) {
21027
+ return {
21028
+ content: [{
21029
+ type: "text",
21030
+ text: JSON.stringify({
21031
+ success: false,
21032
+ error: "TypeScript backend is disabled",
21033
+ hint: "Set LSP_MCP_TYPESCRIPT_ENABLED=true to enable"
21034
+ }, null, 2)
21035
+ }]
21036
+ };
21037
+ }
21038
+ if (language === "vue" && !config2.vue.enabled) {
21039
+ return {
21040
+ content: [{
21041
+ type: "text",
21042
+ text: JSON.stringify({
21043
+ success: false,
21044
+ error: "Vue backend is disabled",
21045
+ hint: "Set LSP_MCP_VUE_ENABLED=true to enable"
21046
+ }, null, 2)
21047
+ }]
21048
+ };
21049
+ }
21050
+ try {
21051
+ const { oldVersion, newVersion } = await updateCallback(language);
21052
+ const backendStatus = backendManager.getStatus();
21053
+ const status2 = backendStatus[language];
21054
+ const updated = oldVersion !== newVersion;
21055
+ return {
21056
+ content: [{
21057
+ type: "text",
21058
+ text: JSON.stringify({
21059
+ success: true,
21060
+ language,
21061
+ updated,
21062
+ oldVersion,
21063
+ newVersion,
21064
+ serverName: status2?.serverName,
21065
+ tools: status2?.tools,
21066
+ message: updated ? `${language} backend updated from ${oldVersion} to ${newVersion}.` : `${language} backend is already at the latest version (${newVersion}).`
21067
+ }, null, 2)
21068
+ }]
21069
+ };
21070
+ } catch (error2) {
21071
+ return {
21072
+ content: [{
21073
+ type: "text",
21074
+ text: JSON.stringify({
21075
+ success: false,
21076
+ language,
21077
+ error: String(error2),
21078
+ hint: "Check network connection and try again"
21079
+ }, null, 2)
21080
+ }]
21081
+ };
21082
+ }
21083
+ }
20927
21084
 
20928
21085
  // src/prompts.ts
20929
21086
  var skillsContent = {
@@ -21426,186 +21583,134 @@ var require2 = createRequire2(import.meta.url);
21426
21583
  var packageJson = require2("../package.json");
21427
21584
  var config2 = loadConfig();
21428
21585
  var backendManager = new BackendManager(config2);
21586
+ var startedBackends = new Set;
21429
21587
  var server = new McpServer({
21430
21588
  name: "lsp-mcp",
21431
21589
  version: packageJson.version
21432
21590
  });
21433
21591
  registerPrompts(server);
21592
+ function jsonSchemaToZod(schema) {
21593
+ const result = {};
21594
+ if (!schema || !schema.properties) {
21595
+ return result;
21596
+ }
21597
+ const required2 = new Set(schema.required || []);
21598
+ for (const [key, prop] of Object.entries(schema.properties)) {
21599
+ let zodType;
21600
+ switch (prop.type) {
21601
+ case "string":
21602
+ zodType = exports_external.string();
21603
+ if (prop.enum) {
21604
+ zodType = exports_external.enum(prop.enum);
21605
+ }
21606
+ break;
21607
+ case "number":
21608
+ case "integer":
21609
+ zodType = exports_external.number();
21610
+ if (prop.type === "integer") {
21611
+ zodType = zodType.int();
21612
+ }
21613
+ if (prop.exclusiveMinimum !== undefined) {
21614
+ zodType = zodType.gt(prop.exclusiveMinimum);
21615
+ }
21616
+ if (prop.minimum !== undefined) {
21617
+ zodType = zodType.gte(prop.minimum);
21618
+ }
21619
+ if (prop.maximum !== undefined) {
21620
+ zodType = zodType.lte(prop.maximum);
21621
+ }
21622
+ break;
21623
+ case "boolean":
21624
+ zodType = exports_external.boolean();
21625
+ break;
21626
+ case "array":
21627
+ if (prop.items?.type === "string") {
21628
+ zodType = exports_external.array(exports_external.string());
21629
+ } else {
21630
+ zodType = exports_external.array(exports_external.any());
21631
+ }
21632
+ break;
21633
+ case "object":
21634
+ zodType = exports_external.record(exports_external.any());
21635
+ break;
21636
+ default:
21637
+ zodType = exports_external.any();
21638
+ }
21639
+ if (prop.description) {
21640
+ zodType = zodType.describe(prop.description);
21641
+ }
21642
+ if (prop.default !== undefined) {
21643
+ zodType = zodType.default(prop.default);
21644
+ }
21645
+ if (!required2.has(key)) {
21646
+ zodType = zodType.optional();
21647
+ }
21648
+ result[key] = zodType;
21649
+ }
21650
+ return result;
21651
+ }
21652
+ function registerBackendTools(language, tools) {
21653
+ let count = 0;
21654
+ for (const tool of tools) {
21655
+ const namespacedName = `${language}_${tool.name}`;
21656
+ const zodSchema = jsonSchemaToZod(tool.inputSchema);
21657
+ server.registerTool(namespacedName, {
21658
+ description: tool.description || `${language} ${tool.name} tool`,
21659
+ inputSchema: zodSchema
21660
+ }, async (args) => backendManager.callTool(language, tool.name, args));
21661
+ console.error(`[lsp-mcp] Registered ${namespacedName}`);
21662
+ count++;
21663
+ }
21664
+ return count;
21665
+ }
21666
+ async function startAndRegisterBackend(language) {
21667
+ if (startedBackends.has(language)) {
21668
+ const status2 = backendManager.getStatus()[language];
21669
+ console.error(`[lsp-mcp] ${language} backend already started (${status2?.tools} tools)`);
21670
+ return status2?.tools || 0;
21671
+ }
21672
+ console.error(`[lsp-mcp] Starting ${language} backend...`);
21673
+ try {
21674
+ const tools = await backendManager.getTools(language);
21675
+ const count = registerBackendTools(language, tools);
21676
+ startedBackends.add(language);
21677
+ console.error(`[lsp-mcp] ${language}: ${count} tools registered`);
21678
+ return count;
21679
+ } catch (error2) {
21680
+ console.error(`[lsp-mcp] Failed to start ${language} backend:`, error2);
21681
+ throw error2;
21682
+ }
21683
+ }
21684
+ async function updateAndRestartBackend(language) {
21685
+ console.error(`[lsp-mcp] Updating ${language} backend...`);
21686
+ const result = await backendManager.restartBackend(language);
21687
+ if (startedBackends.has(language)) {
21688
+ console.error(`[lsp-mcp] ${language} backend updated, tools still available`);
21689
+ } else {
21690
+ const tools = await backendManager.getTools(language);
21691
+ registerBackendTools(language, tools);
21692
+ startedBackends.add(language);
21693
+ console.error(`[lsp-mcp] ${language} backend updated and ${tools.length} tools registered`);
21694
+ }
21695
+ return result;
21696
+ }
21434
21697
  server.registerTool("status", { description: "Get status of all LSP backends and server configuration" }, async () => status(backendManager, config2));
21435
21698
  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));
21436
21699
  server.registerTool("switch_python_backend", {
21437
21700
  description: "Switch the Python backend provider (requires restart)",
21438
21701
  inputSchema: switchPythonBackendSchema
21439
21702
  }, async ({ provider }) => switchPythonBackend(provider));
21440
- if (config2.python.enabled) {
21441
- const backendOption = exports_external.enum(["rope", "pyright"]).optional().describe("Backend to use (rope/pyright)");
21442
- server.registerTool("python/hover", {
21443
- description: pythonToolDescriptions.hover,
21444
- inputSchema: { ...positionArgs, backend: backendOption }
21445
- }, async (args) => backendManager.callTool("python", "hover", args));
21446
- server.registerTool("python/definition", {
21447
- description: pythonToolDescriptions.definition,
21448
- inputSchema: { ...positionArgs, backend: backendOption }
21449
- }, async (args) => backendManager.callTool("python", "definition", args));
21450
- server.registerTool("python/references", {
21451
- description: pythonToolDescriptions.references,
21452
- inputSchema: { ...positionArgs, backend: backendOption }
21453
- }, async (args) => backendManager.callTool("python", "references", args));
21454
- server.registerTool("python/completions", {
21455
- description: pythonToolDescriptions.completions,
21456
- inputSchema: { ...completionsArgs, backend: backendOption }
21457
- }, async (args) => backendManager.callTool("python", "completions", args));
21458
- server.registerTool("python/diagnostics", {
21459
- description: pythonToolDescriptions.diagnostics,
21460
- inputSchema: diagnosticsArgs
21461
- }, async (args) => backendManager.callTool("python", "diagnostics", args));
21462
- server.registerTool("python/symbols", {
21463
- description: pythonToolDescriptions.symbols,
21464
- inputSchema: { ...symbolsArgs, backend: backendOption }
21465
- }, async (args) => backendManager.callTool("python", "symbols", args));
21466
- server.registerTool("python/rename", {
21467
- description: pythonToolDescriptions.rename,
21468
- inputSchema: { ...positionArgs, new_name: exports_external.string().describe("New name for the symbol") }
21469
- }, async (args) => backendManager.callTool("python", "rename", args));
21470
- server.registerTool("python/search", {
21471
- description: pythonToolDescriptions.search,
21472
- inputSchema: searchArgs
21473
- }, async (args) => backendManager.callTool("python", "search", args));
21474
- server.registerTool("python/signature_help", {
21475
- description: pythonToolDescriptions.signature_help,
21476
- inputSchema: positionArgs
21477
- }, async (args) => backendManager.callTool("python", "signature_help", args));
21478
- server.registerTool("python/update_document", {
21479
- description: pythonToolDescriptions.update_document,
21480
- inputSchema: updateDocumentArgs
21481
- }, async (args) => backendManager.callTool("python", "update_document", args));
21482
- server.registerTool("python/status", {
21483
- description: pythonToolDescriptions.status
21484
- }, async () => backendManager.callTool("python", "status", {}));
21485
- server.registerTool("python/move", {
21486
- description: pythonToolDescriptions.move,
21487
- inputSchema: {
21488
- ...positionArgs,
21489
- destination: exports_external.string().describe('Destination module path (e.g., "mypackage.utils")'),
21490
- preview: exports_external.boolean().default(false).describe("If true, only show what would change")
21491
- }
21492
- }, async (args) => backendManager.callTool("python", "move", args));
21493
- server.registerTool("python/change_signature", {
21494
- description: pythonToolDescriptions.change_signature,
21495
- inputSchema: {
21496
- ...positionArgs,
21497
- new_params: exports_external.array(exports_external.string()).optional().describe("New parameter order"),
21498
- add_param: exports_external.string().optional().describe("Name of parameter to add"),
21499
- add_param_default: exports_external.string().optional().describe("Default value for added parameter"),
21500
- add_param_index: exports_external.number().int().optional().describe("Index where to insert new param"),
21501
- remove_param: exports_external.string().optional().describe("Name of parameter to remove"),
21502
- preview: exports_external.boolean().default(false).describe("If true, only show what would change")
21503
- }
21504
- }, async (args) => backendManager.callTool("python", "change_signature", args));
21505
- server.registerTool("python/function_signature", {
21506
- description: pythonToolDescriptions.function_signature,
21507
- inputSchema: positionArgs
21508
- }, async (args) => backendManager.callTool("python", "function_signature", args));
21509
- server.registerTool("python/set_backend", {
21510
- description: pythonToolDescriptions.set_backend,
21511
- inputSchema: {
21512
- backend: exports_external.enum(["rope", "pyright"]).describe("The backend to use"),
21513
- tool: exports_external.string().optional().describe("Optional tool name to set backend for")
21514
- }
21515
- }, async (args) => backendManager.callTool("python", "set_backend", args));
21516
- server.registerTool("python/set_python_path", {
21517
- description: pythonToolDescriptions.set_python_path,
21518
- inputSchema: {
21519
- python_path: exports_external.string().describe("Absolute path to the Python interpreter"),
21520
- workspace: exports_external.string().optional().describe("Optional workspace to set the path for")
21521
- }
21522
- }, async (args) => backendManager.callTool("python", "set_python_path", args));
21523
- }
21524
- if (config2.typescript.enabled) {
21525
- server.registerTool("typescript/hover", {
21526
- description: typescriptToolDescriptions.hover,
21527
- inputSchema: positionArgs
21528
- }, async (args) => backendManager.callTool("typescript", "hover", args));
21529
- server.registerTool("typescript/definition", {
21530
- description: typescriptToolDescriptions.definition,
21531
- inputSchema: positionArgs
21532
- }, async (args) => backendManager.callTool("typescript", "definition", args));
21533
- server.registerTool("typescript/references", {
21534
- description: typescriptToolDescriptions.references,
21535
- inputSchema: positionArgs
21536
- }, async (args) => backendManager.callTool("typescript", "references", args));
21537
- server.registerTool("typescript/completions", {
21538
- description: typescriptToolDescriptions.completions,
21539
- inputSchema: completionsArgs
21540
- }, async (args) => backendManager.callTool("typescript", "completions", args));
21541
- server.registerTool("typescript/diagnostics", {
21542
- description: typescriptToolDescriptions.diagnostics,
21543
- inputSchema: diagnosticsArgs
21544
- }, async (args) => backendManager.callTool("typescript", "diagnostics", args));
21545
- server.registerTool("typescript/symbols", {
21546
- description: typescriptToolDescriptions.symbols,
21547
- inputSchema: symbolsArgs
21548
- }, async (args) => backendManager.callTool("typescript", "symbols", args));
21549
- server.registerTool("typescript/rename", {
21550
- description: typescriptToolDescriptions.rename,
21551
- inputSchema: renameArgs
21552
- }, async (args) => backendManager.callTool("typescript", "rename", args));
21553
- server.registerTool("typescript/search", {
21554
- description: typescriptToolDescriptions.search,
21555
- inputSchema: searchArgs
21556
- }, async (args) => backendManager.callTool("typescript", "search", args));
21557
- server.registerTool("typescript/signature_help", {
21558
- description: typescriptToolDescriptions.signature_help,
21559
- inputSchema: positionArgs
21560
- }, async (args) => backendManager.callTool("typescript", "signature_help", args));
21561
- server.registerTool("typescript/update_document", {
21562
- description: typescriptToolDescriptions.update_document,
21563
- inputSchema: updateDocumentArgs
21564
- }, async (args) => backendManager.callTool("typescript", "update_document", args));
21565
- server.registerTool("typescript/status", {
21566
- description: typescriptToolDescriptions.status,
21567
- inputSchema: {
21568
- file: exports_external.string().describe("A TypeScript/JavaScript file to check project status for")
21569
- }
21570
- }, async (args) => backendManager.callTool("typescript", "status", args));
21571
- server.registerTool("typescript/move", {
21572
- description: "Move a function, class, or variable to a new file",
21573
- inputSchema: {
21574
- file: exports_external.string().describe("Absolute path to the file"),
21575
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
21576
- column: exports_external.number().int().positive().describe("Column number (1-based)"),
21577
- destination: exports_external.string().optional().describe("Destination file path (optional)"),
21578
- preview: exports_external.boolean().default(false).describe("If true, only show what would change")
21579
- }
21580
- }, async (args) => backendManager.callTool("typescript", "move", args));
21581
- server.registerTool("typescript/function_signature", {
21582
- description: "Get the current signature of a function at a specific position",
21583
- inputSchema: {
21584
- file: exports_external.string().describe("Absolute path to the file"),
21585
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
21586
- column: exports_external.number().int().positive().describe("Column number (1-based)")
21587
- }
21588
- }, async (args) => backendManager.callTool("typescript", "function_signature", args));
21589
- server.registerTool("typescript/available_refactors", {
21590
- description: "Get available refactoring actions at a specific position",
21591
- inputSchema: {
21592
- file: exports_external.string().describe("Absolute path to the file"),
21593
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
21594
- column: exports_external.number().int().positive().describe("Column number (1-based)")
21595
- }
21596
- }, async (args) => backendManager.callTool("typescript", "available_refactors", args));
21597
- server.registerTool("typescript/apply_refactor", {
21598
- description: "Apply a specific refactoring action at a position",
21599
- inputSchema: {
21600
- file: exports_external.string().describe("Absolute path to the file"),
21601
- line: exports_external.number().int().positive().describe("Line number (1-based)"),
21602
- column: exports_external.number().int().positive().describe("Column number (1-based)"),
21603
- refactorName: exports_external.string().describe("Name of the refactoring"),
21604
- actionName: exports_external.string().describe("Name of the action"),
21605
- preview: exports_external.boolean().default(false).describe("If true, only show what would change")
21606
- }
21607
- }, async (args) => backendManager.callTool("typescript", "apply_refactor", args));
21608
- }
21703
+ server.registerTool("list_backends", {
21704
+ description: "List available backends and their status. Shows which backends are installed, running, and how many tools they provide."
21705
+ }, async () => listBackends(backendManager, config2));
21706
+ server.registerTool("start_backend", {
21707
+ description: "Start a backend and register its tools. This will download and install the backend if needed, then make its tools available.",
21708
+ inputSchema: startBackendSchema
21709
+ }, async ({ language }) => startBackend(language, backendManager, config2, startAndRegisterBackend));
21710
+ server.registerTool("update_backend", {
21711
+ description: "Update a backend to the latest version. This will restart the backend with the newest version available.",
21712
+ inputSchema: updateBackendSchema
21713
+ }, async ({ language }) => updateBackend(language, backendManager, config2, updateAndRestartBackend));
21609
21714
  async function gracefulShutdown(signal) {
21610
21715
  console.error(`
21611
21716
  [lsp-mcp] Received ${signal}, shutting down gracefully...`);
@@ -21623,12 +21728,15 @@ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
21623
21728
  process.on("SIGINT", () => gracefulShutdown("SIGINT"));
21624
21729
  async function main() {
21625
21730
  console.error("LSP MCP Server - Unified Multi-Language Code Intelligence");
21731
+ console.error(` Version: ${packageJson.version}`);
21626
21732
  console.error(" Python:", config2.python.enabled ? `enabled (${config2.python.provider})` : "disabled");
21627
21733
  console.error(" TypeScript:", config2.typescript.enabled ? "enabled" : "disabled");
21628
21734
  console.error("");
21629
- console.error("Tools are namespaced: python/hover, typescript/definition, etc.");
21735
+ console.error("Backends are loaded on-demand. Use these tools to get started:");
21736
+ console.error(" - list_backends: See available backends and their status");
21737
+ console.error(" - start_backend: Install and start a backend (e.g., start_backend language=python)");
21738
+ console.error("");
21630
21739
  console.error("Prompts available: code-navigation, refactoring, code-analysis, lsp-rules, lsp-quick-start");
21631
- console.error("Backends start lazily on first tool call.");
21632
21740
  console.error("");
21633
21741
  const transport = new StdioServerTransport;
21634
21742
  await server.connect(transport);
@@ -21639,4 +21747,4 @@ main().catch((error2) => {
21639
21747
  process.exit(1);
21640
21748
  });
21641
21749
 
21642
- //# debugId=42A9C81F8A74BE4464756E2164756E21
21750
+ //# debugId=0931320CB6D5336A64756E2164756E21