An example implementation of a tool server using universal-tool-server.
This server implements the following example tools:
- Exchange Rate: use an exchange rate API to find the exchange rate between two different currncies.
- GithHub API: surface most recent 50 issues for a given github repository.
- Hacker News: query hacker news to find the 5 most relevant matches.
- Reddit: Query reddit for a particular topic
If you want to spin the server up locally to test it out without authentication, you can run the following command:
DISABLE_AUTH=true uv run uvicorn app.server:app You'll need to have uv installed: https://docs.astral.sh/uv/
Once the server is running, if auth is disabled, you'll be able to access the API documentation at: http://localhost:8000/docs
The server implements a very basic form of authentication that supports a single user. To use it, you'll need to set an APP_SECRET environment variable.
-
Generate a secret using your favorite random number generator
export APP_SECRET=$(openssl rand -base64 32 )
or
export APP_SECRET=$(head -c 32 /dev/urandom | base64)
or
export APP_SECRET="some_super_secure_password"
-
Run with
uvAPP_SECRET=$APP_SECRET uv run uvicorn app.server:app
-
Build with docker
docker build -t example-tool-server . -
Generate a secret key
-
Run the image locally
docker run -e APP_SECRET=$APP_SECRET -p 8080:8080 example-tool-server
Alternatively, deploy to your favorite cloud provider.
Once the server is running you can use the universal-tool-client to interact with it.
pip install universal-tool-clientfrom universal_tool_client import get_sync_client
url = "http://localhost:8000"
headers = {
"Authorization": "YOUR SECRET GOES HERE",
}
client = get_sync_client(url=url, headers=headers)
print(client.health()) # Health check
print(client.info()) # Server version and other information
# List tools
print(client.tools.list()) # List of tools
# Call a tool
print(client.tools.call("echo", {"msg": "hello"})) # hello!
# Get the tools as a LangchainTools object
tools = client.tools.as_langchain_tools()Use the async client instead of the sync client.
from universal_tool_client import get_async_clientNo authentication:
curl -X 'POST' \
'http://127.0.0.1:8000/tools/call' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"$schema": "otc://1.0",
"request": {
"tool_id": "get_weather@1.0.0",
"input": { "city": "san francisco"}
}
}'With authentication:
Add the Authorization header with the secret you generated earlier.
e.g., -H 'Authorization: YOUR SECRET
You will see a result like:
{
"call_id": "b5b034c5-064e-4f72-9ffc-842bf6f38ef9",
"success": true,
"value": "The weather in san francisco is nice today with a high of 75°F."
}