Skip to content

Commit e3be835

Browse files
renovate-sh-app[bot]sd2kclaude
authored
chore(deps): update dependency mcp to v2 (#1329)
* chore(deps): update dependency mcp to v2 * test(e2e): use mcp v2 streamable_http_client mcp 2.0 removed streamablehttp_client; its replacement takes an httpx client instead of headers and yields (read, write) without the session-id callback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(e2e): use mcp v2 snake_case field names mcp 2.0 types expose snake_case attributes (is_error, input_schema, mime_type, read_only_hint, ...); camelCase stays valid only as an input alias. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com> Co-authored-by: Ben Sully <ben.sully@grafana.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent b119db2 commit e3be835

8 files changed

Lines changed: 85 additions & 35 deletions

File tree

‎tests/alerting_test.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ async def alert_rule_for_tests(mcp_client: ClientSession):
381381
"labels": {"team": "python-e2e"},
382382
},
383383
)
384-
assert not result.isError, f"Failed to create test rule: {result.content}"
384+
assert not result.is_error, f"Failed to create test rule: {result.content}"
385385

386386
yield rule_uid
387387

‎tests/conftest.py‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from dotenv import load_dotenv
77
from mcp.client.sse import sse_client
88
from mcp.client.stdio import stdio_client
9-
from mcp.client.streamable_http import streamablehttp_client
9+
from mcp.client.streamable_http import create_mcp_http_client, streamable_http_client
1010
from mcp import ClientSession, StdioServerParameters
1111

1212
load_dotenv()
@@ -119,13 +119,12 @@ async def mcp_client(mcp_transport, mcp_url, grafana_env, grafana_headers):
119119
elif mcp_transport == "streamable-http":
120120
# Use HTTP client for streamable-http transport
121121
url = f"{mcp_url}/mcp"
122-
async with streamablehttp_client(url, headers=grafana_headers) as (
123-
read,
124-
write,
125-
_,
122+
async with (
123+
create_mcp_http_client(headers=grafana_headers) as http_client,
124+
streamable_http_client(url, http_client=http_client) as (read, write),
125+
ClientSession(read, write) as session,
126126
):
127-
async with ClientSession(read, write) as session:
128-
await session.initialize()
129-
yield session
127+
await session.initialize()
128+
yield session
130129
else:
131130
raise ValueError(f"Unsupported transport: {mcp_transport}")

‎tests/disable_write_test.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ async def test_disable_write_flag_disables_write_tools(grafana_env):
5757
# Verify the read-only alerting_rules_read is present
5858
assert "alerting_rules_read" in tool_names, "alerting_rules_read should be available with --disable-write flag"
5959
alerting_tool = next(t for t in tools_result.tools if t.name == "alerting_rules_read")
60-
assert alerting_tool.annotations.readOnlyHint is True, "alerting_rules_read should be read-only with --disable-write flag"
60+
assert alerting_tool.annotations.read_only_hint is True, "alerting_rules_read should be read-only with --disable-write flag"
6161

6262
# Verify the read-only alerting_silences_read is present
6363
assert "alerting_silences_read" in tool_names, "alerting_silences_read should be available with --disable-write flag"
6464
silences_tool = next(t for t in tools_result.tools if t.name == "alerting_silences_read")
65-
assert silences_tool.annotations.readOnlyHint is True, "alerting_silences_read should be read-only with --disable-write flag"
65+
assert silences_tool.annotations.read_only_hint is True, "alerting_silences_read should be read-only with --disable-write flag"
6666

6767
# Verify read tools ARE still present
6868
read_tools = [
@@ -119,7 +119,7 @@ async def test_without_disable_write_flag_enables_write_tools(grafana_env):
119119

120120
# Verify the read-write alerting_rules_write is present (with destructive hint)
121121
alerting_tool = next(t for t in tools_result.tools if t.name == "alerting_rules_write")
122-
assert alerting_tool.annotations.destructiveHint is True, "alerting_rules_write should be marked destructive without --disable-write flag"
122+
assert alerting_tool.annotations.destructive_hint is True, "alerting_rules_write should be marked destructive without --disable-write flag"
123123

124124
# Verify read tools are also present
125125
read_tools = [

‎tests/pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dev = [
1616
"anyio>=4.9.0",
1717
"deepeval>=1.0.0",
1818
"litellm>=1.105.1,<1.106",
19-
"mcp>=1.9.3,<2",
19+
"mcp>=2.3,<3",
2020
"pytest>=9.0.3",
2121
"pytest-rerunfailures>=15.0",
2222
"python-dotenv>=1.2.2",

‎tests/rendering_test.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ async def test_get_panel_image(
3636
content_item = mcp_tc.result.content[0]
3737
assert isinstance(content_item, ImageContent)
3838
assert content_item.type == "image"
39-
assert content_item.mimeType == "image/png"
39+
assert content_item.mime_type == "image/png"
4040
assert len(content_item.data) > 0
4141

4242
assert_mcp_eval(

‎tests/tempo_test.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,21 @@ async def test_tempo_tools_have_datasourceUid_parameter(self, mcp_client):
7474

7575
for tool in tempo_tools:
7676
# Verify the tool has input schema
77-
assert hasattr(tool, "inputSchema"), (
77+
assert hasattr(tool, "input_schema"), (
7878
f"Tool {tool.name} should have inputSchema"
7979
)
80-
assert isinstance(tool.inputSchema, dict), (
80+
assert isinstance(tool.input_schema, dict), (
8181
f"Tool {tool.name} inputSchema should be a dict"
8282
)
8383

8484
# Verify datasourceUid parameter exists (camelCase)
85-
properties = tool.inputSchema.get("properties", {})
85+
properties = tool.input_schema.get("properties", {})
8686
assert "datasourceUid" in properties, (
8787
f"Tool {tool.name} should have datasourceUid parameter (camelCase)"
8888
)
8989

9090
# Verify it's required
91-
required = tool.inputSchema.get("required", [])
91+
required = tool.input_schema.get("required", [])
9292
assert "datasourceUid" in required, (
9393
f"Tool {tool.name} should require datasourceUid parameter"
9494
)
@@ -137,7 +137,7 @@ async def test_tempo_tool_call_missing_datasourceUid(self, mcp_client):
137137
arguments={}, # Missing datasourceUid
138138
)
139139
# If the server returns an error result instead of raising
140-
assert result.isError, "Should return an error when datasourceUid is missing"
140+
assert result.is_error, "Should return an error when datasourceUid is missing"
141141
error_text = result.content[0].text.lower()
142142
assert "datasourceuid" in error_text or "required" in error_text, (
143143
f"Error should mention datasourceUid: {result.content[0].text}"
@@ -158,7 +158,7 @@ async def test_tempo_tool_call_invalid_datasourceUid(self, mcp_client):
158158
arguments={"datasourceUid": "nonexistent-tempo"},
159159
)
160160
# Server may return an error result rather than raising
161-
assert result.isError, "Should return an error for invalid datasourceUid"
161+
assert result.is_error, "Should return an error for invalid datasourceUid"
162162
error_text = result.content[0].text.lower()
163163
assert "not found" in error_text or "not accessible" in error_text, (
164164
f"Should indicate datasource not found: {result.content[0].text}"

‎tests/utils.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def convert_tool(tool: Tool) -> dict:
2121
"name": tool.name,
2222
"description": tool.description,
2323
"parameters": {
24-
**tool.inputSchema,
25-
"properties": tool.inputSchema.get("properties", {}),
24+
**tool.input_schema,
25+
"properties": tool.input_schema.get("properties", {}),
2626
},
2727
},
2828
}
@@ -154,7 +154,7 @@ def assert_mcp_eval(
154154
# Give the output judge the actual tool evidence, not just the user's prompt.
155155
# Otherwise a correct answer with real logs looks fabricated to GEval.
156156
tool_results = [
157-
f"{tool.name} {'error' if tool.result.isError else 'result'}: {tool_result_text(tool.result)}"
157+
f"{tool.name} {'error' if tool.result.is_error else 'result'}: {tool_result_text(tool.result)}"
158158
for tool in tools_called
159159
]
160160
test_case = LLMTestCase(

‎tests/uv.lock‎

Lines changed: 63 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)