[MCP Server] i18n for tool activity messages

(cherry picked from commit 774d78070494db974b41baaa33f047a5760d3c8a)

GitOrigin-RevId: e1f84771d6189fa1267632ad6c1de23d2c7c366c
This commit is contained in:
Artem.Bukhonov
2025-07-12 18:49:41 +02:00
committed by intellij-monorepo-bot
parent d34f8bf3f5
commit 22d44fe866
11 changed files with 55 additions and 41 deletions

View File

@@ -57,4 +57,28 @@ progress.title.collecting.project.problems=Collecting project problems
command.execution.confirmation.allow=Allow command.execution.confirmation.allow=Allow
command.execution.confirmation.deny=Deny command.execution.confirmation.deny=Deny
dialog.mcp.server.consent.enable.button=Enable dialog.mcp.server.consent.enable.button=Enable
dialog.mcp.server.consent.cancel.button=Cancel dialog.mcp.server.consent.cancel.button=Cancel
# Tool activities
tool.activity.traversing.folder.tree=Traversing folder tree for ''{0}''
tool.activity.finding.files.by.name=Finding files with name containing ''{0}''
tool.activity.finding.files.by.glob=Finding files by glob ''{0}''
tool.activity.opening.file=Opening file ''{0}''
tool.activity.getting.open.files=Getting open files
tool.activity.creating.file=Creating file ''{0}''
tool.activity.searching.commits=Searching commits for ''{0}''
tool.activity.checking.vcs.status=Checking VCS status
tool.activity.formatting.file=Formatting file ''{0}''
tool.activity.reading.file=Reading file ''{0}''
tool.activity.replacing.text.in.file=Replacing text in ''{0}'': ''{1}'' \u2192 ''{2}''
tool.activity.searching.files.for.text=Searching project files for ''{0}''
tool.activity.searching.content.with.regex=Searching content with regex ''{0}''
tool.activity.running.command=Running command: ''{0}''
tool.activity.getting.symbol.info=Getting symbol info at ''{0}:{1}:{2}''
tool.activity.renaming.symbol=Renaming ''{0}'' to ''{1}'' in ''{2}''
tool.activity.getting.run.configurations=Getting run configurations
tool.activity.executing.run.configuration=Executing run configuration ''{0}''
tool.activity.collecting.file.problems=Collecting problems in file ''{0}''
tool.activity.checking.project.issues=Checking project issues
tool.activity.listing.modules=Listing modules
tool.activity.checking.dependencies=Checking dependencies

View File

@@ -1,5 +1,6 @@
package com.intellij.mcpserver package com.intellij.mcpserver
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.application import com.intellij.util.application
import com.intellij.util.messages.Topic import com.intellij.util.messages.Topic
@@ -15,7 +16,7 @@ interface ToolCallListener {
fun afterMcpToolCall(mcpToolDescriptor: McpToolDescriptor, events: List<McpToolSideEffectEvent>, error: Throwable?) {} fun afterMcpToolCall(mcpToolDescriptor: McpToolDescriptor, events: List<McpToolSideEffectEvent>, error: Throwable?) {}
fun toolActivity(mcpToolDescriptor: McpToolDescriptor, toolActivityDescription: String) {} fun toolActivity(mcpToolDescriptor: McpToolDescriptor, @NlsContexts.Label toolActivityDescription: String) {}
} }
sealed interface McpToolSideEffectEvent sealed interface McpToolSideEffectEvent
@@ -27,6 +28,6 @@ class FileDeletedEvent(val file: VirtualFile, val content: String?) : FileEvent
class FileMovedEvent(val file: VirtualFile, val oldParent: VirtualFile, val newParent: VirtualFile) : FileEvent class FileMovedEvent(val file: VirtualFile, val oldParent: VirtualFile, val newParent: VirtualFile) : FileEvent
class FileContentChangeEvent(val file: VirtualFile, val oldContent: String?, val newContent: String) : FileEvent class FileContentChangeEvent(val file: VirtualFile, val oldContent: String?, val newContent: String) : FileEvent
fun CoroutineContext.reportToolActivity(toolDescription: String) { fun CoroutineContext.reportToolActivity(@NlsContexts.Label toolDescription: String) {
application.messageBus.syncPublisher(ToolCallListener.TOPIC).toolActivity(this.currentToolDescriptor, toolDescription) application.messageBus.syncPublisher(ToolCallListener.TOPIC).toolActivity(this.currentToolDescriptor, toolDescription)
} }

View File

@@ -51,7 +51,7 @@ class AnalysisToolset : McpToolset {
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION)
timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE, timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE,
): FileProblemsResult { ): FileProblemsResult {
currentCoroutineContext().reportToolActivity("Collecting problems in file '$filePath'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.collecting.file.problems", filePath))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val projectDir = project.projectDirectory val projectDir = project.projectDirectory
@@ -107,7 +107,7 @@ class AnalysisToolset : McpToolset {
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION)
timeout: Int = Constants.LONG_TIMEOUT_MILLISECONDS_VALUE, timeout: Int = Constants.LONG_TIMEOUT_MILLISECONDS_VALUE,
): ProjectProblemsResult { ): ProjectProblemsResult {
currentCoroutineContext().reportToolActivity("Checking project issues") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.checking.project.issues"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val problems = CopyOnWriteArrayList<ProjectProblem>() val problems = CopyOnWriteArrayList<ProjectProblem>()
@@ -145,7 +145,7 @@ class AnalysisToolset : McpToolset {
|Returns structured information about each module including name and type. |Returns structured information about each module including name and type.
""") """)
suspend fun get_project_modules(): ProjectModulesResult { suspend fun get_project_modules(): ProjectModulesResult {
currentCoroutineContext().reportToolActivity("Listing modules") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.listing.modules"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val modules = readAction { val modules = readAction {
@@ -167,7 +167,7 @@ class AnalysisToolset : McpToolset {
|Returns structured information about project library names. |Returns structured information about project library names.
""") """)
suspend fun get_project_dependencies(): ProjectDependenciesResult { suspend fun get_project_dependencies(): ProjectDependenciesResult {
currentCoroutineContext().reportToolActivity("Checking dependencies") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.checking.dependencies"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val dependencies = readAction { val dependencies = readAction {

View File

@@ -1,12 +1,9 @@
package com.intellij.mcpserver.toolsets.general package com.intellij.mcpserver.toolsets.general
import com.intellij.lang.documentation.impl.documentationTargets import com.intellij.lang.documentation.impl.documentationTargets
import com.intellij.mcpserver.McpToolset import com.intellij.mcpserver.*
import com.intellij.mcpserver.annotations.McpDescription import com.intellij.mcpserver.annotations.McpDescription
import com.intellij.mcpserver.annotations.McpTool import com.intellij.mcpserver.annotations.McpTool
import com.intellij.mcpserver.mcpFail
import com.intellij.mcpserver.project
import com.intellij.mcpserver.reportToolActivity
import com.intellij.mcpserver.toolsets.Constants import com.intellij.mcpserver.toolsets.Constants
import com.intellij.mcpserver.util.SymbolInfo import com.intellij.mcpserver.util.SymbolInfo
import com.intellij.mcpserver.util.convertHtmlToMarkdown import com.intellij.mcpserver.util.convertHtmlToMarkdown
@@ -46,7 +43,7 @@ class CodeInsightToolset : McpToolset {
@McpDescription("1-based column number") @McpDescription("1-based column number")
column: Int, column: Int,
): SymbolInfoResult { ): SymbolInfoResult {
currentCoroutineContext().reportToolActivity("Getting symbol info at '$filePath:$line:$column'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.getting.symbol.info", filePath, line, column))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(filePath) val resolvedPath = project.resolveInProject(filePath)

View File

@@ -44,7 +44,7 @@ class ExecutionToolset : McpToolset {
|Use this tool to query the list of available run configurations in the current project. |Use this tool to query the list of available run configurations in the current project.
""") """)
suspend fun get_run_configurations(): RunConfigurationsList { suspend fun get_run_configurations(): RunConfigurationsList {
currentCoroutineContext().reportToolActivity("Getting run configurations") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.getting.run.configurations"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val runManager = RunManager.getInstance(project) val runManager = RunManager.getInstance(project)
@@ -80,7 +80,7 @@ class ExecutionToolset : McpToolset {
@McpDescription(Constants.TRUNCATE_MODE_DESCRIPTION) @McpDescription(Constants.TRUNCATE_MODE_DESCRIPTION)
truncateMode: TruncateMode = Constants.TRUCATE_MODE_VALUE, truncateMode: TruncateMode = Constants.TRUCATE_MODE_VALUE,
): RunConfigurationResult { ): RunConfigurationResult {
currentCoroutineContext().reportToolActivity("Executing run configuration '$configurationName'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.executing.run.configuration", configurationName))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val runManager = RunManager.getInstance(project) val runManager = RunManager.getInstance(project)

View File

@@ -56,7 +56,7 @@ class FileToolset : McpToolset {
@McpDescription("Maximum recursion depth") maxDepth: Int = 5, @McpDescription("Maximum recursion depth") maxDepth: Int = 5,
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE, @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE,
): DirectoryTreeInfo { ): DirectoryTreeInfo {
currentCoroutineContext().reportToolActivity("Traversing folder tree for '$directoryPath'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.traversing.folder.tree", directoryPath))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(directoryPath) val resolvedPath = project.resolveInProject(directoryPath)
if (!resolvedPath.exists()) mcpFail("No such directory: $resolvedPath") if (!resolvedPath.exists()) mcpFail("No such directory: $resolvedPath")
@@ -94,7 +94,7 @@ class FileToolset : McpToolset {
@McpDescription("Timeout in milliseconds") @McpDescription("Timeout in milliseconds")
timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE, timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE,
): FilesListResult { ): FilesListResult {
currentCoroutineContext().reportToolActivity("Finding files with name containing '$nameKeyword'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.finding.files.by.name", nameKeyword))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val projectDir = project.projectDirectory val projectDir = project.projectDirectory
@@ -145,7 +145,7 @@ class FileToolset : McpToolset {
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION)
timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE
) : FilesListResult { ) : FilesListResult {
currentCoroutineContext().reportToolActivity("Finding files by glob '$globPattern'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.finding.files.by.glob", globPattern))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val projectDirPath = project.projectDirectory val projectDirPath = project.projectDirectory
val fileIndex = ProjectRootManager.getInstance(project).getFileIndex() val fileIndex = ProjectRootManager.getInstance(project).getFileIndex()
@@ -205,7 +205,7 @@ class FileToolset : McpToolset {
@McpDescription(Constants.RELATIVE_PATH_IN_PROJECT_DESCRIPTION) @McpDescription(Constants.RELATIVE_PATH_IN_PROJECT_DESCRIPTION)
filePath: String, filePath: String,
) { ) {
currentCoroutineContext().reportToolActivity("Opening file '$filePath'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.opening.file", filePath))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(filePath) val resolvedPath = project.resolveInProject(filePath)
@@ -226,7 +226,7 @@ class FileToolset : McpToolset {
|Use this tool to explore current open editors. |Use this tool to explore current open editors.
""") """)
suspend fun get_all_open_file_paths(): OpenFilesInfo { suspend fun get_all_open_file_paths(): OpenFilesInfo {
currentCoroutineContext().reportToolActivity("Getting open files") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.getting.open.files"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val projectDir = project.projectDirectory val projectDir = project.projectDirectory
@@ -255,7 +255,7 @@ class FileToolset : McpToolset {
@McpDescription("Content to write into the new file") @McpDescription("Content to write into the new file")
text: String? = null, text: String? = null,
) { ) {
currentCoroutineContext().reportToolActivity("Creating file '$pathInProject'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.creating.file", pathInProject))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val path = project.resolveInProject(pathInProject) val path = project.resolveInProject(pathInProject)

View File

@@ -3,12 +3,9 @@
package com.intellij.mcpserver.toolsets.general package com.intellij.mcpserver.toolsets.general
import com.intellij.codeInsight.actions.ReformatCodeProcessor import com.intellij.codeInsight.actions.ReformatCodeProcessor
import com.intellij.mcpserver.McpToolset import com.intellij.mcpserver.*
import com.intellij.mcpserver.annotations.McpDescription import com.intellij.mcpserver.annotations.McpDescription
import com.intellij.mcpserver.annotations.McpTool import com.intellij.mcpserver.annotations.McpTool
import com.intellij.mcpserver.mcpFail
import com.intellij.mcpserver.project
import com.intellij.mcpserver.reportToolActivity
import com.intellij.mcpserver.toolsets.Constants import com.intellij.mcpserver.toolsets.Constants
import com.intellij.mcpserver.util.resolveInProject import com.intellij.mcpserver.util.resolveInProject
import com.intellij.openapi.application.EDT import com.intellij.openapi.application.EDT
@@ -30,7 +27,7 @@ class FormattingToolset : McpToolset {
@McpDescription(Constants.RELATIVE_PATH_IN_PROJECT_DESCRIPTION) @McpDescription(Constants.RELATIVE_PATH_IN_PROJECT_DESCRIPTION)
path: String, path: String,
): String { ): String {
currentCoroutineContext().reportToolActivity("Formatting file '$path'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.formatting.file", path))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedFilePath = project.resolveInProject(path) val resolvedFilePath = project.resolveInProject(path)

View File

@@ -1,11 +1,8 @@
package com.intellij.mcpserver.toolsets.general package com.intellij.mcpserver.toolsets.general
import com.intellij.mcpserver.McpToolset import com.intellij.mcpserver.*
import com.intellij.mcpserver.annotations.McpDescription import com.intellij.mcpserver.annotations.McpDescription
import com.intellij.mcpserver.annotations.McpTool import com.intellij.mcpserver.annotations.McpTool
import com.intellij.mcpserver.mcpFail
import com.intellij.mcpserver.project
import com.intellij.mcpserver.reportToolActivity
import com.intellij.mcpserver.toolsets.Constants import com.intellij.mcpserver.toolsets.Constants
import com.intellij.mcpserver.util.resolveInProject import com.intellij.mcpserver.util.resolveInProject
import com.intellij.openapi.application.EDT import com.intellij.openapi.application.EDT
@@ -45,7 +42,7 @@ class RefactoringToolset : McpToolset {
@McpDescription("New name for the symbol") @McpDescription("New name for the symbol")
newName: String, newName: String,
): String { ): String {
currentCoroutineContext().reportToolActivity("Renaming '$symbolName' to '$newName' in '$pathInProject'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.renaming.symbol", symbolName, newName, pathInProject))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(pathInProject) val resolvedPath = project.resolveInProject(pathInProject)

View File

@@ -5,12 +5,9 @@ package com.intellij.mcpserver.toolsets.general
import com.intellij.find.FindBundle import com.intellij.find.FindBundle
import com.intellij.find.FindManager import com.intellij.find.FindManager
import com.intellij.find.impl.FindInProjectUtil import com.intellij.find.impl.FindInProjectUtil
import com.intellij.mcpserver.McpToolset import com.intellij.mcpserver.*
import com.intellij.mcpserver.annotations.McpDescription import com.intellij.mcpserver.annotations.McpDescription
import com.intellij.mcpserver.annotations.McpTool import com.intellij.mcpserver.annotations.McpTool
import com.intellij.mcpserver.mcpFail
import com.intellij.mcpserver.project
import com.intellij.mcpserver.reportToolActivity
import com.intellij.mcpserver.toolsets.Constants import com.intellij.mcpserver.toolsets.Constants
import com.intellij.mcpserver.util.* import com.intellij.mcpserver.util.*
import com.intellij.openapi.application.readAction import com.intellij.openapi.application.readAction
@@ -52,7 +49,7 @@ class TextToolset : McpToolset {
@McpDescription("Max number of lines to return. Truncation will be performed depending on truncateMode.") @McpDescription("Max number of lines to return. Truncation will be performed depending on truncateMode.")
maxLinesCount: Int = 1000, maxLinesCount: Int = 1000,
): String { ): String {
currentCoroutineContext().reportToolActivity("Reading file '$pathInProject'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.reading.file", pathInProject))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(pathInProject) val resolvedPath = project.resolveInProject(pathInProject)
@@ -104,7 +101,7 @@ class TextToolset : McpToolset {
@McpDescription("Case-sensitive search") @McpDescription("Case-sensitive search")
caseSensitive: Boolean = true, caseSensitive: Boolean = true,
) { ) {
currentCoroutineContext().reportToolActivity("Replacing text in '$pathInProject': '$oldText' → '$newText'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.replacing.text.in.file", pathInProject, oldText, newText))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val resolvedPath = project.resolveInProject(pathInProject) val resolvedPath = project.resolveInProject(pathInProject)
val (document, text) = readAction { val (document, text) = readAction {
@@ -157,7 +154,7 @@ class TextToolset : McpToolset {
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION)
timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE, timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE,
): UsageInfoResult { ): UsageInfoResult {
currentCoroutineContext().reportToolActivity("Searching project files for '$searchText'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.searching.files.for.text", searchText))
return search_in_files(searchText, false, directoryToSearch, fileMask, caseSensitive, maxUsageCount, timeout) return search_in_files(searchText, false, directoryToSearch, fileMask, caseSensitive, maxUsageCount, timeout)
} }
@@ -182,7 +179,7 @@ class TextToolset : McpToolset {
@McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION) @McpDescription(Constants.TIMEOUT_MILLISECONDS_DESCRIPTION)
timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE, timeout: Int = Constants.MEDIUM_TIMEOUT_MILLISECONDS_VALUE,
): UsageInfoResult { ): UsageInfoResult {
currentCoroutineContext().reportToolActivity("Searching content with regex '$regexPattern'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.searching.content.with.regex", regexPattern))
return search_in_files(regexPattern, true, directoryToSearch, fileMask, caseSensitive, maxUsageCount, timeout) return search_in_files(regexPattern, true, directoryToSearch, fileMask, caseSensitive, maxUsageCount, timeout)
} }

View File

@@ -54,7 +54,7 @@ class TerminalToolset : McpToolset {
@McpDescription(Constants.TRUNCATE_MODE_DESCRIPTION) @McpDescription(Constants.TRUNCATE_MODE_DESCRIPTION)
truncateMode: TruncateMode = Constants.TRUCATE_MODE_VALUE, truncateMode: TruncateMode = Constants.TRUCATE_MODE_VALUE,
): CommandExecutionResult { ): CommandExecutionResult {
currentCoroutineContext().reportToolActivity("Running command: '$command'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.running.command", command))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
checkUserConfirmationIfNeeded(McpServerBundle.message("label.do.you.want.to.execute.command.in.terminal"), command, project) checkUserConfirmationIfNeeded(McpServerBundle.message("label.do.you.want.to.execute.command.in.terminal"), command, project)

View File

@@ -2,6 +2,7 @@
package com.intellij.mcpserver.toolsets.vcs package com.intellij.mcpserver.toolsets.vcs
import com.intellij.mcpserver.McpServerBundle
import com.intellij.mcpserver.McpToolset import com.intellij.mcpserver.McpToolset
import com.intellij.mcpserver.annotations.McpDescription import com.intellij.mcpserver.annotations.McpDescription
import com.intellij.mcpserver.annotations.McpTool import com.intellij.mcpserver.annotations.McpTool
@@ -27,7 +28,7 @@ class VcsToolset : McpToolset {
@McpDescription("Text or keywords to search for in commit messages") @McpDescription("Text or keywords to search for in commit messages")
text: String text: String
): String { ): String {
currentCoroutineContext().reportToolActivity("Searching commits for '$text'") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.searching.commits", text))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val queryText = text val queryText = text
val matchingCommits = mutableListOf<String>() val matchingCommits = mutableListOf<String>()
@@ -79,7 +80,7 @@ class VcsToolset : McpToolset {
Note: Works with any VCS supported by the IDE, but is most commonly used with Git Note: Works with any VCS supported by the IDE, but is most commonly used with Git
""") """)
suspend fun get_project_vcs_status(): String { suspend fun get_project_vcs_status(): String {
currentCoroutineContext().reportToolActivity("Checking VCS status") currentCoroutineContext().reportToolActivity(McpServerBundle.message("tool.activity.checking.vcs.status"))
val project = currentCoroutineContext().project val project = currentCoroutineContext().project
val projectDir = project.projectDirectory val projectDir = project.projectDirectory