diff --git a/CHANGELOG.md b/CHANGELOG.md index e1d0962..8e2d149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on Keep a Changelog, and this project follows Semantic Versioning. +## [1.1.1] + +### Added +- Added functions to extract and replace module specifiers in import statements. +- Added `@Tool` decorator to store method metadata without exposing proxy methods as tools. + +### Changed +- Implemented relative import rewriting for generated proxy files. +- Enhanced proxy generation to include tool metadata in generated methods. +- Updated proxy scaffold template to conditionally emit `@Tool` based on available method metadata. +- Extended runtime LM tool registration to support both `@ExposeTool` and `@Tool` decorated methods. + +### Fixed +- Ensured grouped imports retain only symbols actually used by generated proxy method signatures. + ## [1.1.0] - 2026-04-29 ### Added @@ -25,5 +40,6 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi ### Added - Initial release baseline. +[1.1.1]: https://github.com/codearchitects/mcp-scanner/releases/tag/v1.1.1 [1.1.0]: https://github.com/codearchitects/mcp-scanner/releases/tag/v1.1.0 [1.0.3]: https://github.com/codearchitects/mcp-scanner/releases/tag/v1.0.3 diff --git a/README.md b/README.md index a92e3ee..8944fdf 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,24 @@ Then declare it in your extension's `package.json`: | `icon` | `string` | | VS Code codicon, e.g. `$(search)`. Default: `$(tools)` | | `canBeReferencedInPrompt` | `boolean` | | Allow `#tool` references. Default: `true` | +### `Tool(options)` — Method Decorator + +Used by code generators (e.g., proxy generation) to preserve tool metadata without exposing the method. +Accepts the same options as `@ExposeTool` but does not register the method as a tool. + +| Option | Type | Required | Description | +|--------|------|----------|-------------| +| `name` | `string` | ✅ | Unique tool name | +| `displayName` | `string` | ✅ | Human-readable label | +| `modelDescription` | `string` | ✅ | Description for the language model | +| `icon` | `string` | | VS Code codicon, e.g. `$(search)`. Default: `$(tools)` | +| `canBeReferencedInPrompt` | `boolean` | | Allow `#tool` references. Default: `true` | + +### `registerExposedTools(context, instances)` — Runtime Registration + +Registers methods decorated with either `@ExposeTool` or `@Tool` as runtime LM tool handlers. +This is useful for proxy-based architectures where generated proxy methods carry `@Tool` metadata. + ### `scanProject(projectRoot, tsconfigFileName?)` — Scanner Returns `IScanResult` with discovered tools, file count, and diagnostics. @@ -254,6 +272,7 @@ The scaffold template (EJS) has access to: - `className`: The class name (set via `--proxy-class` or from template) - `methods`: Array of method objects with: - `toolName`: Tool name from `@ExposeTool({ name })` + - `toolOptions`: Complete metadata object from `@ExposeTool({ displayName, modelDescription, icon, canBeReferencedInPrompt })` - `methodName`: Source method name - `returnTypeText`: Return type text - `jsDoc`: JSDoc comment from source @@ -268,6 +287,7 @@ The scaffold template (EJS) has access to: /* This file is auto-generated by mcp-scanner. */ // +import { Tool } from 'mcp-scanner'; <%- methods.flatMap(m => m.importStatements).filter((v, i, a) => a.indexOf(v) === i).sort().join('\n') %> // @@ -275,7 +295,9 @@ The scaffold template (EJS) has access to: export class <%- className %> { // // - // methods generated here + // JSDoc comment + // @Tool decorator with metadata + // public async method(...) { ... } // } ``` @@ -308,6 +330,54 @@ Injection markers used by the generator: // ``` +## Preserving Tool Metadata in Proxies + +When generating proxy methods, `mcp-scanner` automatically applies the `@Tool` decorator to preserve all original tool metadata (displayName, modelDescription, icon, canBeReferencedInPrompt). + +### Why `@Tool` and not `@ExposeTool`? + +- **`@ExposeTool`** exposes the method as a tool, which would cause the _proxy_ method to appear in `languageModelTools` in addition to the original. This is not desired. +- **`@Tool`** preserves metadata without exposure, allowing language model tools and MCP servers to access the complete tool definition without the proxy being registered as a separate tool. + +### Example Generated Proxy + +Given a source library method: + +```typescript +class MyLibrary { + @ExposeTool({ + name: 'processData', + displayName: 'Process Data', + modelDescription: 'Transforms data according to rules.', + icon: '$(gear)', + }) + processData(params: IDataParams): Promise { ... } +} +``` + +The generated proxy preserves the metadata: + +```typescript +class MyProxyClass { + /** + * Transforms data according to rules. + */ + @Tool({ + name: 'processData', + displayName: 'Process Data', + modelDescription: 'Transforms data according to rules.', + icon: '$(gear)', + }) + public async processData(params: IDataParams): Promise { + // TODO: Replace with your implementation + return await this._bridge.dispatch('processData', params); + } +} +``` + +The `@Tool` decorator is automatically imported from `mcp-scanner` in the proxy file's imports section. + + ## How It Works 1. Loads the project's `tsconfig.json` and creates a TypeScript program diff --git a/coverage/coverage-summary.json b/coverage/coverage-summary.json index 9c8682a..eabad9e 100644 --- a/coverage/coverage-summary.json +++ b/coverage/coverage-summary.json @@ -1,7 +1,8 @@ -{"total": {"lines":{"total":513,"covered":439,"skipped":0,"pct":85.57},"statements":{"total":523,"covered":448,"skipped":0,"pct":85.65},"functions":{"total":70,"covered":63,"skipped":0,"pct":90},"branches":{"total":410,"covered":298,"skipped":0,"pct":72.68},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}} +{"total": {"lines":{"total":568,"covered":480,"skipped":0,"pct":84.5},"statements":{"total":582,"covered":492,"skipped":0,"pct":84.53},"functions":{"total":85,"covered":76,"skipped":0,"pct":89.41},"branches":{"total":455,"covered":329,"skipped":0,"pct":72.3},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}} ,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\patcher.ts": {"lines":{"total":76,"covered":65,"skipped":0,"pct":85.52},"functions":{"total":13,"covered":12,"skipped":0,"pct":92.3},"statements":{"total":82,"covered":70,"skipped":0,"pct":85.36},"branches":{"total":61,"covered":44,"skipped":0,"pct":72.13}} -,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\proxy-generator.ts": {"lines":{"total":117,"covered":96,"skipped":0,"pct":82.05},"functions":{"total":20,"covered":16,"skipped":0,"pct":80},"statements":{"total":117,"covered":96,"skipped":0,"pct":82.05},"branches":{"total":84,"covered":59,"skipped":0,"pct":70.23}} -,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\proxy-scanner.ts": {"lines":{"total":150,"covered":123,"skipped":0,"pct":82},"functions":{"total":18,"covered":16,"skipped":0,"pct":88.88},"statements":{"total":152,"covered":125,"skipped":0,"pct":82.23},"branches":{"total":113,"covered":72,"skipped":0,"pct":63.71}} +,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\proxy-generator.ts": {"lines":{"total":128,"covered":106,"skipped":0,"pct":82.81},"functions":{"total":25,"covered":21,"skipped":0,"pct":84},"statements":{"total":129,"covered":107,"skipped":0,"pct":82.94},"branches":{"total":88,"covered":64,"skipped":0,"pct":72.72}} +,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\proxy-scanner.ts": {"lines":{"total":188,"covered":148,"skipped":0,"pct":78.72},"functions":{"total":25,"covered":21,"skipped":0,"pct":84},"statements":{"total":193,"covered":152,"skipped":0,"pct":78.75},"branches":{"total":150,"covered":94,"skipped":0,"pct":62.66}} ,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\decorators\\expose-tool.decorator.ts": {"lines":{"total":6,"covered":6,"skipped":0,"pct":100},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":6,"covered":6,"skipped":0,"pct":100},"branches":{"total":4,"covered":4,"skipped":0,"pct":100}} +,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\decorators\\tool.decorator.ts": {"lines":{"total":6,"covered":6,"skipped":0,"pct":100},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":6,"covered":6,"skipped":0,"pct":100},"branches":{"total":4,"covered":4,"skipped":0,"pct":100}} ,"C:\\Projects\\CodeArchitects\\mcp-scanner\\src\\scanner\\tool-scanner.ts": {"lines":{"total":164,"covered":149,"skipped":0,"pct":90.85},"functions":{"total":16,"covered":16,"skipped":0,"pct":100},"statements":{"total":166,"covered":151,"skipped":0,"pct":90.96},"branches":{"total":148,"covered":119,"skipped":0,"pct":80.4}} } diff --git a/coverage/index.html b/coverage/index.html index a10269e..c482a84 100644 --- a/coverage/index.html +++ b/coverage/index.html @@ -23,30 +23,30 @@

All files

- 85.65% + 84.53% Statements - 448/523 + 492/582
- 72.68% + 72.3% Branches - 298/410 + 329/455
- 90% + 89.41% Functions - 63/70 + 76/85
- 85.57% + 84.5% Lines - 439/513 + 480/568
@@ -80,17 +80,17 @@

All files

src - -
+ +
- 82.9% - 291/351 - 67.82% - 175/258 - 86.27% - 44/51 - 82.79% - 284/343 + 81.43% + 329/404 + 67.55% + 202/299 + 85.71% + 54/63 + 81.37% + 319/392 @@ -99,13 +99,13 @@

All files

100% - 6/6 - 100% - 4/4 + 12/12 100% - 3/3 + 8/8 100% 6/6 + 100% + 12/12 @@ -131,7 +131,7 @@

All files

+ + + + + + \ No newline at end of file diff --git a/coverage/src/index.html b/coverage/src/index.html index 460cca1..01996dd 100644 --- a/coverage/src/index.html +++ b/coverage/src/index.html @@ -23,30 +23,30 @@

All files src

- 82.9% + 81.43% Statements - 291/351 + 329/404
- 67.82% + 67.55% Branches - 175/258 + 202/299
- 86.27% + 85.71% Functions - 44/51 + 54/63
- 82.79% + 81.37% Lines - 284/343 + 319/392
@@ -95,32 +95,32 @@

All files src

proxy-generator.ts - +
- 82.05% - 96/117 - 70.23% - 59/84 - 80% - 16/20 - 82.05% - 96/117 + 82.94% + 107/129 + 72.72% + 64/88 + 84% + 21/25 + 82.81% + 106/128 - proxy-scanner.ts - -
+ proxy-scanner.ts + +
- 82.23% - 125/152 - 63.71% - 72/113 - 88.88% - 16/18 - 82% - 123/150 + 78.75% + 152/193 + 62.66% + 94/150 + 84% + 21/25 + 78.72% + 148/188 @@ -131,7 +131,7 @@

All files src