Skip to content

Commit f21058d

Browse files
author
junjie.miao
committed
feat: add fetch and call MCP Resources Templates
1 parent 133f2f2 commit f21058d

File tree

1 file changed

+64
-19
lines changed

1 file changed

+64
-19
lines changed

utils/mcp_client.py

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,23 @@ def read_resource(self, uri: str) -> list[dict]:
118118
logger.info(f"{self.name} - MCP Server resources/read: {contents}")
119119
return contents
120120

121+
def list_resources_templates(self) -> list[dict]:
122+
data = {
123+
"jsonrpc": "2.0",
124+
"id": self._get_next_id(),
125+
"method": "resources/templates/list"
126+
}
127+
response = self.send_message(data)
128+
if "error" in response:
129+
error = response["error"]
130+
# Method not found
131+
if error["code"] == -32601:
132+
return []
133+
raise Exception(f"{self.name} - MCP Server resources/templates/list error: {error}")
134+
resources = response.get("result", {}).get("resourceTemplates", [])
135+
logger.info(f"{self.name} - MCP Server resources/templates/list: {resources}")
136+
return resources
137+
121138
def list_prompts(self) -> list[dict]:
122139
data = {
123140
"jsonrpc": "2.0",
@@ -389,6 +406,7 @@ def initialize(self):
389406
class ActionType(Enum):
390407
TOOL = "tool"
391408
RESOURCE = "resource"
409+
RESOURCE_TEMPLATE = "resource_template"
392410
PROMPT = "prompt"
393411

394412

@@ -456,10 +474,11 @@ def fetch_tools(self) -> list[dict]:
456474
)
457475
all_tools.append(tool)
458476

459-
# resources list
477+
# resources and resources templates list
460478
if self._resources_as_tools:
461479
resources = client.list_resources()
462-
for resource in resources:
480+
resources_templates = client.list_resources_templates()
481+
for resource in resources + resources_templates:
463482
resource_name = resource["name"]
464483
name = (re.sub(r'[^a-zA-Z0-9 _-]', '', resource_name)
465484
.replace(' ', '_').lower())
@@ -468,30 +487,52 @@ def fetch_tools(self) -> list[dict]:
468487
name = f"{server_name}__{name}"
469488
if name in self._tool_actions:
470489
name = f"resource__{uuid.uuid4().hex}"
490+
resource_description = resource.get("description", "")
491+
resource_mime_type = resource.get("mimeType", None)
492+
properties = {}
493+
required = []
494+
if "uri" in resource:
495+
uri = resource["uri"]
496+
action_type = ActionType.RESOURCE
497+
resource_size = resource.get("size", None)
498+
description = (
499+
f"Read the resource '{resource_name}' from MCP Server."
500+
f" URI: {uri}"
501+
+ (f" Description: {resource_description}" if resource_description else "")
502+
+ (f" MIME type: {resource_mime_type}" if resource_mime_type else "")
503+
+ (f" Size: {resource_size}" if resource_size else "")
504+
)
505+
elif "uriTemplate" in resource:
506+
uri_template = resource["uriTemplate"]
507+
action_type = ActionType.RESOURCE_TEMPLATE
508+
description = (
509+
f"Read the resource '{resource_name}' from MCP Server."
510+
f" URI template: {uri_template}"
511+
+ (f" Description: {resource_description}" if resource_description else "")
512+
+ (f" MIME type: {resource_mime_type}" if resource_mime_type else "")
513+
)
514+
properties = {
515+
"uri": {
516+
"type": "string",
517+
"description": f"The URI of this resource. uriTemplate: {uri_template}"
518+
}
519+
}
520+
required = ["uriTemplate"]
521+
else:
522+
raise Exception(f"Unsupported resource: {resource}")
471523
self._tool_actions[name] = ToolAction(
472524
tool_name=name,
473525
server_name=server_name,
474-
action_type=ActionType.RESOURCE,
526+
action_type=action_type,
475527
action_feature=resource,
476528
)
477-
uri = resource["uri"]
478-
resource_description = resource.get("description", "")
479-
resource_mime_type = resource.get("mimeType", None)
480-
resource_size = resource.get("size", None)
481-
description = (
482-
f"Read the resource '{resource_name}' from MCP Server."
483-
f" URI: {uri}"
484-
+ (f" Description: {resource_description}" if resource_description else "")
485-
+ (f" MIME type: {resource_mime_type}" if resource_mime_type else "")
486-
+ (f" Size: {resource_size}" if resource_size else "")
487-
)
488529
tool = {
489530
"name": name,
490531
"description": description,
491532
"inputSchema": {
492533
"type": "object",
493-
"properties": {},
494-
"required": []
534+
"properties": properties,
535+
"required": required
495536
}
496537
}
497538
all_tools.append(tool)
@@ -559,9 +600,13 @@ def execute_tool(self, tool_name: str, tool_args: dict[str, Any]) -> list[dict]:
559600
tool_contents = []
560601
if action_type == ActionType.TOOL:
561602
tool_contents = client.call_tool(tool_name, tool_args)
562-
elif action_type == ActionType.RESOURCE:
563-
resource = tool_action.action_feature
564-
contents = client.read_resource(resource["uri"])
603+
elif action_type in [ActionType.RESOURCE, ActionType.RESOURCE_TEMPLATE]:
604+
if action_type == ActionType.RESOURCE:
605+
resource = tool_action.action_feature
606+
uri = resource["uri"]
607+
else:
608+
uri = tool_args["uri"]
609+
contents = client.read_resource(uri)
565610
for content in contents:
566611
if "text" in content:
567612
tool_contents.append({

0 commit comments

Comments
 (0)