Skip to content

Commit 3c0b108

Browse files
authored
Merge pull request #9 from jolovicdev/feat/streamable-http-small
Feat/streamable http small
2 parents 27f9ece + c293016 commit 3c0b108

File tree

4 files changed

+58
-7
lines changed

4 files changed

+58
-7
lines changed

docs/tools.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,11 @@ belt = Toolbelt()
133133

134134
## MCP Tool Integration
135135

136-
Connect to MCP (Model Context Protocol) servers and use their tools.
137-
Use `connect_sse` when pointing at an SSE endpoint.
136+
Connect to MCP (Model Context Protocol) servers and use their tools. MCP tools are automatically converted to the blackgeorge `Tool` format and can be passed to workers.
137+
138+
### stdio transport
139+
140+
For local MCP servers that run as subprocesses.
138141

139142
```python
140143
from blackgeorge.tools import MCPToolProvider
@@ -145,7 +148,42 @@ async with MCPToolProvider() as provider:
145148
result = await provider.acall_tool("fetch", {"url": "https://example.com"})
146149
```
147150

148-
MCP tools are automatically converted to the blackgeorge `Tool` format and can be passed to workers.
151+
### Streamable HTTP transport
152+
153+
For remote MCP servers over HTTP.
154+
155+
```python
156+
from blackgeorge.tools import MCPToolProvider
157+
158+
async with MCPToolProvider() as provider:
159+
await provider.connect_streamable_http("https://api.example.com/mcp")
160+
tools = provider.list_tools()
161+
result = await provider.acall_tool("search", {"query": "python"})
162+
```
163+
164+
For servers requiring authentication, pass a custom `httpx.AsyncClient`:
165+
166+
```python
167+
import httpx
168+
from blackgeorge.tools import MCPToolProvider
169+
170+
async with MCPToolProvider() as provider:
171+
client = httpx.AsyncClient(headers={"Authorization": "Bearer token"})
172+
await provider.connect_streamable_http("https://api.example.com/mcp", http_client=client)
173+
tools = provider.list_tools()
174+
```
175+
176+
### SSE transport
177+
178+
For MCP servers that use Server-Sent Events.
179+
180+
```python
181+
from blackgeorge.tools import MCPToolProvider
182+
183+
async with MCPToolProvider() as provider:
184+
await provider.connect_sse("https://api.example.com/mcp/sse")
185+
tools = provider.list_tools()
186+
```
149187

150188
## Execution path
151189

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "blackgeorge"
3-
version = "1.1.1"
3+
version = "1.1.2"
44
description = "Agentic framework with desk/worker/workforce primitives"
55
readme = "README.md"
66
license = { file = "LICENCE.md" }

src/blackgeorge/tools/mcp.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from mcp.client.session import ClientSession
66
from mcp.client.sse import sse_client
77
from mcp.client.stdio import StdioServerParameters, stdio_client
8+
from mcp.client.streamable_http import streamable_http_client
89
from pydantic import BaseModel, create_model
910

1011
from blackgeorge.async_utils import run_coroutine_in_thread, run_coroutine_sync
@@ -88,15 +89,27 @@ async def connect_stdio(
8889
read_stream, write_stream = await self._context_manager.__aenter__()
8990
self._session_context = ClientSession(read_stream, write_stream)
9091
self._session = await self._session_context.__aenter__()
91-
await self._session.initialize()
92+
await self._session.initialize() # type: ignore[misc]
9293
await self._discover_tools()
9394

9495
async def connect_sse(self, url: str) -> None:
9596
self._context_manager = sse_client(url)
9697
read_stream, write_stream = await self._context_manager.__aenter__()
9798
self._session_context = ClientSession(read_stream, write_stream)
9899
self._session = await self._session_context.__aenter__()
99-
await self._session.initialize()
100+
await self._session.initialize() # type: ignore[misc]
101+
await self._discover_tools()
102+
103+
async def connect_streamable_http(
104+
self,
105+
url: str,
106+
http_client: Any | None = None,
107+
) -> None:
108+
self._context_manager = streamable_http_client(url, http_client=http_client)
109+
read_stream, write_stream, _ = await self._context_manager.__aenter__()
110+
self._session_context = ClientSession(read_stream, write_stream)
111+
self._session = await self._session_context.__aenter__()
112+
await self._session.initialize() # type: ignore[misc]
100113
await self._discover_tools()
101114

102115
async def close(self) -> None:

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)