@@ -9,11 +9,15 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
99import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ;
1010import {
1111 CallToolRequestSchema ,
12- type CallToolResult ,
12+ ListResourcesRequestSchema ,
13+ ListResourceTemplatesRequestSchema ,
1314 ListToolsRequestSchema ,
15+ ReadResourceRequestSchema ,
16+ type Resource ,
17+ type ResourceTemplate ,
1418 type Tool ,
1519} from "@modelcontextprotocol/sdk/types.js" ;
16- import { Zodios , type ZodiosInstance , isErrorFromAlias } from "@zodios/core" ;
20+ import { Zodios , type ZodiosInstance } from "@zodios/core" ;
1721import { ApiDefinition } from "./types.js" ;
1822
1923const { values } = parseArgs ( {
@@ -44,6 +48,8 @@ class DrupalMcpServer {
4448 private readonly server : Server ;
4549 private readonly api : ZodiosInstance < typeof ApiDefinition > ;
4650 private _tools : Array < Tool > = [ ] ;
51+ private _resourceTemplates : Array < ResourceTemplate > = [ ] ;
52+ private _resources : Array < Resource > = [ ] ;
4753
4854 constructor ( ) {
4955 this . server = new Server (
@@ -54,60 +60,66 @@ class DrupalMcpServer {
5460 {
5561 capabilities : {
5662 tools : { } ,
63+ resources : { } ,
5764 } ,
5865 } ,
5966 ) ;
6067
6168 this . api = new Zodios ( DRUPAL_BASE_URL as string , ApiDefinition ) ;
6269 }
6370
71+ private setupResourceHandlers ( ) : void {
72+ if ( this . _resourceTemplates . length > 0 ) {
73+ console . error ( this . _resourceTemplates ) ;
74+
75+ this . server . setRequestHandler (
76+ ListResourceTemplatesRequestSchema ,
77+ async ( ) => ( {
78+ resourceTemplates : this . _resourceTemplates ,
79+ } ) ,
80+ ) ;
81+ }
82+ if ( this . _resources . length > 0 ) {
83+ this . server . setRequestHandler ( ListResourcesRequestSchema , async ( ) => ( {
84+ resources : this . _resources ,
85+ } ) ) ;
86+ }
87+
88+ this . server . setRequestHandler (
89+ ReadResourceRequestSchema ,
90+ async ( request ) => {
91+ const response = await this . api . post ( "/mcp/post" , {
92+ jsonrpc : "2.0" ,
93+ id : 2 ,
94+ method : "resources/read" ,
95+ params : {
96+ uri : request . params . uri ,
97+ } ,
98+ } ) ;
99+
100+ return response . result ;
101+ } ,
102+ ) ;
103+ }
104+
64105 private setupToolHandlers ( ) : void {
65106 this . server . setRequestHandler ( ListToolsRequestSchema , async ( ) => ( {
66107 tools : this . _tools ,
67108 } ) ) ;
68109
69110 this . server . setRequestHandler ( CallToolRequestSchema , async ( request ) => {
70- if (
71- this . _tools . length === 0 ||
72- ! this . _tools . find ( ( t ) => t . name === request . params . name )
73- ) {
74- return {
75- content : {
76- mimeType : "text/plain" ,
77- text : `Tool "${ request . params . name } " not found` ,
78- } ,
79- isError : true ,
80- } ;
81- }
82-
83- try {
84- const response = await this . api . executeTool ( request . params . arguments , {
85- params : {
86- toolId : request . params . name ,
87- } ,
88- } ) ;
111+ const response = await this . api . post ( "/mcp/post" , {
112+ jsonrpc : "2.0" ,
113+ id : 2 ,
114+ method : "tools/call" ,
115+ params : {
116+ name : request . params . name ,
117+ arguments : request . params . arguments ,
118+ } ,
119+ } ) ;
120+ console . error ( response . result ) ;
89121
90- return {
91- content : [
92- {
93- type : "text" ,
94- text : JSON . stringify ( response , null , 2 ) ,
95- } ,
96- ] ,
97- } satisfies CallToolResult ;
98- } catch ( error ) {
99- if ( isErrorFromAlias ( ApiDefinition , "executeTool" , error ) ) {
100- return {
101- content : {
102- mimeType : "text/plain" ,
103- text : `Drupal API error: ${ error . message } ` ,
104- } ,
105- isError : true ,
106- } ;
107- }
108-
109- throw error ;
110- }
122+ return response . result ;
111123 } ) ;
112124 }
113125
@@ -124,26 +136,39 @@ class DrupalMcpServer {
124136 }
125137
126138 async init ( ) {
127- try {
128- const initInfo = await this . api . getInitializationInfo ( ) ;
129- this . _tools = initInfo . tools ;
130-
131- if ( this . _tools . length > 0 ) {
132- this . setupToolHandlers ( ) ;
133- }
134-
135- this . setupErrorHandling ( ) ;
139+ const [ tools , resourceTemplates , resources ] = await Promise . all ( [
140+ this . api . post ( "/mcp/post" , {
141+ jsonrpc : "2.0" ,
142+ id : 0 ,
143+ method : "tools/list" ,
144+ } ) ,
145+ this . api . post ( "/mcp/post" , {
146+ jsonrpc : "2.0" ,
147+ id : 1 ,
148+ method : "resources/templates/list" ,
149+ } ) ,
150+ this . api . post ( "/mcp/post" , {
151+ jsonrpc : "2.0" ,
152+ id : 2 ,
153+ method : "resources/list" ,
154+ } ) ,
155+ ] ) ;
156+
157+ this . _tools = tools . result . tools ;
158+ this . _resourceTemplates = resourceTemplates . result . resourceTemplates ;
159+ this . _resources = resources . result . resources ;
160+
161+ if ( this . _tools . length > 0 ) {
162+ this . setupToolHandlers ( ) ;
163+ }
136164
137- return this ;
138- } catch ( error ) {
139- if ( isErrorFromAlias ( ApiDefinition , "getInitializationInfo" , error ) ) {
140- console . error ( `Drupal API error: ${ error . message } ` ) ;
165+ if ( this . _resourceTemplates . length > 0 || this . _resources . length > 0 ) {
166+ this . setupResourceHandlers ( ) ;
167+ }
141168
142- process . exit ( 1 ) ;
143- }
169+ this . setupErrorHandling ( ) ;
144170
145- throw error ;
146- }
171+ return this ;
147172 }
148173
149174 async run ( ) {
0 commit comments