Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **`scripts/install.sh` and `scripts/install.ps1`** — one-command installers for Linux/macOS (`curl -fsSL .../install.sh | sh`) and Windows (`irm .../install.ps1 | iex`). Both detect OS/architecture, resolve the latest (or a pinned `MCPLS_VERSION`/`-Version`) GitHub Release via the `/releases/latest/download/` convention, verify the published SHA256 checksum before extracting, and install `mcpls` to `~/.local/bin` (`$HOME\.local\bin` on Windows) without requiring `sudo`. `install.sh` is POSIX `sh` and shellcheck-clean; a `shellcheck` CI job lints it, gated by a new `detect-changes` `scripts` output (`scripts/**`, `.github/workflows/ci.yml`) so it only runs when those paths change. The `security` (cargo-deny) job is now likewise gated on the existing `run-full-ci` output, so a docs-only or scripts-only change no longer triggers a full dependency/license audit. README's Installation section now documents both scripts as the primary install method, keeps `cargo install mcpls` as an alternative, and fixes the pre-built-binaries table to the real target-triple archive names produced by `release.yml` (the previous table referenced stale/nonexistent names, including a musl build that has never been produced by CI). (#288)

- **`skills/mcpls/` Agent Skill** — a spec-compliant [Agent Skill](https://agentskills.io/specification) (`SKILL.md` + `references/configuration.md`) teaching an AI coding agent to install mcpls, choose CLI flags/`MCPLS_*` environment variables, register mcpls with an MCP client, and write `mcpls.toml`, including the per-platform config-path table, the project-config trust model, and the `--listen`/`transport-http` feature-gate asymmetry. (#252)
- **`ToolAnnotations` (`readOnlyHint`, `destructiveHint`, `idempotentHint`) plus top-level `Tool.title` on all 20 `#[tool]` definitions** in `mcp/server.rs` — MCP clients can now use these hints to decide when to skip confirmation dialogs. All 20 tools are marked `readOnlyHint=true`: mcpls has no write-back path today, so even `rename_symbol`, `format_document`, and `get_code_actions` only return a proposed edit rather than applying one — revisit their classification if a write-back path is added. (#136)
- **`ToolAnnotations` (`readOnlyHint`, `destructiveHint`, `idempotentHint`) plus top-level `Tool.title` on all 20 `#[tool]` definitions** in `mcp/server.rs` — MCP clients can now use these hints to decide when to skip confirmation dialogs. All 20 tools are marked `readOnlyHint=true`: mcpls has no write-back path today, so even `rename_symbol`, `format_document`, and `get_code_actions` only return a proposed edit rather than applying one — revisit their classification if a write-back path is added. Superseded by #301 below, which moves these per-tool declarations to a single central pass. (#136)
- **Shared `PositionParams`/`RangeParams` structs** in `mcp/tools.rs`, embedded via `#[serde(flatten)]` in the eleven tool-parameter structs that previously repeated the `file_path`/`line`/`character` trio or the `start_line`/`start_character`/`end_line`/`end_character` quad verbatim. The MCP wire format (flat JSON) and generated JSON schema are unchanged. (#235)
- **`LspServerConfig::request_timeout_seconds`** — per-request LSP timeout, configurable per server and separate from the handshake-only `timeout_seconds`. Defaults to 30s (bit-identical to the previous hardcoded behavior). Bounds a single request attempt, not a whole tool call: on a `-32802` (`ServerCancelled`) response, `LspClient::request` retries up to 4 attempts total, so the worst-case latency for one tool call is `4 * request_timeout_seconds + 3.5s`. `LspClient::request_timeout()`/`completion_timeout()` accessors expose the effective value; `completion_timeout()` clamps to at most 10s regardless of the configured value — an explicit MVP ceiling, not an oversight. See `docs/user-guide/configuration.md#request_timeout_seconds`. (#267)
- **`Error::CapabilityNotSupported`** — new `Error` variant returned when the LSP server routed for a request does not advertise the `ServerCapabilities` field a capability-gated tool needs. (#240)
Expand Down Expand Up @@ -42,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **`serve`/`serve_with` now validate caller-supplied `ServerConfig`s** — Breaking change: previously `ServerConfig::validate()` only ran on the TOML-loading path (`load`/`load_from`), so a `ServerConfig` built programmatically by a library embedder skipped validation entirely and only surfaced misconfiguration later as silent accessor-level clamping (e.g. `LspClient::request_timeout()`). `serve_with` (and `serve`, which delegates to it) now call `validate()` unconditionally, so an invalid caller-supplied config (empty `command`/`language_id`, zero `timeout_seconds`/`request_timeout_seconds`, empty or duplicate-tool `handles`) is rejected up front with the same `Error::InvalidConfig` the TOML path already returns. A config that was previously accepted silently by `serve`/`serve_with` despite failing these checks will now return an error instead. (#282)
- **`ServerInitConfig` gains a `position_encodings` field** — carries the configured position-encoding preference order into `LspServer::spawn`'s `initialize` handshake (see Fixed below). Breaking change: existing `ServerInitConfig { .. }` struct-literal construction (not behind `#[non_exhaustive]`) must add `position_encodings`. Also breaking: `ServerConfig::validate()` now rejects an empty `workspace.position_encodings` list or any value other than `"utf-8"`/`"utf-16"`/`"utf-32"` — a config that previously left this garbage had it silently ignored; it now fails to load. (#287)
- **`bridge::translator` position-conversion helpers are now `async`** — Breaking change: `EncodingCtx`'s `to_lsp`/`to_mcp`/`normalize_range`/`denormalize_range`, roughly twenty `Translator` handler/helper methods that call them, and `diagnostics_from_cache_entry`/`merge_diagnostics` all gained `async`, needed to `.await` the disk-read fallback used by the negotiated-encoding fix below. No MCP tool's external request/response shape changed. Acceptable pre-1.0. (#290)
- **`mcp::server`'s per-tool `annotations(...)` blocks replaced by a single central pass** — the identical `read_only_hint = true, destructive_hint = false, idempotent_hint = true` triple, previously repeated on all 20 `#[tool(...)]` attributes, is now applied once by `McplsServer::tool_router()`, which retags the impl block `#[tool_router(router = declared_tool_router)]` and fills in any route missing `annotations` via `ToolAnnotations::from_raw`. A tool that declares its own `annotations(...)` keeps them. No client-visible change: the resulting `Tool` values are byte-identical to the previous per-tool declarations (pinned by a new golden-snapshot test, `tool_surface.json`). Also collapsed the redundant `let result = { ... }; to_tool_result(result)` two-statement pattern in 19 of the 20 handlers down to a single `to_tool_result(...)` expression; `get_cached_diagnostics` keeps its `let` binding since its body is a multi-arm `match`, not a single expression. (#301)
- **`mcp::tools`'s six position-only parameter wrappers collapsed into `PositionParams`** — `HoverParams`, `DefinitionParams`, `SignatureHelpParams`, `GoToImplementationParams`, `GoToTypeDefinitionParams`, and `CallHierarchyPrepareParams` each wrapped `PositionParams` with `#[serde(flatten)]` and added nothing: `rmcp`'s schema validation already strips the top-level `title`/`description` these wrappers carried before it reaches an MCP client, so the six were structurally identical to `PositionParams` itself. The six corresponding `#[tool]` handlers (`get_hover`, `get_definition`, `get_signature_help`, `go_to_implementation`, `go_to_type_definition`, `prepare_call_hierarchy`) now take `Parameters<PositionParams>` directly. No client-visible schema or wire-format change. (#302)

### Removed

- **`mcpls_core::mcp::{HoverParams, DefinitionParams, CallHierarchyPrepareParams}`** — Breaking change: removed along with the other three position-only wrapper structs described above (`SignatureHelpParams`, `GoToImplementationParams`, `GoToTypeDefinitionParams` were never re-exported from `mcp::mod`). Use `mcpls_core::mcp::PositionParams` directly. No deprecation shim, per pre-1.0 policy. (#302)

### Fixed

Expand Down
6 changes: 3 additions & 3 deletions crates/mcpls-core/src/mcp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod tools;

pub use server::McplsServer;
pub use tools::{
CallHierarchyCallsParams, CallHierarchyPrepareParams, CompletionsParams, DefinitionParams,
DiagnosticsParams, DocumentSymbolsParams, FormatDocumentParams, HoverParams, PositionParams,
RangeParams, ReferencesParams, RenameParams, WorkspaceSymbolParams,
CallHierarchyCallsParams, CompletionsParams, DiagnosticsParams, DocumentSymbolsParams,
FormatDocumentParams, PositionParams, RangeParams, ReferencesParams, RenameParams,
WorkspaceSymbolParams,
};
Loading
Loading