@@ -2,6 +2,22 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22import { z } from "zod" ;
33import { createKernelClient } from "@/lib/mcp/kernel-client" ;
44
5+ function textResponse ( text : string ) {
6+ return { content : [ { type : "text" as const , text } ] } ;
7+ }
8+
9+ function jsonResponse ( value : unknown ) {
10+ return textResponse ( JSON . stringify ( value , null , 2 ) ?? String ( value ) ) ;
11+ }
12+
13+ function errorResponse ( text : string ) {
14+ return { ...textResponse ( text ) , isError : true as const } ;
15+ }
16+
17+ function errorMessage ( error : unknown ) {
18+ return error instanceof Error ? error . message : String ( error ) ;
19+ }
20+
521export function registerAPIKeyCapabilities ( server : McpServer ) {
622 // manage_api_keys -- Create, list, get, update, and delete Kernel API keys
723 server . tool (
@@ -33,8 +49,18 @@ export function registerAPIKeyCapabilities(server: McpServer) {
3349 "(create) Days until expiry, up to 3650. Use null for no expiry." ,
3450 )
3551 . optional ( ) ,
36- limit : z . number ( ) . describe ( "(list) Max results per page." ) . optional ( ) ,
37- offset : z . number ( ) . describe ( "(list) Pagination offset." ) . optional ( ) ,
52+ limit : z
53+ . number ( )
54+ . int ( )
55+ . min ( 1 )
56+ . describe ( "(list) Max results per page." )
57+ . optional ( ) ,
58+ offset : z
59+ . number ( )
60+ . int ( )
61+ . min ( 0 )
62+ . describe ( "(list) Pagination offset." )
63+ . optional ( ) ,
3864 } ,
3965 async ( params , extra ) => {
4066 if ( ! extra . authInfo ) throw new Error ( "Authentication required" ) ;
@@ -44,11 +70,7 @@ export function registerAPIKeyCapabilities(server: McpServer) {
4470 switch ( params . action ) {
4571 case "create" : {
4672 if ( ! params . name ) {
47- return {
48- content : [
49- { type : "text" , text : "Error: name is required for create." } ,
50- ] ,
51- } ;
73+ return errorResponse ( "Error: name is required for create." ) ;
5274 }
5375 const createParams : Parameters < typeof client . apiKeys . create > [ 0 ] = {
5476 name : params . name ,
@@ -60,106 +82,51 @@ export function registerAPIKeyCapabilities(server: McpServer) {
6082 createParams . days_to_expire = params . days_to_expire ;
6183 }
6284 const apiKey = await client . apiKeys . create ( createParams ) ;
63- return {
64- content : [
65- { type : "text" , text : JSON . stringify ( apiKey , null , 2 ) } ,
66- ] ,
67- } ;
85+ return jsonResponse ( apiKey ) ;
6886 }
6987 case "list" : {
7088 const page = await client . apiKeys . list ( {
7189 ...( params . limit !== undefined && { limit : params . limit } ) ,
7290 ...( params . offset !== undefined && { offset : params . offset } ) ,
7391 } ) ;
7492 const items = page . getPaginatedItems ( ) ;
75- return {
76- content : [
77- {
78- type : "text" ,
79- text : JSON . stringify (
80- {
81- items,
82- has_more : page . has_more ,
83- next_offset : page . next_offset ,
84- } ,
85- null ,
86- 2 ,
87- ) ,
88- } ,
89- ] ,
90- } ;
93+ return jsonResponse ( {
94+ items,
95+ has_more : page . has_more ,
96+ next_offset : page . next_offset ,
97+ } ) ;
9198 }
9299 case "get" : {
93100 if ( ! params . api_key_id ) {
94- return {
95- content : [
96- {
97- type : "text" ,
98- text : "Error: api_key_id is required for get." ,
99- } ,
100- ] ,
101- } ;
101+ return errorResponse ( "Error: api_key_id is required for get." ) ;
102102 }
103103 const apiKey = await client . apiKeys . retrieve ( params . api_key_id ) ;
104- return {
105- content : [
106- { type : "text" , text : JSON . stringify ( apiKey , null , 2 ) } ,
107- ] ,
108- } ;
104+ return jsonResponse ( apiKey ) ;
109105 }
110106 case "update" : {
111107 if ( ! params . api_key_id ) {
112- return {
113- content : [
114- {
115- type : "text" ,
116- text : "Error: api_key_id is required for update." ,
117- } ,
118- ] ,
119- } ;
108+ return errorResponse ( "Error: api_key_id is required for update." ) ;
120109 }
121110 if ( ! params . name ) {
122- return {
123- content : [
124- { type : "text" , text : "Error: name is required for update." } ,
125- ] ,
126- } ;
111+ return errorResponse ( "Error: name is required for update." ) ;
127112 }
128113 const apiKey = await client . apiKeys . update ( params . api_key_id , {
129114 name : params . name ,
130115 } ) ;
131- return {
132- content : [
133- { type : "text" , text : JSON . stringify ( apiKey , null , 2 ) } ,
134- ] ,
135- } ;
116+ return jsonResponse ( apiKey ) ;
136117 }
137118 case "delete" : {
138119 if ( ! params . api_key_id ) {
139- return {
140- content : [
141- {
142- type : "text" ,
143- text : "Error: api_key_id is required for delete." ,
144- } ,
145- ] ,
146- } ;
120+ return errorResponse ( "Error: api_key_id is required for delete." ) ;
147121 }
148122 await client . apiKeys . delete ( params . api_key_id ) ;
149- return {
150- content : [ { type : "text" , text : "API key deleted successfully" } ] ,
151- } ;
123+ return textResponse ( "API key deleted successfully" ) ;
152124 }
153125 }
154126 } catch ( error ) {
155- return {
156- content : [
157- {
158- type : "text" ,
159- text : `Error in manage_api_keys (${ params . action } ): ${ error instanceof Error ? error . message : String ( error ) } ` ,
160- } ,
161- ] ,
162- } ;
127+ return errorResponse (
128+ `Error in manage_api_keys (${ params . action } ): ${ errorMessage ( error ) } ` ,
129+ ) ;
163130 }
164131 } ,
165132 ) ;
0 commit comments