Skip to content

Commit 37e1a15

Browse files
committed
add resource Link
1 parent a2f8766 commit 37e1a15

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/mcp/types.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,27 @@ class EmbeddedResource(BaseModel):
733733
model_config = ConfigDict(extra="allow")
734734

735735

736-
Content = TextContent | ImageContent | AudioContent | EmbeddedResource
736+
class ResourceLink(Resource):
737+
"""
738+
A resource that the server is capable of reading, included in a prompt or tool call result.
739+
740+
Note: resource links returned by tools are not guaranteed to appear in the results of `resources/list` requests.
741+
"""
742+
743+
type: Literal["resource_link"]
744+
745+
746+
ContentBlock = TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource
747+
"""A content block that can be used in prompts and tool results."""
748+
749+
Content = ContentBlock
737750

738751

739752
class PromptMessage(BaseModel):
740753
"""Describes a message returned as part of a prompt."""
741754

742755
role: Role
743-
content: Content
756+
content: ContentBlock
744757
model_config = ConfigDict(extra="allow")
745758

746759

@@ -859,7 +872,7 @@ class CallToolRequest(Request[CallToolRequestParams, Literal["tools/call"]]):
859872
class CallToolResult(Result):
860873
"""The server's response to a tool call."""
861874

862-
content: list[Content]
875+
content: list[ContentBlock]
863876
isError: bool = False
864877

865878

tests/server/fastmcp/test_integration.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
ProgressNotification,
3838
PromptReference,
3939
ReadResourceResult,
40+
ResourceLink,
4041
ResourceListChangedNotification,
4142
ResourceTemplateReference,
4243
SamplingMessage,
@@ -147,6 +148,25 @@ async def tool_with_progress(message: str, ctx: Context, steps: int = 3) -> str:
147148
def echo(message: str) -> str:
148149
return f"Echo: {message}"
149150

151+
# Tool that returns ResourceLinks
152+
@mcp.tool(description="Lists files and returns resource links", title="List Files Tool")
153+
def list_files() -> list[ResourceLink]:
154+
"""Returns a list of resource links for files matching the pattern."""
155+
156+
# Mock some file resources for testing
157+
file_resources = [
158+
{
159+
"type": "resource_link",
160+
"uri": "file:///project/README.md",
161+
"name": "README.md",
162+
"mimeType": "text/markdown",
163+
}
164+
]
165+
166+
result: list[ResourceLink] = [ResourceLink.model_validate(file_json) for file_json in file_resources]
167+
168+
return result
169+
150170
# Tool with sampling capability
151171
@mcp.tool(description="A tool that uses sampling to generate content", title="Sampling Tool")
152172
async def sampling_tool(prompt: str, ctx: Context) -> str:
@@ -753,7 +773,17 @@ async def call_all_mcp_features(session: ClientSession, collector: NotificationC
753773
assert isinstance(tool_result.content[0], TextContent)
754774
assert tool_result.content[0].text == "Echo: hello"
755775

756-
# 2. Tool with context (logging and progress)
776+
# 2. Test tool that returns ResourceLinks
777+
list_files_result = await session.call_tool("list_files")
778+
assert len(list_files_result.content) == 1
779+
780+
# Rest should be ResourceLinks
781+
content = list_files_result.content[0]
782+
assert isinstance(content, ResourceLink)
783+
assert str(content.uri).startswith("file:///")
784+
assert content.name is not None
785+
assert content.mimeType is not None
786+
757787
# Test progress callback functionality
758788
progress_updates = []
759789

0 commit comments

Comments
 (0)