Skip to content

Commit 2507375

Browse files
committed
Fix Local Execution of MCP Servers
1 parent 914470d commit 2507375

7 files changed

Lines changed: 166 additions & 42 deletions

File tree

mcp-server-hello-world/README.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,11 @@ uv run pytest tests/
119119
```bash
120120
./scripts/dev/start_server.sh
121121
```
122-
123-
```python
124-
from databricks_mcp import DatabricksMCPClient
125-
mcp_client = DatabricksMCPClient(
126-
server_url="http://localhost:8000"
127-
)
128-
# List available MCP tools
129-
print(mcp_client.list_tools())
122+
```bash
123+
python ./scripts/dev/query_local.py
130124
```
131125

132-
The script connects to your local MCP server without authentication and lists available tools.
126+
With the server running you can run the `query_local.py` file to test the server locally. `query_local.py` lists and returns all the available tools. Uncomment code as necessary in the script to call an individual tool.
133127

134128
#### End-to-end test your deployed MCP server
135129

mcp-server-hello-world/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dev = [
2626
"databricks-sdk",
2727
"databricks-mcp",
2828
"pytest",
29+
"pytest-asyncio",
2930
"requests"
3031
]
3132

mcp-server-hello-world/scripts/dev/README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ Scripts for testing and developing the MCP server.
1717
./scripts/dev/start_server.sh # Terminal 1
1818
```
1919

20-
```python
21-
from databricks_mcp import DatabricksMCPClient
22-
mcp_client = DatabricksMCPClient(
23-
server_url="http://localhost:8000"
24-
)
25-
# List available MCP tools
26-
print(mcp_client.list_tools())
20+
With the server running you can run the `query_local.py` file to test the server locally. `query_local.py` lists and returns all the available tools. Uncomment code as necessary in the script to call an individual tool.
21+
```bash
22+
python query_local.py # Terminal 2
2723
```
2824

2925
### Remote Testing
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
Minimal example showing how to interact with an MCP server using Python.
3+
4+
This script demonstrates:
5+
1. Listing available tools
6+
2. Calling a specific tool
7+
8+
Requirements:
9+
pip install mcp
10+
"""
11+
12+
import asyncio
13+
import json
14+
from typing import Any, List
15+
16+
from mcp.client.session import ClientSession
17+
from mcp.client.streamable_http import streamablehttp_client
18+
from mcp.types import CallToolResult, Tool
19+
20+
# ---------------------------------------------------------------------
21+
# Configuration
22+
# ---------------------------------------------------------------------
23+
24+
SERVER_URL = "http://localhost:8000/mcp" # Update to your MCP server URL
25+
26+
27+
# ---------------------------------------------------------------------
28+
# MCP helpers
29+
# ---------------------------------------------------------------------
30+
31+
32+
async def list_tools() -> List[Tool]:
33+
"""
34+
Fetch and return the list of tools exposed by the MCP server.
35+
"""
36+
async with streamablehttp_client(url=SERVER_URL) as (
37+
read_stream,
38+
write_stream,
39+
_,
40+
):
41+
async with ClientSession(read_stream, write_stream) as session:
42+
await session.initialize()
43+
return (await session.list_tools()).tools
44+
45+
46+
async def call_tool(
47+
tool_name: str,
48+
arguments: dict[str, Any] | None = None,
49+
) -> CallToolResult:
50+
"""
51+
Call a tool by name with optional arguments.
52+
"""
53+
async with streamablehttp_client(url=SERVER_URL) as (
54+
read_stream,
55+
write_stream,
56+
_,
57+
):
58+
async with ClientSession(read_stream, write_stream) as session:
59+
await session.initialize()
60+
return await session.call_tool(tool_name, arguments)
61+
62+
63+
# ---------------------------------------------------------------------
64+
# Example usage
65+
# ---------------------------------------------------------------------
66+
67+
68+
async def main():
69+
print(f"Connecting to MCP server at {SERVER_URL} ...")
70+
# List available tools
71+
tools = await list_tools()
72+
print(f"{len(tools)} tools found")
73+
SEP = "-" * 80
74+
for tool in tools:
75+
output = f"""
76+
TOOL: {tool.name}
77+
{SEP}
78+
Description:
79+
{tool.description.strip()}
80+
81+
{SEP}
82+
Input Schema:
83+
{json.dumps(tool.inputSchema, indent=2)}
84+
85+
{SEP}
86+
Output Schema:
87+
{json.dumps(tool.outputSchema, indent=2)}
88+
{SEP}
89+
{SEP}
90+
""".strip()
91+
print(output)
92+
93+
# Example: call a tool
94+
# Uncomment and update as needed
95+
#
96+
# result = await call_tool(
97+
# tool_name="health", # Replace with the desired tool name
98+
# arguments={}, # Replace with the desired arguments
99+
# )
100+
#
101+
# print("\nTool result:")
102+
# print(result)
103+
104+
105+
if __name__ == "__main__":
106+
asyncio.run(main())

mcp-server-hello-world/tests/test_integration_server.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
import pytest
1010
import requests
11-
from databricks_mcp import DatabricksMCPClient
11+
from mcp.client.session import ClientSession
12+
from mcp.client.streamable_http import streamablehttp_client
1213

1314

1415
def _find_free_port() -> int:
@@ -70,17 +71,20 @@ def run_mcp_server():
7071

7172

7273
# Test List Tools runs without errors
73-
def test_list_tools(run_mcp_server):
74-
url = run_mcp_server
75-
mcp_client = DatabricksMCPClient(server_url=f"{url}/mcp")
76-
tools = mcp_client.list_tools()
77-
78-
79-
# Test Call Tools runs without errors
80-
def test_call_tools(run_mcp_server):
81-
url = run_mcp_server
82-
mcp_client = DatabricksMCPClient(server_url=f"{url}/mcp")
83-
tools = mcp_client.list_tools()
84-
for tool in tools:
85-
result = mcp_client.call_tool(tool.name)
86-
assert result is not None
74+
@pytest.mark.asyncio
75+
async def test_list_tools(run_mcp_server):
76+
url = f"{run_mcp_server}/mcp"
77+
async with streamablehttp_client(url=url) as (
78+
read_stream,
79+
write_stream,
80+
_,
81+
):
82+
async with ClientSession(read_stream, write_stream) as session:
83+
await session.initialize()
84+
85+
response = await session.list_tools()
86+
tools = response.tools
87+
88+
assert tools is not None
89+
assert isinstance(tools, list)
90+
assert len(tools) > 0

mcp-server-open-api-spec/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ dev = [
2222
"hatchling>=1.27.0",
2323
"ruff>=0.8.0",
2424
"databricks-mcp>=0.1.0",
25-
"pytest"
25+
"pytest",
26+
"pytest-asyncio"
2627
]
2728

2829
[tool.hatch.build.targets.wheel]

mcp-server-open-api-spec/tests/test_integration_server.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
import pytest
1010
import requests
11-
from databricks_mcp import DatabricksMCPClient
11+
from mcp.client.session import ClientSession
12+
from mcp.client.streamable_http import streamablehttp_client
1213

1314

1415
def _find_free_port() -> int:
@@ -85,15 +86,36 @@ def run_mcp_server():
8586

8687

8788
# Test List Tools runs without errors
88-
def test_list_tools(run_mcp_server):
89-
url = run_mcp_server
90-
mcp_client = DatabricksMCPClient(server_url=f"{url}/mcp")
91-
tools = mcp_client.list_tools()
89+
@pytest.mark.asyncio
90+
async def test_list_tools(run_mcp_server):
91+
url = f"{run_mcp_server}/mcp"
92+
async with streamablehttp_client(url=url) as (
93+
read_stream,
94+
write_stream,
95+
_,
96+
):
97+
async with ClientSession(read_stream, write_stream) as session:
98+
await session.initialize()
99+
100+
response = await session.list_tools()
101+
tools = response.tools
102+
103+
assert tools is not None
104+
assert isinstance(tools, list)
105+
assert len(tools) > 0
92106

93107

94108
# Test Call Tools runs without errors
95-
def test_call_tools(run_mcp_server):
96-
url = run_mcp_server
97-
mcp_client = DatabricksMCPClient(server_url=f"{url}/mcp")
98-
result = mcp_client.call_tool("list_api_endpoints")
99-
assert result is not None
109+
@pytest.mark.asyncio
110+
async def test_list_tools(run_mcp_server):
111+
url = f"{run_mcp_server}/mcp"
112+
async with streamablehttp_client(url=url) as (
113+
read_stream,
114+
write_stream,
115+
_,
116+
):
117+
async with ClientSession(read_stream, write_stream) as session:
118+
await session.initialize()
119+
120+
response = await session.call_tool("list_api_endpoints")
121+
assert response is not None

0 commit comments

Comments
 (0)