Skip to content

feat(mcp): proactive roots/list bootstrap + расширенный type_info + новый global_member_info#4131

Merged
nixel2007 merged 5 commits into
developfrom
feature/mcp-roots-bootstrap-and-rich-type-info
Jun 16, 2026
Merged

feat(mcp): proactive roots/list bootstrap + расширенный type_info + новый global_member_info#4131
nixel2007 merged 5 commits into
developfrom
feature/mcp-roots-bootstrap-and-rich-type-info

Conversation

@sfaqer

@sfaqer sfaqer commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

Три темы вокруг MCP-режима bsl-language-server.

1. Roots bootstrap

McpRootsBootstrapper — при первом tool-вызове сервер сам шлёт клиенту roots/list, если тот объявил roots-capability в initialize. По MCP-спеке клиент должен ответить на этот запрос. Без проактивного запроса bsl-ls регистрирует workspace только по уведомлению notifications/roots/list_changed, а клиенты (Claude Code 2.1.178 в частности) шлют его только при последующих изменениях roots, а не на инициализацию. Симптом: все workspace-зависимые tools падали с «No registered workspace» сразу после подключения.

McpToolSpecificationsBootstrapWrapperBeanPostProcessor оборачивает каждый SyncToolSpecification из bean'а toolSpecs, прозрачно вызывая bootstrap перед делегированием в исходный callHandler. Существующие @McpTool-методы про bootstrap не знают (diff в них — нулевой).

McpRootsChangeConsumer.normalizeWindowsFileUri — фикс под windows-патологию: Claude Code 2.1.178 на Windows шлёт roots вида file://D:\path\with\backslashes (буква диска как «host» + backslash в path). Absolute.uri такое не разбирает → root отбрасывается с warn'ом, workspace не регистрируется. Нормализуем до RFC 8089 file:///D:/path/with/forward-slashes до передачи в Absolute.

2. Расширенный type_info

  • Параметр language (RU/EN, default RU): имена, описания, билингв-поля платформенной метаинформации возвращаются на выбранной локали.
  • Новые поля Result: constructors, events, definedAt (URI исходного файла-объявления для USER/CONFIGURATION).
  • TypeMemberDto: добавлены async и metadata (TypeMemberMetadataDto со sinceVersion / deprecatedSinceVersion / recommendedReplacements / availabilities / accessMode / returnValueDescription / notes / examples / seeAlso).
  • TypeParameterDto: добавлены variadic и description.

Чтобы получить URI определения без активного DocumentContext'а (MCP-tool вызывается «снаружи» документа), добавлен публичный TypeService.definingUri(TypeRef) — лёгкий вариант существующего definingSymbol(TypeRef, DocumentContext).

3. Новый MCP-tool global_member_info

Резолв глобальной функции / свойства / системного перечисления через GlobalScopeProvider. Для функций возвращает полный TypeMemberDto с сигнатурами и метаинформацией; для глобальных свойств/перечислений — упрощённый дескриптор с типом значения и описанием. Покрывает кейсы вроде «расскажи про Сообщить/Message», «какой тип у Метаданные», без необходимости открывать конкретный файл.

Test plan

  • TypeMemberMetadataDtoTest, TypeMemberDtoTest, TypeParameterDtoTest — DTO-маппинг (билингв-локаль, blank → null, сортировка, generic-семантика).
  • McpRootsBootstrapperTest — proactive listRoots, идемпотентность (только раз), отсутствие capability, null exchange, ошибка listRoots swallow, пустой набор.
  • McpToolSpecificationsBootstrapWrapperTest — обёртка другие bean'ы не трогает, не-List не трогает, при обёртке tool-метадата сохраняется, bootstrap вызывается до handler'а, при ошибке bootstrap'а original всё равно выполняется.
  • McpRootsChangeConsumerTest — windows-URI нормализация (изолированный helper + end-to-end с Root).
  • McpToolsTest — расширен сценариями type_info (constructors/events/language/definedAt) и кейсами global_member_info (function / EN alias / unknown / OS file type).
  • TypeServiceTestdefiningUri для PLATFORM/UNKNOWN/ANY (везде Optional.empty()).
  • Локально проходят все mcp-related тесты (McpRootsBootstrapperTest, McpRootsChangeConsumerTest, McpToolsTest, McpHttpServerTest, McpSseServerTest, McpStreamableServerTest, McpToolSpecificationsBootstrapWrapperTest, DTO-тесты, TypeServiceTest).

Summary by CodeRabbit

Release Notes

  • New Features

    • Added an MCP tool to fetch global member information by name with explicit workspace/root selection.
    • Enhanced type_info to be root/workspace aware and locale aware, including events, constructors, and definedAt.
    • Extended exported member/parameter metadata (async, richer member metadata, variadic, and additional localized details).
    • Proactively bootstraps MCP roots/list when supported by the client.
  • Bug Fixes

    • Improved Windows file:// URI normalization for correct path conversion.
  • Tests

    • Added coverage for roots bootstrapping, tool registration/wrapping, workspace/root resolution, and DTO mappings.
  • Chores

    • Added support for resolving a type’s defining URI.

…obal_member_info

Roots
- McpRootsBootstrapper: при первом tool-вызове сервер сам шлёт roots/list
  если клиент объявил roots-capability — без него Claude Code на Windows
  и подобные клиенты, которые не отправляют roots/list_changed, оставляли
  bsl-ls без зарегистрированного workspace и валили все workspace-зависимые
  инструменты с «No registered workspace».
- McpToolSpecificationsBootstrapWrapper: BeanPostProcessor оборачивает каждый
  SyncToolSpecification из bean'а `toolSpecs` Spring AI, прозрачно дёргая
  bootstrap перед делегированием в исходный callHandler. Сами @McpTool-методы
  не знают о bootstrap-логике.
- McpRootsChangeConsumer.normalizeWindowsFileUri: чинит роуты вида
  `file://D:\path` (буква диска как host + backslash) → `file:///D:/path`,
  которые шлёт Claude Code 2.1.178 на Windows и которые Absolute.uri не парсит.

type_info
- Параметр `language` (RU/EN, default RU) на сам tool: имена, описания и
  билингв-поля платформенной метаинформации возвращаются на выбранной локали.
- Новые поля Result: `constructors`, `events`, `definedAt`.
- TypeMemberDto: добавлены `async` и `metadata` (TypeMemberMetadataDto со
  sinceVersion / deprecatedSinceVersion / recommendedReplacements /
  availabilities / accessMode / returnValueDescription / notes / examples /
  seeAlso).
- TypeParameterDto: добавлены `variadic` и `description`.
- TypeService.definingUri(TypeRef): публичный URI исходного файла-объявления
  для USER и CONFIGURATION без необходимости в активном DocumentContext'е.

global_member_info
- Новый MCP-tool: резолв глобальной функции / свойства / системного
  перечисления (GlobalScopeProvider.findFunction → findGlobalProperty →
  findGlobalEnum) с возвратом полного TypeMemberDto для функций и
  упрощённого дескриптора с типом значения для свойств/перечислений.

Tests
- TypeMemberMetadataDtoTest, TypeMemberDtoTest, TypeParameterDtoTest: DTO-маппинг.
- McpRootsBootstrapperTest, McpToolSpecificationsBootstrapWrapperTest: цикл
  bootstrap, идемпотентность, обработка отсутствия capability, обёртка callHandler'а.
- McpRootsChangeConsumerTest: windows-URI normalization, end-to-end приведение
  битого URI к работоспособному.
- McpToolsTest: расширен новыми сценариями type_info (constructors / events /
  language / definedAt) и кейсами global_member_info (function / EN alias /
  unknown / OS file type).
- TypeServiceTest: определение definingUri для PLATFORM / UNKNOWN / ANY.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 166353cb-b9f2-4a61-a535-7181da18e409

📥 Commits

Reviewing files that changed from the base of the PR and between 9948eb7 and f622fc8.

📒 Files selected for processing (7)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumer.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapper.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDto.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeParameterDto.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapperTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapperTest.java
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapper.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumer.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapperTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapperTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDto.java

📝 Walkthrough

Walkthrough

Adds GlobalMemberInfoTool MCP tool for resolving global BSL members by name. Extends TypeInfoTool with events, constructors, definedAt, and optional language/root parameters via new McpWorkspaceResolver. Introduces TypeMemberMetadataDto and expands TypeMemberDto/TypeParameterDto with metadata, async, variadic, and description fields. Adds McpRootsBootstrapper for proactive one-time roots/list requests, McpToolSpecificationsBootstrapWrapper to inject bootstrap into every tool call, and Windows file URI normalization in McpRootsChangeConsumer.

Changes

MCP Tool Enrichment and Roots Bootstrapping

Layer / File(s) Summary
DTO shape expansion and TypeService.definingUri
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDto.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeParameterDto.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberDto.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/types/TypeService.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDtoTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeParameterDtoTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberDtoTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/types/TypeServiceTest.java
Adds TypeMemberMetadataDto record with EMPTY, from(PlatformMetadata, Language), and isEmpty(); extends TypeParameterDto with variadic and description; extends TypeMemberDto with async, metadata, and event signature mapping; adds TypeService.definingUri(TypeRef) returning Optional<URI> for user/configuration types.
Workspace resolution for MCP tool requests
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpWorkspaceResolver.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpWorkspaceResolverTest.java
Introduces McpWorkspaceResolver component that selects a registered workspace URI by normalizing and matching an optional root parameter against registered contexts, or throws IllegalArgumentException if root is missing or no match exists.
TypeInfoTool expansion and new GlobalMemberInfoTool
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/McpToolParams.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/TypeInfoTool.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java
Extends TypeInfoTool.Result with events, constructors, and definedAt; adds optional language and required root parameters to typeInfo(); introduces GlobalMemberInfoTool resolving global functions/properties/enums by name with bilingual support; adds LANGUAGE and GLOBAL_MEMBER_NAME documentation constants.
Tool registration and integration tests
src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpHttpServerTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpSseServerTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpStreamableServerTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java
Updates all three MCP server implementation tests to expect the new global_member_info tool; extends McpToolsTest with GlobalMemberInfoTool injection and comprehensive test cases for typeInfo() and globalMemberInfo() covering language selection, root workspace resolution, constructors, events, and error handling.
MCP roots bootstrapping infrastructure
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapper.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapper.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapperTest.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapperTest.java
Adds McpRootsBootstrapper performing a one-time proactive roots/list call during the first tool invocation when client declares roots capability; adds McpToolSpecificationsBootstrapWrapper BeanPostProcessor that wraps each SyncToolSpecification to invoke bootstrapIfNeeded before handler delegation; comprehensive tests validate bootstrap behavior, failure handling, and tool metadata preservation.
Windows file URI normalization
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumer.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumerTest.java
Fixes Windows file://<drive-letter>\\... URI form in McpRootsChangeConsumer via new normalizeWindowsFileUri helper that converts to RFC-compliant file:///D:/... form and replaces backslashes with forward slashes; adds Windows-specific test coverage and supporting string utility helpers.

Sequence Diagram(s)

sequenceDiagram
  participant Client as MCP Client
  rect rgba(70, 130, 180, 0.5)
    note over Client: First tool invocation with roots capability declared
    Client->>McpToolSpecificationsBootstrapWrapper: CallToolRequest (with McpSyncServerExchange)
    McpToolSpecificationsBootstrapWrapper->>McpRootsBootstrapper: bootstrapIfNeeded(exchange)
    McpRootsBootstrapper->>Client: exchange.listRoots()
    Client-->>McpRootsBootstrapper: ListRootsResult(roots)
    McpRootsBootstrapper->>McpRootsChangeConsumer: accept(roots)
    McpRootsChangeConsumer->>McpRootsChangeConsumer: normalizeWindowsFileUri(uri)
  end
  McpToolSpecificationsBootstrapWrapper->>OriginalToolHandler: callHandler(exchange, request)
  OriginalToolHandler-->>Client: CallToolResult
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • nixel2007

Poem

🐇 Hop, hop, a global member found!
The roots are fetched on the very first round.
Windows URIs, no longer askew,
Metadata blooms in languages two.
Events and constructors now shine so bright—
This rabbit ships features deep into the night! 🌙

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: proactive roots/list bootstrap, extended type_info tool, and new global_member_info tool, matching the three interconnected enhancements documented in PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/mcp-roots-bootstrap-and-rich-type-info

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/bsl/languageserver/types/TypeServiceTest.java (1)

130-140: ⚡ Quick win

Assert the resolved fixture type before the empty-URI expectation.

This test assumes the fixture symbol resolves to a platform type. Add an explicit kind assertion first so failures stay diagnostic if test data changes.

Suggested test hardening
   var typeRef = typeService.typesAt(reference).refs().iterator().next();
+  assertThat(typeRef.kind()).isEqualTo(com.github._1c_syntax.bsl.languageserver.types.model.TypeKind.PLATFORM);

   var uri = typeService.definingUri(typeRef);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/types/TypeServiceTest.java`
around lines 130 - 140, In the definingUriEmptyForPlatformType test method, add
an explicit assertion to verify that typeRef resolves to the expected platform
type kind before the assertThat(uri).isEmpty() assertion. This ensures that if
the test fixture data changes, the test will fail at the kind check with a clear
diagnostic message rather than silently failing at the URI assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumerTest.java`:
- Around line 78-91: The test `normalizesWindowsStyleFileUriBeforeRegistration`
extracts path components from the actual filesystem (using
`path.getRoot().toString().substring(0, 2)` for the drive letter and path
manipulation), which will fail on Unix systems where `getRoot()` returns "/"
instead of a drive letter. Replace the filesystem-dependent path extraction
logic with hardcoded Windows path values (e.g., hardcode "D:" for driveLetter
and use a hardcoded path string like "D:\\path\\with\\backslashes" for
constructing brokenUri) to make the test platform-independent and focused on
testing the URI normalization logic rather than filesystem specifics.

---

Nitpick comments:
In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/types/TypeServiceTest.java`:
- Around line 130-140: In the definingUriEmptyForPlatformType test method, add
an explicit assertion to verify that typeRef resolves to the expected platform
type kind before the assertThat(uri).isEmpty() assertion. This ensures that if
the test fixture data changes, the test will fail at the kind check with a clear
diagnostic message rather than silently failing at the URI assertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: feae3a91-d5ba-4ff7-96c2-fcc6779651ba

📥 Commits

Reviewing files that changed from the base of the PR and between 59fa125 and 6aeb719.

📒 Files selected for processing (21)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapper.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumer.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapper.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberDto.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDto.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeParameterDto.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/McpToolParams.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/TypeInfoTool.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/types/TypeService.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpHttpServerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsBootstrapperTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpRootsChangeConsumerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpSseServerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpStreamableServerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolSpecificationsBootstrapWrapperTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberDtoTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeMemberMetadataDtoTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/dto/TypeParameterDtoTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/types/TypeServiceTest.java

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Test Results

 3 468 files  + 36   3 468 suites  +36   1h 21m 20s ⏱️ - 19m 32s
 3 476 tests + 56   3 458 ✅ + 56   18 💤 ±0  0 ❌ ±0 
20 856 runs  +336  20 744 ✅ +332  112 💤 +4  0 ❌ ±0 

Results for commit f622fc8. ± Comparison against base commit 59fa125.

♻️ This comment has been updated with latest results.

sfaqer added 2 commits June 16, 2026 17:55
Если у клиента открыто несколько MCP-roots, прежний выбор первого попавшегося
workspace в type_info/global_member_info был детерминированно неверным для
проектов, где ответ зависит от scope'а: смешанные конфигурация + OneScript,
разные конфигурации с разным составом метаданных и т.п.

Добавлен опциональный параметр `root`: клиент адресует конкретный workspace
по URI из объявленных им roots. Если параметр не задан — старое поведение
(любой зарегистрированный workspace), это нормально для платформенных имён.

McpWorkspaceResolver — единая точка резолва, который нормализует URI через
Absolute.uri (терпим к разным написаниям, включая trailing slash и file://D:\)
и кидает осмысленное «No registered workspace matches root: …», если клиент
указал URI, под которым ни один workspace не зарегистрирован.

Покрыто 6 unit-тестами на сам резолвер и 4 интеграционными в McpToolsTest
для type_info и global_member_info (явный root, неизвестный root).
… платформой Windows

Тест вытаскивает букву диска из реального filesystem-роута тестовой директории
(`path.getRoot().toString().substring(0, 2)` = `D:`), что работоспособно только
на Windows: на Unix getRoot() возвращает `/`, выражение даёт нерабочий URI и
ассерт валится на ubuntu-latest и macOS-latest.

Само правило нормализации `file://D:\path` → `file:///D:/path` остаётся под
кросс-платформенным покрытием через три string-теста normalizeWindowsFileUri*
рядом с этим тестом — они проверяют логику без зависимости от FS.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java (1)

110-113: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix enum payload kind mismatch in global_member_info responses.

For enum lookups, Result.kind is "ENUM" but member.kind is hardcoded to "PROPERTY". That creates contradictory API payloads for the same entity. Use the kind argument when constructing TypeMemberDto.

Proposed fix
   private Result globalValueResult(String requestedName, FileType fileType,
                                    TypeRef valueType, String kind, Language language) {
@@
     var member = new TypeMemberDto(
       canonicalName,
-      "PROPERTY",
+      kind,
       List.of(valueType.qualifiedName()),
       description,
       List.of(),
       false,
       null
     );

Also applies to: 127-142

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java`
around lines 110 - 113, Fix the enum payload kind mismatch where Result.kind is
set to "ENUM" but member.kind is hardcoded to "PROPERTY" in the
GlobalMemberInfoTool class. In the globalValueResult method call at lines
110-113 (anchor location where "ENUM" is passed as the kind argument), ensure
that the kind parameter is properly passed through to the TypeMemberDto
constructor instead of being hardcoded to "PROPERTY". Apply the same fix at the
sibling locations at lines 127-142 where other member type lookups occur,
ensuring that the kind argument provided to the method is consistently used when
constructing TypeMemberDto objects rather than hardcoding a value.
🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java (1)

219-283: ⚡ Quick win

Add explicit tests for property/enum branches of global_member_info.

Current tests validate only function resolution. Please add assertions for property and enum responses (including result.kind and member.kind) to lock the contract and prevent regressions.

As per coding guidelines, “Always run tests before submitting changes and maintain or improve test coverage using appropriate test frameworks (JUnit, AssertJ, Mockito)”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java`
around lines 219 - 283, Add two new test methods to McpToolsTest to cover
property and enum member resolution in the globalMemberInfoTool. Create a test
method for property member resolution (following the pattern of
globalMemberInfoResolvesPlatformFunction) that calls
globalMemberInfoTool.globalMemberInfo with a known property name and asserts
that result.kind() matches the expected value and result.member().kind() is
correct for properties. Create another test method for enum member resolution
using the same pattern with a known enum name. Both tests should include
assertions for result.kind() and result.member().kind() to establish and
maintain the contract for these member types, ensuring comprehensive coverage
beyond the existing function-only tests.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java`:
- Around line 110-113: Fix the enum payload kind mismatch where Result.kind is
set to "ENUM" but member.kind is hardcoded to "PROPERTY" in the
GlobalMemberInfoTool class. In the globalValueResult method call at lines
110-113 (anchor location where "ENUM" is passed as the kind argument), ensure
that the kind parameter is properly passed through to the TypeMemberDto
constructor instead of being hardcoded to "PROPERTY". Apply the same fix at the
sibling locations at lines 127-142 where other member type lookups occur,
ensuring that the kind argument provided to the method is consistently used when
constructing TypeMemberDto objects rather than hardcoding a value.

---

Nitpick comments:
In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java`:
- Around line 219-283: Add two new test methods to McpToolsTest to cover
property and enum member resolution in the globalMemberInfoTool. Create a test
method for property member resolution (following the pattern of
globalMemberInfoResolvesPlatformFunction) that calls
globalMemberInfoTool.globalMemberInfo with a known property name and asserts
that result.kind() matches the expected value and result.member().kind() is
correct for properties. Create another test method for enum member resolution
using the same pattern with a known enum name. Both tests should include
assertions for result.kind() and result.member().kind() to establish and
maintain the contract for these member types, ensuring comprehensive coverage
beyond the existing function-only tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 21da46ec-3c30-43b8-8749-672e0e52fdd8

📥 Commits

Reviewing files that changed from the base of the PR and between 6aeb719 and 4fe50c6.

📒 Files selected for processing (6)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpWorkspaceResolver.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/GlobalMemberInfoTool.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/McpToolParams.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/TypeInfoTool.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpToolsTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/mcp/McpWorkspaceResolverTest.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/McpToolParams.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/mcp/tools/TypeInfoTool.java

sfaqer added 2 commits June 16, 2026 18:36
…info

Прежний выбор «любого» workspace при отсутствии root оставлял место для
тихо неверных ответов: при нескольких roots (конфигурация + OneScript,
разные конфигурации) клиент получал результат из произвольного scope'а
без сигнала, что он промахнулся.

Параметр `root` теперь required, порядок параметров переставлен так, чтобы
все обязательные шли перед опциональными:
  type_info(typeName, fileType, root, language?)
  global_member_info(name, fileType, root, language?)

McpWorkspaceResolver: убрана мёртвая ветка «root не задан → взять любой» —
теперь null/blank сразу даёт IllegalArgumentException «Workspace root is
required», ошибка указывает что именно пропущено.

Тесты обновлены: WORKSPACE_ROOT-константа подставлена во все вызовы;
добавлены кейсы на отсутствующий root и на blank-root.
- McpRootsChangeConsumer.normalizeWindowsFileUri: пометить return как @nullable
  (S2637, BUG — return null в @NullMarked пакете) и вытащить «file://» в
  константу FILE_SCHEME_PREFIX (S1192).
- McpToolSpecificationsBootstrapWrapper: явный тип параметров лямбды wrapHandler
  (S2211).
- TypeMemberMetadataDto.isEmpty: разбить 8-конъюнктное выражение на три
  helper'а по группам полей (S1067).
- TypeParameterDto.from: убрать `defaultValue == null` / `description == null`
  — ParameterDescriptor гарантирует non-null оба поля, проверки always-false
  (S2589).
- GlobalMemberInfoTool: functionResult статический (S2325), убран неиспользуемый
  параметр language у globalValueResult (S1172), `symbol -> symbol.getName()`
  → `Symbol::getName` (S1612).
- Тесты: убран неиспользуемый импорт McpSchema; ListRootsResult, Tool.builder,
  TextContent, CallToolRequest заменены на не-deprecated формы (S1128, S1874).
@sonarqubecloud

Copy link
Copy Markdown

@nixel2007
nixel2007 merged commit 3dd3a91 into develop Jun 16, 2026
37 checks passed
@nixel2007
nixel2007 deleted the feature/mcp-roots-bootstrap-and-rich-type-info branch June 16, 2026 13:31
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.

2 participants