tokenlite-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/litemcp.d.ts +19 -0
- package/dist/litemcp.d.ts.map +1 -0
- package/dist/litemcp.js +222 -0
- package/dist/litemcp.js.map +1 -0
- package/dist/search.d.ts +27 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +90 -0
- package/dist/search.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Martin Beiro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# LiteMCP
|
|
2
|
+
|
|
3
|
+
A drop-in replacement for the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk) that adds **intelligent tool discovery** for MCP clients.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
Many AI agents and MCP clients don't have native tool searching. When your server exposes 50+ tools, the client loads *all* tool definitions into the LLM context - wasting tokens and overwhelming the model.
|
|
8
|
+
|
|
9
|
+
LiteMCP solves this by wrapping your tools with:
|
|
10
|
+
|
|
11
|
+
- **`search`** - BM25-ranked tool discovery by name/description
|
|
12
|
+
- **`execute`** - Run any tool by name with arguments
|
|
13
|
+
|
|
14
|
+
Now clients can search for relevant tools instead of loading everything upfront.
|
|
15
|
+
|
|
16
|
+
## Token Savings
|
|
17
|
+
|
|
18
|
+
With 10 tools, LiteMCP reduces base context usage by **~80%**:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────┬─────────────┐
|
|
22
|
+
│ Approach │ Tokens │
|
|
23
|
+
├─────────────────┼─────────────┤
|
|
24
|
+
│ Traditional MCP │ 917 │
|
|
25
|
+
│ LiteMCP (base) │ 162 │
|
|
26
|
+
└─────────────────┴─────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Run `bun run compare-tokens` to see stats for your own tools.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add lean-mcp
|
|
35
|
+
# or
|
|
36
|
+
npm install lean-mcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
LiteMCP has the **exact same API** as `McpServer`:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { LiteMCP } from 'lean-mcp';
|
|
45
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
46
|
+
import { z } from 'zod';
|
|
47
|
+
|
|
48
|
+
const server = new LiteMCP({ name: 'my-server', version: '1.0.0' });
|
|
49
|
+
|
|
50
|
+
// Register tools exactly like McpServer
|
|
51
|
+
server.registerTool(
|
|
52
|
+
'create_user',
|
|
53
|
+
{
|
|
54
|
+
description: 'Create a new user account',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
email: z.string().email(),
|
|
57
|
+
name: z.string(),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
async ({ email, name }) => ({
|
|
61
|
+
content: [{ type: 'text', text: JSON.stringify({ id: '123', email, name }) }],
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const transport = new StdioServerTransport();
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## What Clients See
|
|
70
|
+
|
|
71
|
+
Instead of all your tools, clients see two meta-tools:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"tools": [
|
|
76
|
+
{ "name": "search", "description": "Search available tools..." },
|
|
77
|
+
{ "name": "execute", "description": "Execute a tool by name..." }
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Search with BM25 Ranking
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
// Request
|
|
86
|
+
{ "name": "search", "arguments": { "query": "user" } }
|
|
87
|
+
|
|
88
|
+
// Response - ranked by relevance
|
|
89
|
+
{
|
|
90
|
+
"tools": [
|
|
91
|
+
{ "name": "create_user", "description": "Create a new user account", "inputSchema": {...} },
|
|
92
|
+
{ "name": "get_user", "description": "Get user by ID", "inputSchema": {...} },
|
|
93
|
+
{ "name": "delete_user", "description": "Delete a user", "inputSchema": {...} }
|
|
94
|
+
],
|
|
95
|
+
"total": 3,
|
|
96
|
+
"limit": 10
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Search features:
|
|
101
|
+
- Splits `snake_case` and `camelCase` into words
|
|
102
|
+
- Matches across name and description
|
|
103
|
+
- IDF-weighted scoring (rare terms rank higher)
|
|
104
|
+
- Exact name matches get boosted
|
|
105
|
+
|
|
106
|
+
### Execute Tools
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
// Request
|
|
110
|
+
{ "name": "execute", "arguments": { "tool": "create_user", "arguments": { "email": "a@b.com", "name": "Alice" } } }
|
|
111
|
+
|
|
112
|
+
// Response
|
|
113
|
+
{ "content": [{ "type": "text", "text": "{\"id\":\"123\",\"email\":\"a@b.com\",\"name\":\"Alice\"}" }] }
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Options
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const server = new LiteMCP(
|
|
120
|
+
{ name: 'my-server', version: '1.0.0' },
|
|
121
|
+
{
|
|
122
|
+
liteMode: true, // Enable search+execute (default: true)
|
|
123
|
+
// Set to false for traditional MCP behavior
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Programmatic Token Stats
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const stats = server.getTokenStats();
|
|
132
|
+
console.log(stats);
|
|
133
|
+
// {
|
|
134
|
+
// toolCount: 10,
|
|
135
|
+
// traditional: { tokens: 917, characters: 3667 },
|
|
136
|
+
// liteMcp: { baseTokens: 162, baseCharacters: 646, avgSearchTokens: 283 },
|
|
137
|
+
// savingsPercent: 82
|
|
138
|
+
// }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
bun install # Install dependencies
|
|
145
|
+
bun test # Run tests (40 tests)
|
|
146
|
+
bun run example # Run example server
|
|
147
|
+
bun run inspector # Test with MCP Inspector
|
|
148
|
+
bun run compare-tokens # See token comparison
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,YAAY,EACV,cAAc,EACd,IAAI,EACJ,cAAc,EACd,cAAc,EACd,aAAa,EACb,SAAS,EACT,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type Implementation } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
4
|
+
import type { TokenStats, LiteMCPOptions } from './types.js';
|
|
5
|
+
export declare class LiteMCP extends McpServer {
|
|
6
|
+
private readonly _liteMode;
|
|
7
|
+
constructor(serverInfo: Implementation, options?: LiteMCPOptions);
|
|
8
|
+
/** Check if lite mode is enabled */
|
|
9
|
+
get liteMode(): boolean;
|
|
10
|
+
connect(transport: Transport): Promise<void>;
|
|
11
|
+
private handleSearch;
|
|
12
|
+
/**
|
|
13
|
+
* Get token usage statistics comparing traditional MCP vs LiteMCP approach.
|
|
14
|
+
* Uses ~4 characters per token as approximation.
|
|
15
|
+
*/
|
|
16
|
+
getTokenStats(): TokenStats;
|
|
17
|
+
private handleExecute;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=litemcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"litemcp.d.ts","sourceRoot":"","sources":["../src/litemcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,yCAAyC,CAAC;AAEzF,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG7D,qBAAa,OAAQ,SAAQ,SAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;gBAExB,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,cAAc;IAKhE,oCAAoC;IACpC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAEc,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAoF3D,OAAO,CAAC,YAAY;IAsCpB;;;OAGG;IACH,aAAa,IAAI,UAAU;YA4Eb,aAAa;CA+C5B"}
|
package/dist/litemcp.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';
|
|
4
|
+
import { bm25Search } from './search.js';
|
|
5
|
+
export class LiteMCP extends McpServer {
|
|
6
|
+
_liteMode;
|
|
7
|
+
constructor(serverInfo, options) {
|
|
8
|
+
super(serverInfo, options);
|
|
9
|
+
this._liteMode = options?.liteMode ?? true;
|
|
10
|
+
}
|
|
11
|
+
/** Check if lite mode is enabled */
|
|
12
|
+
get liteMode() {
|
|
13
|
+
return this._liteMode;
|
|
14
|
+
}
|
|
15
|
+
async connect(transport) {
|
|
16
|
+
// Access private _registeredTools via any cast
|
|
17
|
+
const registeredTools = this
|
|
18
|
+
._registeredTools;
|
|
19
|
+
// If not in lite mode, use default SDK behavior
|
|
20
|
+
if (!this._liteMode) {
|
|
21
|
+
await super.connect(transport);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Build lite mode tool definitions
|
|
25
|
+
const searchTool = {
|
|
26
|
+
name: 'search',
|
|
27
|
+
description: 'Search available tools. Returns tool names, descriptions, and input schemas.',
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
query: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
description: 'Filter by name or description',
|
|
34
|
+
},
|
|
35
|
+
limit: {
|
|
36
|
+
type: 'number',
|
|
37
|
+
description: 'Max results to return (default: 10)',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
const executeTool = {
|
|
43
|
+
name: 'execute',
|
|
44
|
+
description: 'Execute a tool by name with the provided arguments.',
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: 'object',
|
|
47
|
+
properties: {
|
|
48
|
+
tool: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
description: 'Name of the tool to execute',
|
|
51
|
+
},
|
|
52
|
+
arguments: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
description: 'Arguments to pass to the tool',
|
|
55
|
+
additionalProperties: true,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
required: ['tool'],
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
// Override tools/list to expose only search + execute
|
|
62
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
63
|
+
return { tools: [searchTool, executeTool] };
|
|
64
|
+
});
|
|
65
|
+
// Override tools/call to route through search/execute
|
|
66
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
67
|
+
const { name, arguments: args = {} } = request.params;
|
|
68
|
+
if (name === 'search') {
|
|
69
|
+
return this.handleSearch(registeredTools, args['query'], args['limit']);
|
|
70
|
+
}
|
|
71
|
+
if (name === 'execute') {
|
|
72
|
+
return this.handleExecute(registeredTools, args['tool'], (args['arguments'] ?? {}));
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
isError: true,
|
|
76
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}. Use 'search' and 'execute'.` }],
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
await super.connect(transport);
|
|
80
|
+
}
|
|
81
|
+
handleSearch(registeredTools, query, limit = 10) {
|
|
82
|
+
const tools = Object.entries(registeredTools)
|
|
83
|
+
.filter(([, tool]) => tool.enabled)
|
|
84
|
+
.map(([name, tool]) => ({
|
|
85
|
+
name,
|
|
86
|
+
description: tool.description,
|
|
87
|
+
inputSchema: tool.inputSchema
|
|
88
|
+
? toJsonSchemaCompat(tool.inputSchema)
|
|
89
|
+
: undefined,
|
|
90
|
+
}));
|
|
91
|
+
// Use BM25 ranking when query is provided
|
|
92
|
+
let results;
|
|
93
|
+
if (query) {
|
|
94
|
+
const ranked = bm25Search(tools, query);
|
|
95
|
+
results = ranked.map((r) => r.doc);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
results = tools;
|
|
99
|
+
}
|
|
100
|
+
// Apply limit
|
|
101
|
+
const total = results.length;
|
|
102
|
+
const limited = results.slice(0, limit);
|
|
103
|
+
return {
|
|
104
|
+
content: [
|
|
105
|
+
{
|
|
106
|
+
type: 'text',
|
|
107
|
+
text: JSON.stringify({ tools: limited, total, limit }, null, 2),
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get token usage statistics comparing traditional MCP vs LiteMCP approach.
|
|
114
|
+
* Uses ~4 characters per token as approximation.
|
|
115
|
+
*/
|
|
116
|
+
getTokenStats() {
|
|
117
|
+
const registeredTools = this
|
|
118
|
+
._registeredTools;
|
|
119
|
+
// Build all tool schemas as they'd appear in traditional tools/list
|
|
120
|
+
const allToolSchemas = Object.entries(registeredTools)
|
|
121
|
+
.filter(([, tool]) => tool.enabled)
|
|
122
|
+
.map(([name, tool]) => ({
|
|
123
|
+
name,
|
|
124
|
+
description: tool.description,
|
|
125
|
+
inputSchema: tool.inputSchema ? toJsonSchemaCompat(tool.inputSchema) : undefined,
|
|
126
|
+
}));
|
|
127
|
+
const traditionalJson = JSON.stringify({ tools: allToolSchemas });
|
|
128
|
+
// LiteMCP base: just search + execute
|
|
129
|
+
const liteMcpBase = JSON.stringify({
|
|
130
|
+
tools: [
|
|
131
|
+
{
|
|
132
|
+
name: 'search',
|
|
133
|
+
description: 'Search available tools. Returns tool names, descriptions, and input schemas.',
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {
|
|
137
|
+
query: { type: 'string', description: 'Filter by name or description' },
|
|
138
|
+
limit: { type: 'number', description: 'Max results to return (default: 10)' },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'execute',
|
|
144
|
+
description: 'Execute a tool by name with the provided arguments.',
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
tool: { type: 'string', description: 'Name of the tool to execute' },
|
|
149
|
+
arguments: { type: 'object', description: 'Arguments to pass to the tool', additionalProperties: true },
|
|
150
|
+
},
|
|
151
|
+
required: ['tool'],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
// Estimate tokens (~4 chars per token)
|
|
157
|
+
const charsPerToken = 4;
|
|
158
|
+
const traditionalTokens = Math.ceil(traditionalJson.length / charsPerToken);
|
|
159
|
+
const liteMcpBaseTokens = Math.ceil(liteMcpBase.length / charsPerToken);
|
|
160
|
+
// Average search result (3 tools)
|
|
161
|
+
const sampleSearchResult = JSON.stringify({
|
|
162
|
+
tools: allToolSchemas.slice(0, 3),
|
|
163
|
+
total: allToolSchemas.length,
|
|
164
|
+
limit: 10,
|
|
165
|
+
});
|
|
166
|
+
const avgSearchTokens = Math.ceil(sampleSearchResult.length / charsPerToken);
|
|
167
|
+
const savings = traditionalTokens > 0
|
|
168
|
+
? Math.round((1 - liteMcpBaseTokens / traditionalTokens) * 100)
|
|
169
|
+
: 0;
|
|
170
|
+
return {
|
|
171
|
+
toolCount: allToolSchemas.length,
|
|
172
|
+
traditional: {
|
|
173
|
+
tokens: traditionalTokens,
|
|
174
|
+
characters: traditionalJson.length,
|
|
175
|
+
},
|
|
176
|
+
liteMcp: {
|
|
177
|
+
baseTokens: liteMcpBaseTokens,
|
|
178
|
+
baseCharacters: liteMcpBase.length,
|
|
179
|
+
avgSearchTokens,
|
|
180
|
+
},
|
|
181
|
+
savingsPercent: savings,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async handleExecute(registeredTools, toolName, args) {
|
|
185
|
+
const tool = registeredTools[toolName];
|
|
186
|
+
if (!tool) {
|
|
187
|
+
return {
|
|
188
|
+
isError: true,
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: 'text',
|
|
192
|
+
text: `Unknown tool: "${toolName}". Use the search tool to list available tools.`,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
if (!tool.enabled) {
|
|
198
|
+
return {
|
|
199
|
+
isError: true,
|
|
200
|
+
content: [{ type: 'text', text: `Tool "${toolName}" is disabled.` }],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
// Call the original handler
|
|
205
|
+
const handler = tool.handler;
|
|
206
|
+
const result = await handler(args, {});
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
return {
|
|
211
|
+
isError: true,
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: `Tool error: ${error instanceof Error ? error.message : String(error)}`,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=litemcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"litemcp.js","sourceRoot":"","sources":["../src/litemcp.ts"],"names":[],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BM25 search implementation for tool discovery.
|
|
3
|
+
*
|
|
4
|
+
* BM25 (Best Matching 25) is a ranking function used by search engines.
|
|
5
|
+
* It considers term frequency, document length, and inverse document frequency.
|
|
6
|
+
*/
|
|
7
|
+
/** A searchable document with name and optional description */
|
|
8
|
+
export interface SearchableDoc {
|
|
9
|
+
name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Search result with relevance score */
|
|
13
|
+
export interface SearchResult<T extends SearchableDoc> {
|
|
14
|
+
doc: T;
|
|
15
|
+
score: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* BM25 search implementation.
|
|
19
|
+
*
|
|
20
|
+
* @param docs - Documents to search
|
|
21
|
+
* @param query - Search query string
|
|
22
|
+
* @param k1 - Term frequency saturation (default: 1.5)
|
|
23
|
+
* @param b - Document length normalization (default: 0.75)
|
|
24
|
+
* @returns Sorted results with scores (highest first)
|
|
25
|
+
*/
|
|
26
|
+
export declare function bm25Search<T extends SearchableDoc>(docs: T[], query: string, k1?: number, b?: number): SearchResult<T>[];
|
|
27
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yCAAyC;AACzC,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,aAAa;IACnD,GAAG,EAAE,CAAC,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;CACf;AAkBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,aAAa,EAChD,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,EAAE,SAAM,EACR,CAAC,SAAO,GACP,YAAY,CAAC,CAAC,CAAC,EAAE,CAqEnB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BM25 search implementation for tool discovery.
|
|
3
|
+
*
|
|
4
|
+
* BM25 (Best Matching 25) is a ranking function used by search engines.
|
|
5
|
+
* It considers term frequency, document length, and inverse document frequency.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Tokenize text into searchable terms.
|
|
9
|
+
* Splits on word boundaries, lowercases, and handles snake_case/camelCase.
|
|
10
|
+
*/
|
|
11
|
+
function tokenize(text) {
|
|
12
|
+
return text
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
// Split camelCase: "createUser" -> "create User"
|
|
15
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
16
|
+
// Split snake_case: "create_user" -> "create user"
|
|
17
|
+
.replace(/_/g, ' ')
|
|
18
|
+
// Split on non-alphanumeric
|
|
19
|
+
.split(/[^a-z0-9]+/)
|
|
20
|
+
.filter((t) => t.length > 0);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* BM25 search implementation.
|
|
24
|
+
*
|
|
25
|
+
* @param docs - Documents to search
|
|
26
|
+
* @param query - Search query string
|
|
27
|
+
* @param k1 - Term frequency saturation (default: 1.5)
|
|
28
|
+
* @param b - Document length normalization (default: 0.75)
|
|
29
|
+
* @returns Sorted results with scores (highest first)
|
|
30
|
+
*/
|
|
31
|
+
export function bm25Search(docs, query, k1 = 1.5, b = 0.75) {
|
|
32
|
+
if (!query.trim()) {
|
|
33
|
+
// No query = return all with score 0
|
|
34
|
+
return docs.map((doc) => ({ doc, score: 0 }));
|
|
35
|
+
}
|
|
36
|
+
const queryTerms = tokenize(query);
|
|
37
|
+
if (queryTerms.length === 0) {
|
|
38
|
+
return docs.map((doc) => ({ doc, score: 0 }));
|
|
39
|
+
}
|
|
40
|
+
// Build corpus: combine name + description for each doc
|
|
41
|
+
const corpus = docs.map((doc) => {
|
|
42
|
+
const text = `${doc.name} ${doc.description ?? ''}`;
|
|
43
|
+
return tokenize(text);
|
|
44
|
+
});
|
|
45
|
+
// Calculate average document length
|
|
46
|
+
const totalLength = corpus.reduce((sum, terms) => sum + terms.length, 0);
|
|
47
|
+
const avgdl = totalLength / corpus.length || 1;
|
|
48
|
+
// Calculate IDF for each query term
|
|
49
|
+
const N = docs.length;
|
|
50
|
+
const idf = new Map();
|
|
51
|
+
for (const term of queryTerms) {
|
|
52
|
+
// Count documents containing this term
|
|
53
|
+
const docsWithTerm = corpus.filter((docTerms) => docTerms.includes(term)).length;
|
|
54
|
+
// IDF formula: log((N - n + 0.5) / (n + 0.5) + 1)
|
|
55
|
+
const idfValue = Math.log((N - docsWithTerm + 0.5) / (docsWithTerm + 0.5) + 1);
|
|
56
|
+
idf.set(term, idfValue);
|
|
57
|
+
}
|
|
58
|
+
// Calculate BM25 score for each document
|
|
59
|
+
const results = docs.map((doc, i) => {
|
|
60
|
+
const docTerms = corpus[i] ?? [];
|
|
61
|
+
const docLength = docTerms.length;
|
|
62
|
+
let score = 0;
|
|
63
|
+
for (const term of queryTerms) {
|
|
64
|
+
// Term frequency in this document
|
|
65
|
+
const tf = docTerms.filter((t) => t === term).length;
|
|
66
|
+
if (tf === 0)
|
|
67
|
+
continue;
|
|
68
|
+
const termIdf = idf.get(term) ?? 0;
|
|
69
|
+
// BM25 formula
|
|
70
|
+
const numerator = tf * (k1 + 1);
|
|
71
|
+
const denominator = tf + k1 * (1 - b + b * (docLength / avgdl));
|
|
72
|
+
score += termIdf * (numerator / denominator);
|
|
73
|
+
}
|
|
74
|
+
// Boost exact name matches
|
|
75
|
+
const nameLower = doc.name.toLowerCase();
|
|
76
|
+
const queryLower = query.toLowerCase();
|
|
77
|
+
if (nameLower === queryLower) {
|
|
78
|
+
score += 10; // Strong boost for exact match
|
|
79
|
+
}
|
|
80
|
+
else if (nameLower.includes(queryLower)) {
|
|
81
|
+
score += 2; // Mild boost for substring match in name
|
|
82
|
+
}
|
|
83
|
+
return { doc, score };
|
|
84
|
+
});
|
|
85
|
+
// Filter to only docs with positive scores and sort by score descending
|
|
86
|
+
return results
|
|
87
|
+
.filter((r) => r.score > 0)
|
|
88
|
+
.sort((a, b) => b.score - a.score);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type { CallToolResult, Tool, Implementation, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export type { RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
export type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
export type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
5
|
+
import type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
|
|
6
|
+
/** LiteMCP server options */
|
|
7
|
+
export interface LiteMCPOptions extends ServerOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Enable lite mode (search + execute).
|
|
10
|
+
* When false, behaves like standard McpServer (all tools exposed directly).
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
liteMode?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Token usage statistics for comparing traditional MCP vs LiteMCP */
|
|
16
|
+
export interface TokenStats {
|
|
17
|
+
/** Number of registered tools */
|
|
18
|
+
toolCount: number;
|
|
19
|
+
/** Traditional MCP approach (all tools in tools/list) */
|
|
20
|
+
traditional: {
|
|
21
|
+
tokens: number;
|
|
22
|
+
characters: number;
|
|
23
|
+
};
|
|
24
|
+
/** LiteMCP approach (search + execute only) */
|
|
25
|
+
liteMcp: {
|
|
26
|
+
/** Base tokens for search + execute tools */
|
|
27
|
+
baseTokens: number;
|
|
28
|
+
baseCharacters: number;
|
|
29
|
+
/** Average tokens for a search result (3 tools) */
|
|
30
|
+
avgSearchTokens: number;
|
|
31
|
+
};
|
|
32
|
+
/** Percentage savings in base context */
|
|
33
|
+
savingsPercent: number;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,YAAY,EACV,cAAc,EACd,IAAI,EACJ,cAAc,GACf,MAAM,oCAAoC,CAAC;AAE5C,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAE9E,YAAY,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE/E,YAAY,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE/E,6BAA6B;AAC7B,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,+CAA+C;IAC/C,OAAO,EAAE;QACP,6CAA6C;QAC7C,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,mDAAmD;QACnD,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tokenlite-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight MCP proxy wrapper for tool interception and composition",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "bun run --watch src/index.ts",
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"start": "bun run src/index.ts",
|
|
21
|
+
"test": "bun test",
|
|
22
|
+
"lint": "eslint src/",
|
|
23
|
+
"format": "prettier --write src/",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"prepublishOnly": "bun run build && bun test",
|
|
26
|
+
"example": "bun run examples/basic.ts",
|
|
27
|
+
"inspector": "npx @modelcontextprotocol/inspector bun run examples/basic.ts",
|
|
28
|
+
"compare-tokens": "bun run scripts/compare-tokens.ts"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"mcp",
|
|
32
|
+
"model-context-protocol",
|
|
33
|
+
"proxy",
|
|
34
|
+
"tools"
|
|
35
|
+
],
|
|
36
|
+
"author": "",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
40
|
+
"zod": "^4.3.6"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/bun": "latest",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
45
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
46
|
+
"eslint": "^10.0.1",
|
|
47
|
+
"prettier": "^3.8.1",
|
|
48
|
+
"typescript": "^5.9.3"
|
|
49
|
+
}
|
|
50
|
+
}
|