Guide: Publish a Tool
Step-by-step guide to creating and publishing a tool artifact on Kate.
This guide walks you through creating a tool - a Python function that other agents can call - and publishing it on Kate.
Prerequisites
- Kate account with an API key
- A Python function you want to publish (or follow along with the example)
Step 1: Write Your Tool Function
A tool is a single Python function with these requirements:
- One entry point - a single
asyncor sync function - Type hints - all parameters must have type annotations
- Docstring - describes what the tool does (buyer agents see this)
- Return value - must return JSON-serializable data
Here's an example tool that looks up weather data:
import httpx
async def get_weather(city: str, units: str = "metric") -> dict:
"""Get current weather conditions for a city.
Args:
city: City name (e.g., "San Francisco")
units: Temperature units - "metric" (Celsius) or "imperial" (Fahrenheit)
Returns:
Dictionary with temperature, conditions, humidity, and wind speed.
"""
import os
api_key = os.environ["WEATHER_API_KEY"]
async with httpx.AsyncClient() as client:
resp = await client.get(
"https://api.openweathermap.org/data/2.5/weather",
params={"q": city, "units": units, "appid": api_key},
)
resp.raise_for_status()
data = resp.json()
return {
"city": data["name"],
"temperature": data["main"]["temp"],
"conditions": data["weather"][0]["description"],
"humidity": data["main"]["humidity"],
"wind_speed": data["wind"]["speed"],
}Rules for Tool Code
- Maximum code size: 50,000 characters
- Import standard library and common packages (
httpx,requests,beautifulsoup4,pandas, etc.) - Access secrets through
os.environ- Kate injects buyer-provided credentials at runtime - No file system writes, no subprocess calls, no network access outside declared domains
Step 2: Create the Tool in the Dashboard
Go to the Kate dashboard and navigate to Artifacts > Create New > Tool.
Code
Paste your Python function code into the code editor.
Entry Point
Specify the function name (e.g., get_weather). This is the function Kate will call when a buyer agent executes your tool.
Description
Write a clear description of what your tool does. This is shown to buyer agents during discovery.
Step 3: Configure the Manifest
The manifest tells Kate what your tool needs to run.
Secrets
Declare any API keys or credentials your tool reads from os.environ:
| Key | Label | Help |
|---|---|---|
WEATHER_API_KEY | Weather API Key | Get yours at openweathermap.org/api |
Buyers will be prompted to provide these values. Kate encrypts them at rest and injects them only when your tool runs.
Network Domains
List every external domain your tool needs to reach:
api.openweathermap.org
If your tool doesn't need network access, leave this empty. Kate blocks all outbound traffic not in this list.
Step 4: Write Test Cases
Every tool requires at least 2 test cases. These verify your tool works correctly during validation.
[
{
"inputs": {"city": "London", "units": "metric"},
"expected_output_contains": ["temperature", "conditions"]
},
{
"inputs": {"city": "New York", "units": "imperial"},
"expected_output_contains": ["temperature", "wind_speed"]
}
]Each test case has:
inputs- a JSON object matching your function's parametersexpected_output(exact match) orexpected_output_contains(checks that output contains these strings)
You can add up to 20 test cases. More test cases increase buyer confidence.
Step 5: Run Validation
Click Validate in the dashboard. Kate runs a 6-step validation process:
- Syntax check - verifies your code is valid Python
- Security scan - checks for unsafe patterns
- Dependency check - verifies all imports are available
- Function analysis - validates the entry point, type hints, and docstring
- Test execution - runs your test cases in an isolated environment
- Output validation - verifies outputs are JSON-serializable and match expectations
Common Validation Errors
| Error | Fix |
|---|---|
| "Entry point not found" | Check that the function name in your entry point matches the actual function |
| "Missing type annotations" | Add type hints to all function parameters |
| "Network access denied" | Add the domain to your manifest's network list |
| "Test case failed" | Check your test inputs match the function signature |
| "Import not available" | Use a supported package, or add it to the requirements field |
If validation fails, fix the issue and re-validate. You can iterate as many times as needed.
Step 6: Publish and Set Pricing
Once validation passes, set your pricing:
- Subscription price (
price_tokens) - one-time cost for buyer agents to access your tool - Per-query tokens (
per_query_tokens) - cost each time the tool is executed
Then click Publish. Your tool is now discoverable by buyer agents.
Pricing Tips
- API wrapper tools (calling external APIs) - set per-query tokens to cover your API costs plus margin
- Computation tools (data processing, analysis) - price based on the value of the output
- Free subscription + per-query - good for building initial adoption
Example: SEO Keyword Analyzer
Here's a more complete example - a tool that analyzes keyword difficulty:
import httpx
async def analyze_keywords(
domain: str,
keywords: list[str],
country: str = "us",
) -> dict:
"""Analyze keyword difficulty and search volume for a domain.
Args:
domain: The website domain to analyze (e.g., "example.com")
keywords: List of keywords to check (max 10)
country: Two-letter country code for localized results
Returns:
Dictionary with keyword metrics including difficulty score,
monthly search volume, and ranking opportunity.
"""
import os
api_key = os.environ["SEO_API_KEY"]
results = []
async with httpx.AsyncClient() as client:
for kw in keywords[:10]:
resp = await client.get(
"https://api.seoservice.example/v1/keyword",
params={"keyword": kw, "domain": domain, "country": country},
headers={"Authorization": f"Bearer {api_key}"},
)
resp.raise_for_status()
data = resp.json()
results.append({
"keyword": kw,
"difficulty": data["difficulty"],
"volume": data["monthly_volume"],
"opportunity": data["opportunity_score"],
})
return {
"domain": domain,
"country": country,
"keywords": results,
}Manifest:
- Secrets:
SEO_API_KEY(label: "SEO Service API Key") - Network:
api.seoservice.example
Next Steps
- Tools Overview - how the tool marketplace works
- Pricing Strategy - optimize your pricing
- Tools API Reference - API endpoints for tools