A lightweight Python client for the Tool Server Protocol (TSP). It provides a simple, asynchronous way to interact with tool servers (like gtsp) via the stdio mode.
- Asynchronous IO: Built with
asyncio. - Full Protocol Support: Methods for
initialize,tool,sandbox, andshutdown. - Event Handling: Easy subscription to server-sent events.
- Error Handling: Custom
TSPExceptionwith error codes. - Logging: Captures server
stderrfor easier debugging.
pip install pytspclientIf you are developing locally:
git clone https://github.com/alexazhou/gTSP.git
cd gTSP/pyTSPClient
pip install -e .import asyncio
from pytspclient import TSPClient, TSPException
async def main():
# command to launch the TSP server
client = TSPClient(["./gtsp", "--mode", "stdio"])
# 1. Connect (starts the subprocess)
await client.connect()
try:
# 2. Initialize handshake
# protocol_version is hardcoded to 0.3 internally
init_data = await client.initialize(
client_info={"name": "my-agent"},
include=["read_file", "write_file"]
)
print(f"Connected to: {init_data.server_info.get('name')}")
# 3. Call a tool
try:
result = await client.tool("read_file", {"file_path": "test.txt"})
print(f"File content: {result['content']}")
except TSPException as e:
print(f"Tool failed: [{e.code}] {e.message}")
# 4. Graceful Shutdown
await client.shutdown()
finally:
# Ensure resources are cleaned up
await client.disconnect()
if __name__ == "__main__":
asyncio.run(main())command: The shell command to run the TSP server.request_timeout_sec: Timeout for each request.
Spawns the TSP server process and starts the internal read loops for stdout and stderr.
Forcefully terminates the process and fails all pending requests.
Handshake with the server. Protocol version is internally set to 0.3.
Parameters:
client_info: optional metadata about the client.include: optional list of tools to enable.exclude: optional list of tools to disable.
Returns a TSPInitializeResult object.
Executes a specific tool on the server.
Configures the server's sandbox/workspace environment.
Sends a shutdown request and then calls disconnect().
Registers a callback for server-sent events.
def on_event(event: TSPEvent):
print(f"Received event: {event.event} with data: {event.data}")
client.add_event_handler(on_event)protocol_version: strcapabilities: Dict[str, Any]server_info: Dict[str, Any]
Raised when the server returns an error response.
code: The error code (e.g.,tsp/error,tool/not_found).message: Human-readable error message.
MIT