7
7
from typing import Dict , Any , Optional , List
8
8
9
9
from mcp .server .fastmcp import FastMCP , Image , Context
10
+ from mcp .types import (
11
+ Tool , Resource , ResourceTemplate ,
12
+ ServerResult , ListToolsResult , ListResourcesResult , ListResourceTemplatesResult
13
+ )
10
14
11
15
from .engine import MatlabEngine
12
16
from .utils .section_parser import get_section_info
@@ -40,6 +44,9 @@ class MatlabServer:
40
44
41
45
def __init__ (self ):
42
46
"""Initialize the MATLAB MCP server."""
47
+ # Configure logging level to reduce debug noise
48
+ logging .getLogger ('mcp' ).setLevel (logging .INFO )
49
+
43
50
self .mcp = FastMCP (
44
51
"MATLAB" ,
45
52
dependencies = [
@@ -57,6 +64,11 @@ def __init__(self):
57
64
}
58
65
}
59
66
)
67
+
68
+ # Set up core MCP protocol handlers
69
+ self .mcp ._mcp_server .list_tools ()(self ._list_tools )
70
+ self .mcp ._mcp_server .list_resources ()(self ._list_resources )
71
+ self .mcp ._mcp_server .list_resource_templates ()(self ._list_resource_templates )
60
72
self .engine = MatlabEngine ()
61
73
# Use .mcp directory in home for all files
62
74
self .mcp_dir = Path .home () / ".mcp"
@@ -67,6 +79,89 @@ def __init__(self):
67
79
self ._setup_tools ()
68
80
self ._setup_resources ()
69
81
82
+ async def _list_tools (self ) -> ServerResult :
83
+ """Handle ListToolsRequest."""
84
+ tools = [
85
+ Tool (
86
+ name = "execute_script" ,
87
+ description = "Execute MATLAB code or script file" ,
88
+ inputSchema = {
89
+ "type" : "object" ,
90
+ "properties" : {
91
+ "script" : {"type" : "string" },
92
+ "is_file" : {"type" : "boolean" },
93
+ "workspace_vars" : {"type" : "object" }
94
+ },
95
+ "required" : ["script" ]
96
+ }
97
+ ),
98
+ Tool (
99
+ name = "execute_script_section" ,
100
+ description = "Execute specific sections of a MATLAB script" ,
101
+ inputSchema = {
102
+ "type" : "object" ,
103
+ "properties" : {
104
+ "script_name" : {"type" : "string" },
105
+ "section_range" : {
106
+ "type" : "array" ,
107
+ "items" : {"type" : "integer" },
108
+ "minItems" : 2 ,
109
+ "maxItems" : 2
110
+ },
111
+ "maintain_workspace" : {"type" : "boolean" }
112
+ },
113
+ "required" : ["script_name" , "section_range" ]
114
+ }
115
+ ),
116
+ Tool (
117
+ name = "get_script_sections" ,
118
+ description = "Get information about sections in a MATLAB script" ,
119
+ inputSchema = {
120
+ "type" : "object" ,
121
+ "properties" : {
122
+ "script_name" : {"type" : "string" }
123
+ },
124
+ "required" : ["script_name" ]
125
+ }
126
+ ),
127
+ Tool (
128
+ name = "create_matlab_script" ,
129
+ description = "Create a new MATLAB script" ,
130
+ inputSchema = {
131
+ "type" : "object" ,
132
+ "properties" : {
133
+ "script_name" : {"type" : "string" },
134
+ "code" : {"type" : "string" }
135
+ },
136
+ "required" : ["script_name" , "code" ]
137
+ }
138
+ ),
139
+ Tool (
140
+ name = "get_workspace" ,
141
+ description = "Get current MATLAB workspace variables" ,
142
+ inputSchema = {
143
+ "type" : "object" ,
144
+ "properties" : {}
145
+ }
146
+ )
147
+ ]
148
+ return ServerResult (ListToolsResult (tools = tools ))
149
+
150
+ async def _list_resources (self ) -> ServerResult :
151
+ """Handle ListResourcesRequest."""
152
+ return ServerResult (ListResourcesResult (resources = [])) # We don't have static resources
153
+
154
+ async def _list_resource_templates (self ) -> ServerResult :
155
+ """Handle ListResourceTemplatesRequest."""
156
+ templates = [
157
+ ResourceTemplate (
158
+ uriTemplate = "matlab://scripts/{script_name}" ,
159
+ name = "MATLAB Script" ,
160
+ description = "Get the content of a MATLAB script"
161
+ )
162
+ ]
163
+ return ServerResult (ListResourceTemplatesResult (resourceTemplates = templates ))
164
+
70
165
def _setup_tools (self ):
71
166
"""Set up MCP tools for MATLAB operations."""
72
167
@@ -259,18 +354,24 @@ def signal_handler(signum, frame):
259
354
signal .signal (signal .SIGINT , signal_handler )
260
355
signal .signal (signal .SIGTERM , signal_handler )
261
356
357
+ # Print available tools
358
+ tools = [
359
+ "execute_script: Execute MATLAB code or script file" ,
360
+ "execute_script_section: Execute specific sections of a MATLAB script" ,
361
+ "get_script_sections: Get information about script sections" ,
362
+ "create_matlab_script: Create a new MATLAB script" ,
363
+ "get_workspace: Get current MATLAB workspace variables"
364
+ ]
365
+
262
366
print ("MATLAB MCP Server is running..." )
263
367
print ("Available tools:" )
264
- print (" - execute_script: Execute MATLAB code or script file" )
265
- print (" - execute_script_section: Execute specific sections of a MATLAB script" )
266
- print (" - get_script_sections: Get information about script sections" )
267
- print (" - create_matlab_script: Create a new MATLAB script" )
268
- print (" - get_workspace: Get current MATLAB workspace variables" )
368
+ for tool in tools :
369
+ print (f" - { tool } " )
269
370
print ("\n Use the tools with Cline or other MCP-compatible clients." )
270
371
print ("Press Ctrl+C to shutdown gracefully" )
271
372
272
373
try :
273
- # Let FastMCP handle its own event loop
374
+ # Let FastMCP handle protocol messages and event loop
274
375
self .mcp .run (transport = 'stdio' )
275
376
except KeyboardInterrupt :
276
377
print ("\n Received keyboard interrupt..." )
0 commit comments