
Steroid_Kit
Steroid MCP›Tool Discovery
Tool Discovery — search_tools
search_tools finds the right tool for a task among 3,188 tools from 241 catalog entries, using one natural-language query. It returns at most three candidates with their argument descriptors, plus a short-lived capability handle that run_tool needs to execute one of them.
What is search_tools?
Registering every catalog tool with your coding agent would put thousands of schemas into its context. Instead, the agent describes what it wants to do, and search_tools returns only the few tools that match. The agent then reads their arguments and calls run_tool with the one it picked.
| Mode | search_tools available? | Notes |
|---|---|---|
| Local | No | Local mode registers three recall operations only. |
| Connected | Yes | Registered with run_tool and four workflow operations — nine operations in total. |
NOTE
Discovery runs on Steroid's service at mcp.steroidkit.com and is authenticated with your connection string. See Local vs Connected Mode to switch modes.
Writing a Query
search_tools takes exactly one parameter, query, a plain-language description of the action. There is no result-count, filter or server parameter.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | What you want to do, in plain language. |
- Include the action — send, create, list, query — and the object it acts on.
- Name the service when you know it (Slack, GitHub, Postgres).
- A vague query still returns up to three candidates — there is no relevance cutoff — so they are simply less likely to be what you meant. Check
server_nameand the tool description before running.
Queries that identify both action and service
"post a message to a Slack channel"
"create a new issue in a GitHub repository"
"search the web for recent information"
"run a read-only SQL query on Postgres"Understanding Results
Every tool in the catalog is indexed individually. A search retrieves the 50 closest tools, re-ranks them, and returns the best three. Two candidates can come from the same server.
| Ranking stage | Weight | What it does |
|---|---|---|
| Semantic similarity | 68% | How closely the tool's meaning matches the query (normalized). |
| Keyword match | 32% | How many query terms appear in the tool's name and description (normalized). |
| Diversity re-ranking (MMR) | After scoring | Avoids returning three near-identical tools; favours variety across servers. |
search_tools — response (one candidate shown)
{
"workflow_run_id": "w1a2b3c4d",
"step": "discovery",
"capability_token": "Xk3_9aQe2L",
"tool_candidates": [
{
"server_name": "slack",
"server_description": "Interact with Slack Workspaces over the Slack API.",
"server_metadata": "category:communication | owner:modelcontextprotocol | tags:slack communication",
"tool_details": {
"name": "slack_post_message",
"description": "Post a new message to a Slack channel",
"arguments": [
{ "name": "channel_id", "type": "string", "desc": "The ID of the channel to post to" },
{ "name": "text", "type": "string", "desc": "The message text to post" }
]
}
}
],
"message": "<guidance from the server>",
"instructions": "<next-step instructions for the agent>"
}server_metadatais a single string ofkey:valuepairs, not an object.- Each entry in
argumentshasname,typeanddesc, plusoptionalwhen the argument is not required. - Ranking scores are not returned. Candidate order is the ranking.
When nothing matches
Errors come back as a normal response with an error field, so the agent can read them and retry with a different query.
No candidates found
{
"error": "NO_CANDIDATES",
"message": "No tool candidates found matching the query",
"hint": "Try a different query",
"workflow_run_id": "w1a2b3c4d"
}The Capability Handle
capability_token is a random ten-character handle that points to state held by Steroid's service. It is not a signed token and encodes nothing; the agent passes it to run_tool unchanged.
| Property | Value |
|---|---|
| Authorizes | Only the tools returned by the search that issued it |
| Lifetime | 5 minutes |
| Uses | One run_tool call — the workflow is finished after it runs, whether it succeeded or failed |
| Survives a service restart | No |
TIP
If run_tool returns INVALID_TOKEN or INVALID_STEP_SEQUENCE, the handle has expired, was already used, or does not cover that tool. Call search_tools again — never reuse or construct a handle.
Examples
These are MCP tools/call requests as your coding agent sends them. Ranking can change as the catalog changes, so always use the candidate actually returned.
Post to Slack
tools/call
{
"name": "search_tools",
"arguments": { "query": "post a message to a Slack channel" }
}Expected candidate
server_name: slack
tool_details.name: slack_post_message
inputs: channel_id, text
needs: secret slack.bot_token and config slack.team_idCreate a GitHub issue
tools/call
{
"name": "search_tools",
"arguments": { "query": "create a new issue in a GitHub repository" }
}Expected candidate
server_name: github-official
tool_details.name: issue_write
required inputs: method, owner, repo (method "create" for a new issue)
needs: secret github.personal_access_tokenSearch the web
tools/call
{
"name": "search_tools",
"arguments": { "query": "search the web for recent information" }
}Expected candidate
server_name: brave
tool_details.name: brave_web_search
required inputs: query
needs: secret brave.api_key