toolception 0.5.5 → 0.6.1
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/README.md +114 -0
- package/dist/http/FastifyTransport.d.ts +40 -4
- package/dist/http/FastifyTransport.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +844 -577
- package/dist/index.js.map +1 -1
- package/dist/meta/registerMetaTools.d.ts +12 -1
- package/dist/meta/registerMetaTools.d.ts.map +1 -1
- package/dist/mode/ModuleResolver.d.ts.map +1 -1
- package/dist/server/createMcpServer.d.ts +20 -1
- package/dist/server/createMcpServer.d.ts.map +1 -1
- package/dist/server/createPermissionBasedMcpServer.d.ts.map +1 -1
- package/dist/session/SessionContextResolver.d.ts +115 -0
- package/dist/session/SessionContextResolver.d.ts.map +1 -0
- package/dist/session/validateSessionContextConfig.d.ts +10 -0
- package/dist/session/validateSessionContextConfig.d.ts.map +1 -0
- package/dist/types/index.d.ts +103 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- [Permission-based starter guide](#permission-based-starter-guide)
|
|
12
12
|
- [Permission configuration approaches](#permission-configuration-approaches)
|
|
13
13
|
- [Custom HTTP endpoints](#custom-http-endpoints)
|
|
14
|
+
- [Per-session context](#per-session-context)
|
|
14
15
|
- [API](#api)
|
|
15
16
|
- [createMcpServer](#createmcpserveroptions)
|
|
16
17
|
- [createPermissionBasedMcpServer](#createpermissionbasedmcpserveroptions)
|
|
@@ -39,6 +40,7 @@ Toolception addresses this by grouping tools into toolsets and letting you expos
|
|
|
39
40
|
- **Large or multi-domain catalogs**: You have >20–50 tools or multiple domains (e.g., search, data, billing) and don’t want to expose them all at once.
|
|
40
41
|
- **Task-specific workflows**: You want the client/agent to enable only the tools relevant to the current task.
|
|
41
42
|
- **Multi-tenant or policy needs**: Different users/tenants require different tool access or limits.
|
|
43
|
+
- **Per-session context**: You need different context values (API tokens, user IDs) for each client session passed to module loaders.
|
|
42
44
|
- **Permission-based access control**: You need to enforce client-specific toolset permissions for security, compliance, or multi-tenant isolation. Each client should only see and access the toolsets they're authorized to use, with server-side or header-based permission enforcement.
|
|
43
45
|
- **Collision-safe naming**: You need predictable, namespaced tool names to avoid conflicts.
|
|
44
46
|
- **Lazy loading**: Some tools are heavy and should be loaded on demand.
|
|
@@ -719,6 +721,88 @@ Custom endpoints cannot override built-in MCP paths:
|
|
|
719
721
|
|
|
720
722
|
See `examples/custom-endpoints-demo.ts` for a full working example with GET, POST, PUT, DELETE endpoints, pagination, and permission-aware handlers.
|
|
721
723
|
|
|
724
|
+
## Per-session context
|
|
725
|
+
|
|
726
|
+
Use the `sessionContext` option to enable per-client context values extracted from query parameters. This is useful for multi-tenant scenarios where each client needs different configuration (API tokens, user IDs, etc.) passed to module loaders.
|
|
727
|
+
|
|
728
|
+
### Basic usage
|
|
729
|
+
|
|
730
|
+
```ts
|
|
731
|
+
import { createMcpServer } from "toolception";
|
|
732
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
733
|
+
|
|
734
|
+
const { start } = await createMcpServer({
|
|
735
|
+
catalog: { /* ... */ },
|
|
736
|
+
moduleLoaders: { /* ... */ },
|
|
737
|
+
context: { baseValue: 'shared' }, // Base context for all sessions
|
|
738
|
+
sessionContext: {
|
|
739
|
+
enabled: true,
|
|
740
|
+
queryParam: {
|
|
741
|
+
name: 'config',
|
|
742
|
+
encoding: 'base64',
|
|
743
|
+
allowedKeys: ['API_TOKEN', 'USER_ID'], // Security: always specify
|
|
744
|
+
},
|
|
745
|
+
merge: 'shallow',
|
|
746
|
+
},
|
|
747
|
+
createServer: () => new McpServer({
|
|
748
|
+
name: "my-server",
|
|
749
|
+
version: "1.0.0",
|
|
750
|
+
capabilities: { tools: { listChanged: true } },
|
|
751
|
+
}),
|
|
752
|
+
http: { port: 3000 },
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
await start();
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Client connection
|
|
759
|
+
|
|
760
|
+
```bash
|
|
761
|
+
# Encode session config as base64
|
|
762
|
+
CONFIG=$(echo -n '{"API_TOKEN":"user-secret-token","USER_ID":"123"}' | base64)
|
|
763
|
+
|
|
764
|
+
# Connect with session config
|
|
765
|
+
curl -X POST "http://localhost:3000/mcp?config=$CONFIG" \
|
|
766
|
+
-H "mcp-client-id: my-client" \
|
|
767
|
+
-H "Content-Type: application/json" \
|
|
768
|
+
-d '{"jsonrpc":"2.0","method":"initialize",...}'
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Module loader receives merged context
|
|
772
|
+
|
|
773
|
+
```ts
|
|
774
|
+
const moduleLoaders = {
|
|
775
|
+
tenant: async (ctx: any) => {
|
|
776
|
+
// ctx = { baseValue: 'shared', API_TOKEN: 'user-secret-token', USER_ID: '123' }
|
|
777
|
+
return [/* tools using ctx.API_TOKEN */];
|
|
778
|
+
},
|
|
779
|
+
};
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Custom context resolver
|
|
783
|
+
|
|
784
|
+
For advanced use cases, provide a custom resolver function:
|
|
785
|
+
|
|
786
|
+
```ts
|
|
787
|
+
sessionContext: {
|
|
788
|
+
enabled: true,
|
|
789
|
+
queryParam: { allowedKeys: ['tenant_id'] },
|
|
790
|
+
contextResolver: (request, baseContext, parsedConfig) => ({
|
|
791
|
+
...baseContext,
|
|
792
|
+
...parsedConfig,
|
|
793
|
+
clientId: request.clientId,
|
|
794
|
+
timestamp: Date.now(),
|
|
795
|
+
}),
|
|
796
|
+
}
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### Security considerations
|
|
800
|
+
|
|
801
|
+
- **Always specify `allowedKeys`**: Without a whitelist, any key in the query config is accepted
|
|
802
|
+
- **Fail-secure**: Invalid encoding silently falls back to base context
|
|
803
|
+
- **No logging of values**: Session config values are never logged
|
|
804
|
+
- **Filtered silently**: Disallowed keys are filtered without error messages
|
|
805
|
+
|
|
722
806
|
## API
|
|
723
807
|
|
|
724
808
|
### createMcpServer(options)
|
|
@@ -864,6 +948,28 @@ const moduleLoaders = {
|
|
|
864
948
|
};
|
|
865
949
|
```
|
|
866
950
|
|
|
951
|
+
#### options.sessionContext (optional)
|
|
952
|
+
|
|
953
|
+
`SessionContextConfig`
|
|
954
|
+
|
|
955
|
+
Configuration for per-session context extraction from query parameters. Enables multi-tenant use cases where each client session can have its own context values passed to module loaders. See [Per-session context](#per-session-context) for detailed usage examples.
|
|
956
|
+
|
|
957
|
+
| Field | Type | Default | Description |
|
|
958
|
+
|-------|------|---------|-------------|
|
|
959
|
+
| `enabled` | `boolean` | `true` | Whether session context extraction is enabled |
|
|
960
|
+
| `queryParam.name` | `string` | `'config'` | Query parameter name |
|
|
961
|
+
| `queryParam.encoding` | `'base64' \| 'json'` | `'base64'` | Encoding format |
|
|
962
|
+
| `queryParam.allowedKeys` | `string[]` | - | Whitelist of allowed keys (recommended for security) |
|
|
963
|
+
| `contextResolver` | `function` | - | Custom context resolver function |
|
|
964
|
+
| `merge` | `'shallow' \| 'deep'` | `'shallow'` | How to merge with base context |
|
|
965
|
+
|
|
966
|
+
Notes
|
|
967
|
+
|
|
968
|
+
- Session context is extracted per-request and merged with the base `context` option
|
|
969
|
+
- Each unique session config generates a different cache key, enabling per-tenant module caching
|
|
970
|
+
- Invalid encoding or parsing errors silently fall back to base context (fail-secure)
|
|
971
|
+
- Only applies to DYNAMIC mode servers; STATIC mode uses a single shared server instance
|
|
972
|
+
|
|
867
973
|
#### options.http (optional)
|
|
868
974
|
|
|
869
975
|
`{ host?: string; port?: number; basePath?: string; cors?: boolean; logger?: boolean; customEndpoints?: CustomEndpointDefinition[] }`
|
|
@@ -970,6 +1076,14 @@ Same as `createMcpServer` - see [options.configSchema](#optionsconfigschema-opti
|
|
|
970
1076
|
|
|
971
1077
|
Same as `createMcpServer` - see [options.context](#optionscontext-optional).
|
|
972
1078
|
|
|
1079
|
+
#### options.sessionContext (optional)
|
|
1080
|
+
|
|
1081
|
+
`SessionContextConfig`
|
|
1082
|
+
|
|
1083
|
+
Session context is available in permission-based servers but has limited support. Because permission-based servers determine toolsets at connection time based on permissions, the session context cannot affect which toolsets are loaded. However, the merged context is still passed to module loaders.
|
|
1084
|
+
|
|
1085
|
+
**Note:** A warning is issued if `sessionContext` is used with `createPermissionBasedMcpServer`. For full session context support with per-session toolset caching, use `createMcpServer` with DYNAMIC mode.
|
|
1086
|
+
|
|
973
1087
|
### Meta-tools
|
|
974
1088
|
|
|
975
1089
|
Meta-tools are registered based on mode:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FastifyInstance } from 'fastify';
|
|
2
2
|
import { DynamicToolManager } from '../core/DynamicToolManager.js';
|
|
3
3
|
import { ServerOrchestrator } from '../core/ServerOrchestrator.js';
|
|
4
|
+
import { SessionContextResolver } from '../session/SessionContextResolver.js';
|
|
4
5
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
6
|
import { CustomEndpointDefinition } from './customEndpoints.js';
|
|
6
7
|
export interface FastifyTransportOptions {
|
|
@@ -16,17 +17,24 @@ export interface FastifyTransportOptions {
|
|
|
16
17
|
*/
|
|
17
18
|
customEndpoints?: CustomEndpointDefinition[];
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Callback type for creating a server bundle.
|
|
22
|
+
* Accepts an optional merged context for per-session context support.
|
|
23
|
+
*/
|
|
24
|
+
export type CreateBundleCallback = (mergedContext?: unknown) => {
|
|
25
|
+
server: McpServer;
|
|
26
|
+
orchestrator: ServerOrchestrator;
|
|
27
|
+
};
|
|
19
28
|
export declare class FastifyTransport {
|
|
20
29
|
private readonly options;
|
|
21
30
|
private readonly defaultManager;
|
|
22
31
|
private readonly createBundle;
|
|
32
|
+
private readonly sessionContextResolver?;
|
|
33
|
+
private readonly baseContext?;
|
|
23
34
|
private app;
|
|
24
35
|
private readonly configSchema?;
|
|
25
36
|
private readonly clientCache;
|
|
26
|
-
constructor(defaultManager: DynamicToolManager, createBundle:
|
|
27
|
-
server: McpServer;
|
|
28
|
-
orchestrator: ServerOrchestrator;
|
|
29
|
-
}, options?: FastifyTransportOptions, configSchema?: object);
|
|
37
|
+
constructor(defaultManager: DynamicToolManager, createBundle: CreateBundleCallback, options?: FastifyTransportOptions, configSchema?: object, sessionContextResolver?: SessionContextResolver, baseContext?: unknown);
|
|
30
38
|
start(): Promise<void>;
|
|
31
39
|
/**
|
|
32
40
|
* Stops the Fastify server and cleans up all resources.
|
|
@@ -40,5 +48,33 @@ export declare class FastifyTransport {
|
|
|
40
48
|
* @private
|
|
41
49
|
*/
|
|
42
50
|
private cleanupBundle;
|
|
51
|
+
/**
|
|
52
|
+
* Resolves the session context and generates a cache key for the request.
|
|
53
|
+
* If a session context resolver is configured, it extracts query parameters
|
|
54
|
+
* and merges session-specific context with the base context.
|
|
55
|
+
*
|
|
56
|
+
* @param req - The Fastify request
|
|
57
|
+
* @param clientId - The client identifier
|
|
58
|
+
* @returns Object with cache key and merged context
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
private resolveSessionContext;
|
|
62
|
+
/**
|
|
63
|
+
* Extracts headers from a Fastify request as a Record.
|
|
64
|
+
* Normalizes header names to lowercase.
|
|
65
|
+
*
|
|
66
|
+
* @param req - The Fastify request
|
|
67
|
+
* @returns Headers as a string record
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
private extractHeaders;
|
|
71
|
+
/**
|
|
72
|
+
* Extracts query parameters from a Fastify request as a Record.
|
|
73
|
+
*
|
|
74
|
+
* @param req - The Fastify request
|
|
75
|
+
* @returns Query parameters as a string record
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
private extractQuery;
|
|
43
79
|
}
|
|
44
80
|
//# sourceMappingURL=FastifyTransport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FastifyTransport.d.ts","sourceRoot":"","sources":["../../src/http/FastifyTransport.ts"],"names":[],"mappings":"AAAA,OAAgB,EACd,KAAK,eAAe,EAGrB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"FastifyTransport.d.ts","sourceRoot":"","sources":["../../src/http/FastifyTransport.ts"],"names":[],"mappings":"AAAA,OAAgB,EACd,KAAK,eAAe,EAGrB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAInF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB;;;OAGG;IACH,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,aAAa,CAAC,EAAE,OAAO,KAAK;IAC9D,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAQtB;IACF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAyB;IACjE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAU;IACvC,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IAGvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CASzB;gBAGD,cAAc,EAAE,kBAAkB,EAClC,YAAY,EAAE,oBAAoB,EAClC,OAAO,GAAE,uBAA4B,EACrC,YAAY,CAAC,EAAE,MAAM,EACrB,sBAAsB,CAAC,EAAE,sBAAsB,EAC/C,WAAW,CAAC,EAAE,OAAO;IAkBV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwMnC;;;OAGG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYlC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAmBrB;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAqC7B;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAYtB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;CAYrB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { createMcpServer } from './server/createMcpServer.js';
|
|
2
2
|
export type { CreateMcpServerOptions } from './server/createMcpServer.js';
|
|
3
3
|
export { createPermissionBasedMcpServer } from './server/createPermissionBasedMcpServer.js';
|
|
4
|
-
export type { ToolSetCatalog, ToolSetDefinition, McpToolDefinition, ExposurePolicy, Mode, ModuleLoader, PermissionConfig, CreatePermissionBasedMcpServerOptions, } from './types/index.js';
|
|
4
|
+
export type { ToolSetCatalog, ToolSetDefinition, McpToolDefinition, ExposurePolicy, Mode, ModuleLoader, PermissionConfig, CreatePermissionBasedMcpServerOptions, SessionContextConfig, SessionRequestContext, } from './types/index.js';
|
|
5
|
+
export { SessionContextResolver } from './session/SessionContextResolver.js';
|
|
6
|
+
export type { SessionContextResult } from './session/SessionContextResolver.js';
|
|
5
7
|
export type { CustomEndpointDefinition, CustomEndpointRequest, PermissionAwareEndpointRequest, CustomEndpointHandler, PermissionAwareEndpointHandler, HttpMethod, EndpointErrorResponse, } from './http/customEndpoints.js';
|
|
6
8
|
export { defineEndpoint, definePermissionAwareEndpoint, } from './http/customEndpoints.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAG1E,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAG5F,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,qCAAqC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAG1E,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAG5F,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,qCAAqC,EACrC,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAGhF,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,8BAA8B,EAC9B,qBAAqB,EACrB,8BAA8B,EAC9B,UAAU,EACV,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,cAAc,EACd,6BAA6B,GAC9B,MAAM,2BAA2B,CAAC"}
|