New to tool search? Start with Tool Search 101 for an overview of why, how, and when to use it.
The Python SDK provides three methods for tool discovery:
search_tools(): search by intent, returns a Tools collection ready for any framework
search_action_names(): lightweight search returning action names and scores without fetching full tool definitions
get_search_tool(): returns a callable SearchTool for agent loops
Constructor Configuration
You can set default search options at the constructor level. These defaults apply to all search calls unless overridden per-call.
from stackone_ai import StackOneToolSet
# Custom search config
toolset = StackOneToolSet(search={"method": "semantic", "top_k": 5})
# Disable search
toolset = StackOneToolSet(search=None)
# Default: search enabled with method="auto"
toolset = StackOneToolSet()
Search Config Options
| Option | Type | Description |
|---|
method | "auto" | "semantic" | "local" | Search mode (default: "auto") |
top_k | int | Maximum number of tools to return |
min_similarity | float | Minimum relevance score threshold (0-1) |
Per-call overrides take precedence over constructor defaults:
# Constructor sets top_k=5 for all search calls
toolset = StackOneToolSet(search={"method": "semantic", "top_k": 5})
# Uses constructor defaults: method="semantic", top_k=5
tools = toolset.search_tools("manage employees")
# top_k overridden to 10 for this call; method remains "semantic"
tools = toolset.search_tools("manage employees", top_k=10)
search_tools() is the recommended method for agent frameworks. It fetches tools from your linked accounts, searches each connector in parallel via the semantic search API, and returns a Tools collection sorted by relevance.
from stackone_ai import StackOneToolSet
toolset = StackOneToolSet()
# Search for tools by intent
tools = toolset.search_tools(
"manage employee records and time off",
top_k=5,
search="auto", # tries semantic API first, falls back to local search
)
print(f"Found {len(tools)} tools")
# Use with any framework
openai_tools = tools.to_openai()
langchain_tools = tools.to_langchain()
Search Modes
# Auto (default): tries semantic API first, falls back to local search on failure
tools = toolset.search_tools("manage employees", search="auto")
# Semantic only: uses the semantic API, raises SemanticSearchError if unavailable
tools = toolset.search_tools("manage employees", search="semantic")
# Local only: hybrid BM25+TF-IDF search, no network call to the semantic endpoint
tools = toolset.search_tools("manage employees", search="local")
auto: Recommended for production. Searches each connector in parallel via the semantic API. If the API call fails, automatically falls back to local search and logs a warning.
semantic: Strict mode. Same parallel per-connector search, but raises SemanticSearchError on failure instead of falling back.
local: Runs a hybrid BM25 + TF-IDF search entirely in-process (powered by bm25s for BM25). No network call. Useful for offline or low-latency scenarios.
Parameters
| Parameter | Type | Description |
|---|
query | str | Natural language description of what you want to do |
top_k | int | None | Maximum number of tools to return |
search | "auto" | "semantic" | "local" | Search mode (default: "auto") |
connector | str | None | Filter to a specific provider (e.g., "bamboohr") |
min_similarity | float | None | Minimum relevance score threshold (0-1) |
account_ids | list[str] | None | Override account IDs for this search |
Search Action Names
search_action_names() queries the semantic API directly and returns metadata without fetching full tool definitions. Use it to preview results before committing to a full fetch.
results = toolset.search_action_names("manage employees", top_k=5)
for r in results:
print(f"{r.action_name} ({r.connector_key}): {r.similarity_score:.2f}")
# Then fetch specific tools based on results
top_actions = [r.action_name for r in results if r.similarity_score > 0.7]
tools = toolset.fetch_tools(actions=top_actions)
search_action_names() works with just STACKONE_API_KEY, no account ID needed. When called without account_ids, results come from the full StackOne catalog.
get_search_tool() returns a callable SearchTool for agent loops where the LLM decides what to search for.
search_tool = toolset.get_search_tool(search="auto")
# In an agent loop, call it with natural language queries
queries = [
"create a new employee",
"list job candidates",
"send a message to a channel",
]
for query in queries:
tools = search_tool(query, top_k=3)
tool_names = [t.name for t in tools]
print(f'"{query}" -> {", ".join(tool_names)}')
Framework Integration
Tool search returns a Tools collection with built-in framework converters. See the framework guides for full examples:
CrewAI accepts LangChain tools. Use tools.to_langchain() for CrewAI integration.
Next Steps