toolception 0.4.0 → 0.5.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/README.md +132 -1
- package/dist/http/FastifyTransport.d.ts +6 -0
- package/dist/http/FastifyTransport.d.ts.map +1 -1
- package/dist/http/customEndpoints.d.ts +247 -0
- package/dist/http/customEndpoints.d.ts.map +1 -0
- package/dist/http/endpointRegistration.d.ts +35 -0
- package/dist/http/endpointRegistration.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +236 -121
- package/dist/index.js.map +1 -1
- package/dist/permissions/PermissionAwareFastifyTransport.d.ts +7 -0
- package/dist/permissions/PermissionAwareFastifyTransport.d.ts.map +1 -1
- package/dist/server/createMcpServer.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- [Static startup](#static-startup)
|
|
11
11
|
- [Permission-based starter guide](#permission-based-starter-guide)
|
|
12
12
|
- [Permission configuration approaches](#permission-configuration-approaches)
|
|
13
|
+
- [Custom HTTP endpoints](#custom-http-endpoints)
|
|
13
14
|
- [API](#api)
|
|
14
15
|
- [createMcpServer](#createmcpserveroptions)
|
|
15
16
|
- [createPermissionBasedMcpServer](#createpermissionbasedmcpserveroptions)
|
|
@@ -589,6 +590,135 @@ await start();
|
|
|
589
590
|
|
|
590
591
|
**Note:** Resolver functions must be synchronous. If you need to fetch permissions from external sources, do so before server creation and cache the results.
|
|
591
592
|
|
|
593
|
+
## Custom HTTP endpoints
|
|
594
|
+
|
|
595
|
+
Toolception supports custom HTTP endpoints alongside MCP protocol endpoints, enabling REST-like APIs with Zod validation and type inference.
|
|
596
|
+
|
|
597
|
+
### Basic usage
|
|
598
|
+
|
|
599
|
+
```ts
|
|
600
|
+
import { createMcpServer, defineEndpoint } from "toolception";
|
|
601
|
+
import { z } from "zod";
|
|
602
|
+
|
|
603
|
+
const { start } = await createMcpServer({
|
|
604
|
+
// ... standard options
|
|
605
|
+
http: {
|
|
606
|
+
port: 3000,
|
|
607
|
+
customEndpoints: [
|
|
608
|
+
defineEndpoint({
|
|
609
|
+
method: "GET",
|
|
610
|
+
path: "/api/users",
|
|
611
|
+
querySchema: z.object({
|
|
612
|
+
limit: z.coerce.number().int().positive().default(10),
|
|
613
|
+
role: z.enum(["admin", "user"]).optional(),
|
|
614
|
+
}),
|
|
615
|
+
responseSchema: z.object({
|
|
616
|
+
users: z.array(z.object({ id: z.string(), name: z.string() })),
|
|
617
|
+
}),
|
|
618
|
+
handler: async (req) => {
|
|
619
|
+
// req.query is typed: { limit: number, role?: "admin" | "user" }
|
|
620
|
+
// req.clientId is available from mcp-client-id header
|
|
621
|
+
return { users: [{ id: "1", name: "Alice" }] };
|
|
622
|
+
},
|
|
623
|
+
}),
|
|
624
|
+
],
|
|
625
|
+
},
|
|
626
|
+
});
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### Validation schemas
|
|
630
|
+
|
|
631
|
+
- **querySchema**: Validates URL query parameters (use `z.coerce` for type conversion)
|
|
632
|
+
- **bodySchema**: Validates request body (POST/PUT/PATCH)
|
|
633
|
+
- **paramsSchema**: Validates path parameters (e.g., `/users/:userId`)
|
|
634
|
+
- **responseSchema**: Validates handler response (prevents invalid data leakage)
|
|
635
|
+
|
|
636
|
+
### Request context
|
|
637
|
+
|
|
638
|
+
Handlers receive a typed request object:
|
|
639
|
+
|
|
640
|
+
```ts
|
|
641
|
+
{
|
|
642
|
+
body: TBody, // Validated from bodySchema
|
|
643
|
+
query: TQuery, // Validated from querySchema
|
|
644
|
+
params: TParams, // Validated from paramsSchema
|
|
645
|
+
headers: Record<string, string | string[] | undefined>,
|
|
646
|
+
clientId: string, // From mcp-client-id header or auto-generated
|
|
647
|
+
}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Permission-aware endpoints
|
|
651
|
+
|
|
652
|
+
Use `definePermissionAwareEndpoint` in permission-based servers to access client permissions:
|
|
653
|
+
|
|
654
|
+
```ts
|
|
655
|
+
import { createPermissionBasedMcpServer, definePermissionAwareEndpoint } from "toolception";
|
|
656
|
+
|
|
657
|
+
const { start } = await createPermissionBasedMcpServer({
|
|
658
|
+
// ... permission config
|
|
659
|
+
http: {
|
|
660
|
+
customEndpoints: [
|
|
661
|
+
definePermissionAwareEndpoint({
|
|
662
|
+
method: "GET",
|
|
663
|
+
path: "/api/me",
|
|
664
|
+
responseSchema: z.object({
|
|
665
|
+
clientId: z.string(),
|
|
666
|
+
allowedToolsets: z.array(z.string()),
|
|
667
|
+
isAdmin: z.boolean(),
|
|
668
|
+
}),
|
|
669
|
+
handler: async (req) => {
|
|
670
|
+
// req.allowedToolsets and req.failedToolsets are available
|
|
671
|
+
return {
|
|
672
|
+
clientId: req.clientId,
|
|
673
|
+
allowedToolsets: req.allowedToolsets,
|
|
674
|
+
isAdmin: req.allowedToolsets.includes("admin-tools"),
|
|
675
|
+
};
|
|
676
|
+
},
|
|
677
|
+
}),
|
|
678
|
+
],
|
|
679
|
+
},
|
|
680
|
+
});
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Error handling
|
|
684
|
+
|
|
685
|
+
Validation failures return standardized error responses:
|
|
686
|
+
|
|
687
|
+
- **400 VALIDATION_ERROR**: Request validation failed (body, query, or params)
|
|
688
|
+
- **500 INTERNAL_ERROR**: Handler threw an exception
|
|
689
|
+
- **500 RESPONSE_VALIDATION_ERROR**: Response validation failed
|
|
690
|
+
|
|
691
|
+
Example error response:
|
|
692
|
+
|
|
693
|
+
```json
|
|
694
|
+
{
|
|
695
|
+
"error": {
|
|
696
|
+
"code": "VALIDATION_ERROR",
|
|
697
|
+
"message": "Validation failed for query",
|
|
698
|
+
"details": [
|
|
699
|
+
{
|
|
700
|
+
"code": "invalid_type",
|
|
701
|
+
"path": ["limit"],
|
|
702
|
+
"message": "Expected number, received string"
|
|
703
|
+
}
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Reserved paths
|
|
710
|
+
|
|
711
|
+
Custom endpoints cannot override built-in MCP paths:
|
|
712
|
+
|
|
713
|
+
- `/mcp` - MCP JSON-RPC endpoint
|
|
714
|
+
- `/healthz` - Health check
|
|
715
|
+
- `/tools` - Tool listing
|
|
716
|
+
- `/.well-known/mcp-config` - Configuration schema
|
|
717
|
+
|
|
718
|
+
### Complete example
|
|
719
|
+
|
|
720
|
+
See `examples/custom-endpoints-demo.ts` for a full working example with GET, POST, PUT, DELETE endpoints, pagination, and permission-aware handlers.
|
|
721
|
+
|
|
592
722
|
## API
|
|
593
723
|
|
|
594
724
|
### createMcpServer(options)
|
|
@@ -736,9 +866,10 @@ const moduleLoaders = {
|
|
|
736
866
|
|
|
737
867
|
#### options.http (optional)
|
|
738
868
|
|
|
739
|
-
`{ host?: string; port?: number; basePath?: string; cors?: boolean; logger?: boolean }`
|
|
869
|
+
`{ host?: string; port?: number; basePath?: string; cors?: boolean; logger?: boolean; customEndpoints?: CustomEndpointDefinition[] }`
|
|
740
870
|
|
|
741
871
|
- Fastify transport configuration. Defaults: host `0.0.0.0`, port `3000`, basePath `/`, CORS enabled, logger disabled.
|
|
872
|
+
- `customEndpoints`: Optional array of custom HTTP endpoints to register alongside MCP protocol endpoints. See [Custom HTTP endpoints](#custom-http-endpoints) for details.
|
|
742
873
|
|
|
743
874
|
#### options.createServer (optional)
|
|
744
875
|
|
|
@@ -2,6 +2,7 @@ import { FastifyInstance } from 'fastify';
|
|
|
2
2
|
import { DynamicToolManager } from '../core/DynamicToolManager.js';
|
|
3
3
|
import { ServerOrchestrator } from '../core/ServerOrchestrator.js';
|
|
4
4
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { CustomEndpointDefinition } from './customEndpoints.js';
|
|
5
6
|
export interface FastifyTransportOptions {
|
|
6
7
|
host?: string;
|
|
7
8
|
port?: number;
|
|
@@ -9,6 +10,11 @@ export interface FastifyTransportOptions {
|
|
|
9
10
|
cors?: boolean;
|
|
10
11
|
logger?: boolean;
|
|
11
12
|
app?: FastifyInstance;
|
|
13
|
+
/**
|
|
14
|
+
* Optional custom HTTP endpoints to register alongside MCP protocol endpoints.
|
|
15
|
+
* Allows adding REST-like endpoints with Zod validation and type inference.
|
|
16
|
+
*/
|
|
17
|
+
customEndpoints?: CustomEndpointDefinition[];
|
|
12
18
|
}
|
|
13
19
|
export declare class FastifyTransport {
|
|
14
20
|
private readonly options;
|
|
@@ -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;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,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;AAIxE,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,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAQtB;IACF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAG3B;IACF,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,MAAM;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,YAAY,EAAE,kBAAkB,CAAA;KAAE,EAC3E,OAAO,GAAE,uBAA4B,EACrC,YAAY,CAAC,EAAE,MAAM;IAgBV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoMnC;;;OAGG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYlC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;CAkBtB"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Supported HTTP methods for custom endpoints
|
|
4
|
+
*/
|
|
5
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
6
|
+
/**
|
|
7
|
+
* Request context passed to custom endpoint handlers.
|
|
8
|
+
* Contains validated and typed request data without exposing Fastify types.
|
|
9
|
+
*/
|
|
10
|
+
export interface CustomEndpointRequest<TBody = unknown, TQuery = unknown, TParams = unknown> {
|
|
11
|
+
/**
|
|
12
|
+
* Validated request body (typed from bodySchema)
|
|
13
|
+
*/
|
|
14
|
+
body: TBody;
|
|
15
|
+
/**
|
|
16
|
+
* Validated query parameters (typed from querySchema)
|
|
17
|
+
*/
|
|
18
|
+
query: TQuery;
|
|
19
|
+
/**
|
|
20
|
+
* Validated path parameters (typed from paramsSchema)
|
|
21
|
+
*/
|
|
22
|
+
params: TParams;
|
|
23
|
+
/**
|
|
24
|
+
* Raw request headers
|
|
25
|
+
*/
|
|
26
|
+
headers: Record<string, string | string[] | undefined>;
|
|
27
|
+
/**
|
|
28
|
+
* Client ID (from mcp-client-id header or auto-generated for anonymous clients)
|
|
29
|
+
*/
|
|
30
|
+
clientId: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Permission-aware request context for custom endpoints in permission-based servers.
|
|
34
|
+
* Extends CustomEndpointRequest with permission information.
|
|
35
|
+
*/
|
|
36
|
+
export interface PermissionAwareEndpointRequest<TBody = unknown, TQuery = unknown, TParams = unknown> extends CustomEndpointRequest<TBody, TQuery, TParams> {
|
|
37
|
+
/**
|
|
38
|
+
* Toolsets this client is allowed to access (resolved from permissions)
|
|
39
|
+
*/
|
|
40
|
+
allowedToolsets: string[];
|
|
41
|
+
/**
|
|
42
|
+
* Toolsets that failed to enable for this client
|
|
43
|
+
*/
|
|
44
|
+
failedToolsets: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Handler function type with automatic type inference from Zod schemas.
|
|
48
|
+
* Receives validated and typed request data, returns typed response.
|
|
49
|
+
*/
|
|
50
|
+
export type CustomEndpointHandler<TBody extends z.ZodTypeAny, TQuery extends z.ZodTypeAny, TParams extends z.ZodTypeAny, TResponse extends z.ZodTypeAny> = (request: CustomEndpointRequest<TBody extends z.ZodTypeAny ? z.infer<TBody> : never, TQuery extends z.ZodTypeAny ? z.infer<TQuery> : never, TParams extends z.ZodTypeAny ? z.infer<TParams> : never>) => Promise<z.infer<TResponse>> | z.infer<TResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Permission-aware handler function type for permission-based servers.
|
|
53
|
+
* Receives permission context in addition to validated request data.
|
|
54
|
+
*/
|
|
55
|
+
export type PermissionAwareEndpointHandler<TBody extends z.ZodTypeAny, TQuery extends z.ZodTypeAny, TParams extends z.ZodTypeAny, TResponse extends z.ZodTypeAny> = (request: PermissionAwareEndpointRequest<TBody extends z.ZodTypeAny ? z.infer<TBody> : never, TQuery extends z.ZodTypeAny ? z.infer<TQuery> : never, TParams extends z.ZodTypeAny ? z.infer<TParams> : never>) => Promise<z.infer<TResponse>> | z.infer<TResponse>;
|
|
56
|
+
/**
|
|
57
|
+
* Custom HTTP endpoint definition with Zod schema-based validation and type inference.
|
|
58
|
+
* Allows defining REST-like endpoints alongside MCP protocol endpoints.
|
|
59
|
+
*
|
|
60
|
+
* @template TBody - Zod schema for request body validation
|
|
61
|
+
* @template TQuery - Zod schema for query parameter validation
|
|
62
|
+
* @template TParams - Zod schema for path parameter validation
|
|
63
|
+
* @template TResponse - Zod schema for response validation
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const getUserEndpoint = defineEndpoint({
|
|
68
|
+
* method: "GET",
|
|
69
|
+
* path: "/users/:userId",
|
|
70
|
+
* paramsSchema: z.object({
|
|
71
|
+
* userId: z.string().uuid(),
|
|
72
|
+
* }),
|
|
73
|
+
* responseSchema: z.object({
|
|
74
|
+
* id: z.string(),
|
|
75
|
+
* name: z.string(),
|
|
76
|
+
* }),
|
|
77
|
+
* handler: async (req) => {
|
|
78
|
+
* // req.params is typed: { userId: string }
|
|
79
|
+
* const { userId } = req.params;
|
|
80
|
+
* return { id: userId, name: "Alice" };
|
|
81
|
+
* },
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export interface CustomEndpointDefinition<TBody extends z.ZodTypeAny = z.ZodTypeAny, TQuery extends z.ZodTypeAny = z.ZodTypeAny, TParams extends z.ZodTypeAny = z.ZodTypeAny, TResponse extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
86
|
+
/**
|
|
87
|
+
* HTTP method for this endpoint
|
|
88
|
+
*/
|
|
89
|
+
method: HttpMethod;
|
|
90
|
+
/**
|
|
91
|
+
* URL path (relative to basePath). Supports path parameters using :param syntax.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* - "/users" - Simple path
|
|
95
|
+
* - "/users/:id" - Path with single parameter
|
|
96
|
+
* - "/items/:category/:id" - Path with multiple parameters
|
|
97
|
+
*/
|
|
98
|
+
path: string;
|
|
99
|
+
/**
|
|
100
|
+
* Optional Zod schema for request body validation (typically used with POST, PUT, PATCH).
|
|
101
|
+
* Enables automatic type inference for handler body parameter.
|
|
102
|
+
*/
|
|
103
|
+
bodySchema?: TBody;
|
|
104
|
+
/**
|
|
105
|
+
* Optional Zod schema for query parameter validation.
|
|
106
|
+
* Enables automatic type inference for handler query parameter.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* querySchema: z.object({
|
|
111
|
+
* limit: z.coerce.number().int().positive().default(10),
|
|
112
|
+
* offset: z.coerce.number().int().nonnegative().default(0),
|
|
113
|
+
* })
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
querySchema?: TQuery;
|
|
117
|
+
/**
|
|
118
|
+
* Optional Zod schema for path parameter validation.
|
|
119
|
+
* Enables automatic type inference for handler params parameter.
|
|
120
|
+
*/
|
|
121
|
+
paramsSchema?: TParams;
|
|
122
|
+
/**
|
|
123
|
+
* Optional Zod schema for response validation.
|
|
124
|
+
* Enables automatic type inference for handler return type.
|
|
125
|
+
* If validation fails, returns 500 error to prevent information leakage.
|
|
126
|
+
*/
|
|
127
|
+
responseSchema?: TResponse;
|
|
128
|
+
/**
|
|
129
|
+
* Request handler function with inferred types from schemas.
|
|
130
|
+
* Receives validated and typed request data, returns typed response.
|
|
131
|
+
*/
|
|
132
|
+
handler: CustomEndpointHandler<TBody, TQuery, TParams, TResponse>;
|
|
133
|
+
/**
|
|
134
|
+
* Optional description for documentation purposes
|
|
135
|
+
*/
|
|
136
|
+
description?: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Standard error response structure for custom endpoints
|
|
140
|
+
*/
|
|
141
|
+
export interface EndpointErrorResponse {
|
|
142
|
+
error: {
|
|
143
|
+
/**
|
|
144
|
+
* Error code indicating the type of error
|
|
145
|
+
* - VALIDATION_ERROR: Request validation failed (400)
|
|
146
|
+
* - INTERNAL_ERROR: Handler threw an error (500)
|
|
147
|
+
* - RESPONSE_VALIDATION_ERROR: Response validation failed (500)
|
|
148
|
+
*/
|
|
149
|
+
code: "VALIDATION_ERROR" | "INTERNAL_ERROR" | "RESPONSE_VALIDATION_ERROR";
|
|
150
|
+
/**
|
|
151
|
+
* Human-readable error message
|
|
152
|
+
*/
|
|
153
|
+
message: string;
|
|
154
|
+
/**
|
|
155
|
+
* Optional additional error details (e.g., Zod validation errors)
|
|
156
|
+
*/
|
|
157
|
+
details?: unknown;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Helper function to create type-safe custom endpoints with automatic type inference.
|
|
162
|
+
* Provides better IntelliSense and type checking for endpoint definitions.
|
|
163
|
+
*
|
|
164
|
+
* @template TBody - Zod schema for request body
|
|
165
|
+
* @template TQuery - Zod schema for query parameters
|
|
166
|
+
* @template TParams - Zod schema for path parameters
|
|
167
|
+
* @template TResponse - Zod schema for response
|
|
168
|
+
*
|
|
169
|
+
* @param definition - Endpoint definition with schemas and handler
|
|
170
|
+
* @returns The same endpoint definition with full type inference
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* import { z } from "zod";
|
|
175
|
+
* import { defineEndpoint } from "toolception";
|
|
176
|
+
*
|
|
177
|
+
* const getUsersEndpoint = defineEndpoint({
|
|
178
|
+
* method: "GET",
|
|
179
|
+
* path: "/users",
|
|
180
|
+
* querySchema: z.object({
|
|
181
|
+
* limit: z.coerce.number().int().positive().default(10),
|
|
182
|
+
* role: z.enum(["admin", "user"]).optional(),
|
|
183
|
+
* }),
|
|
184
|
+
* responseSchema: z.object({
|
|
185
|
+
* users: z.array(z.object({
|
|
186
|
+
* id: z.string(),
|
|
187
|
+
* name: z.string(),
|
|
188
|
+
* })),
|
|
189
|
+
* total: z.number(),
|
|
190
|
+
* }),
|
|
191
|
+
* handler: async (req) => {
|
|
192
|
+
* // req.query is fully typed: { limit: number, role?: "admin" | "user" }
|
|
193
|
+
* const { limit, role } = req.query;
|
|
194
|
+
*
|
|
195
|
+
* return {
|
|
196
|
+
* users: [{ id: "1", name: "Alice" }],
|
|
197
|
+
* total: 1,
|
|
198
|
+
* };
|
|
199
|
+
* },
|
|
200
|
+
* });
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export declare function defineEndpoint<TBody extends z.ZodTypeAny = z.ZodNever, TQuery extends z.ZodTypeAny = z.ZodNever, TParams extends z.ZodTypeAny = z.ZodNever, TResponse extends z.ZodTypeAny = z.ZodAny>(definition: CustomEndpointDefinition<TBody, TQuery, TParams, TResponse>): CustomEndpointDefinition<TBody, TQuery, TParams, TResponse>;
|
|
204
|
+
/**
|
|
205
|
+
* Helper function to create permission-aware custom endpoints for permission-based servers.
|
|
206
|
+
* Similar to defineEndpoint but with access to permission context in the handler.
|
|
207
|
+
*
|
|
208
|
+
* @template TBody - Zod schema for request body
|
|
209
|
+
* @template TQuery - Zod schema for query parameters
|
|
210
|
+
* @template TParams - Zod schema for path parameters
|
|
211
|
+
* @template TResponse - Zod schema for response
|
|
212
|
+
*
|
|
213
|
+
* @param definition - Endpoint definition with permission-aware handler
|
|
214
|
+
* @returns Endpoint definition compatible with permission-based servers
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* import { definePermissionAwareEndpoint } from "toolception";
|
|
219
|
+
*
|
|
220
|
+
* const statsEndpoint = definePermissionAwareEndpoint({
|
|
221
|
+
* method: "GET",
|
|
222
|
+
* path: "/my-permissions",
|
|
223
|
+
* responseSchema: z.object({
|
|
224
|
+
* toolsets: z.array(z.string()),
|
|
225
|
+
* count: z.number(),
|
|
226
|
+
* }),
|
|
227
|
+
* handler: async (req) => {
|
|
228
|
+
* // req.allowedToolsets and req.failedToolsets are available
|
|
229
|
+
* return {
|
|
230
|
+
* toolsets: req.allowedToolsets,
|
|
231
|
+
* count: req.allowedToolsets.length,
|
|
232
|
+
* };
|
|
233
|
+
* },
|
|
234
|
+
* });
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
export declare function definePermissionAwareEndpoint<TBody extends z.ZodTypeAny = z.ZodNever, TQuery extends z.ZodTypeAny = z.ZodNever, TParams extends z.ZodTypeAny = z.ZodNever, TResponse extends z.ZodTypeAny = z.ZodAny>(definition: {
|
|
238
|
+
method: HttpMethod;
|
|
239
|
+
path: string;
|
|
240
|
+
bodySchema?: TBody;
|
|
241
|
+
querySchema?: TQuery;
|
|
242
|
+
paramsSchema?: TParams;
|
|
243
|
+
responseSchema?: TResponse;
|
|
244
|
+
handler: PermissionAwareEndpointHandler<TBody, TQuery, TParams, TResponse>;
|
|
245
|
+
description?: string;
|
|
246
|
+
}): CustomEndpointDefinition<TBody, TQuery, TParams, TResponse>;
|
|
247
|
+
//# sourceMappingURL=customEndpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customEndpoints.d.ts","sourceRoot":"","sources":["../../src/http/customEndpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FastifyInstance, FastifyRequest } from 'fastify';
|
|
2
|
+
import { CustomEndpointDefinition } from './customEndpoints.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for registering custom endpoints
|
|
5
|
+
*/
|
|
6
|
+
export interface RegisterCustomEndpointsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Optional function to extract additional context for each request.
|
|
9
|
+
* Used by permission-aware transport to inject permission data.
|
|
10
|
+
*/
|
|
11
|
+
contextExtractor?: (req: FastifyRequest) => Promise<Record<string, any>> | Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Registers custom endpoints on a Fastify instance.
|
|
15
|
+
* Handles Zod validation, error responses, and type-safe request mapping.
|
|
16
|
+
*
|
|
17
|
+
* @param app - Fastify instance to register endpoints on
|
|
18
|
+
* @param basePath - Base path for all endpoints (e.g., "/" or "/api")
|
|
19
|
+
* @param endpoints - Array of custom endpoint definitions
|
|
20
|
+
* @param options - Optional configuration for endpoint registration
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* registerCustomEndpoints(app, "/api", [
|
|
25
|
+
* defineEndpoint({
|
|
26
|
+
* method: "GET",
|
|
27
|
+
* path: "/users",
|
|
28
|
+
* querySchema: z.object({ limit: z.coerce.number() }),
|
|
29
|
+
* handler: async (req) => ({ users: [] }),
|
|
30
|
+
* }),
|
|
31
|
+
* ]);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function registerCustomEndpoints(app: FastifyInstance, basePath: string, endpoints: CustomEndpointDefinition[], options?: RegisterCustomEndpointsOptions): void;
|
|
35
|
+
//# sourceMappingURL=endpointRegistration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpointRegistration.d.ts","sourceRoot":"","sources":["../../src/http/endpointRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAgB,MAAM,SAAS,CAAC;AAG7E,OAAO,KAAK,EACV,wBAAwB,EAGzB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CACjB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,wBAAwB,EAAE,EACrC,OAAO,CAAC,EAAE,8BAA8B,GACvC,IAAI,CAgIN"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export { createMcpServer } from './server/createMcpServer.js';
|
|
|
2
2
|
export type { CreateMcpServerOptions } from './server/createMcpServer.js';
|
|
3
3
|
export { createPermissionBasedMcpServer } from './server/createPermissionBasedMcpServer.js';
|
|
4
4
|
export type { ToolSetCatalog, ToolSetDefinition, McpToolDefinition, ExposurePolicy, Mode, ModuleLoader, PermissionConfig, CreatePermissionBasedMcpServerOptions, } from './types/index.js';
|
|
5
|
+
export type { CustomEndpointDefinition, CustomEndpointRequest, PermissionAwareEndpointRequest, CustomEndpointHandler, PermissionAwareEndpointHandler, HttpMethod, EndpointErrorResponse, } from './http/customEndpoints.js';
|
|
6
|
+
export { defineEndpoint, definePermissionAwareEndpoint, } from './http/customEndpoints.js';
|
|
5
7
|
//# 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,GACtC,MAAM,kBAAkB,CAAC"}
|
|
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,GACtC,MAAM,kBAAkB,CAAC;AAG1B,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"}
|