Server tools
Advisor, subagent and web fetch tools that RouterPlus runs for your model.
Server tools are tools that RouterPlus runs for your model. Add them to tools on POST /v1/chat/completions. The model calls them like any function tool. RouterPlus runs the call, gives the result to the model and calls the model again. You get the final answer.
| Tool | What the model gets |
|---|---|
routerplus:advisor | Advice from a second model that sees the conversation. |
routerplus:subagent | The answer of a helper model to a task that the model writes. |
routerplus:web_fetch | The text of a web page. |
Request
{
"model": "moonshotai/kimi-k3",
"messages": [{ "role": "user", "content": "Compare the two pricing pages and recommend one plan." }],
"tools": [
{ "type": "routerplus:advisor", "advisor": { "model": "claude-opus-5-5", "max_calls": 2 } },
{ "type": "routerplus:subagent", "subagent": { "models": ["gpt-6-luna", "claude-sonnet-5-5"], "max_calls": 4 } },
{ "type": "routerplus:web_fetch", "web_fetch": { "allowed_domains": ["example.com"], "max_bytes": 300000 } },
{ "type": "function", "function": { "name": "save_report", "parameters": { "type": "object" } } }
]
}| Field | Rule |
|---|---|
advisor.model | The advisor model. |
advisor.max_calls | 1 to 5. The default is 3. |
subagent.models | 1 to 5 helper models. The model can pick one. The default is the first. |
subagent.max_calls | 1 to 8. The default is 4. |
web_fetch.allowed_domains | Optional. Fetch only these domains and their subdomains. |
web_fetch.max_bytes | Up to 2000000. The default is 500000. RouterPlus cuts a longer page at this size. |
web_fetch.max_calls | 1 to 10. The default is 5. You can send web_fetch without its object. |
List each tool type once. When a server tool is in the request, your own function tools cannot use its name (advisor, subagent or web_fetch).
What the model sees
RouterPlus gives the model one function tool for each server tool:
advisor(question): the advisor gets the conversation so far as text, plus the question. It answers with advice for the model.subagent(task, model?): the helper gets the task as its only message. The model gets the helper's final answer.web_fetch(url): RouterPlus fetches the URL and gives the model the page as plain text.
When a tool has used its max_calls, the model gets a message that says so and continues without that tool.
How the loop ends
- The model answers without a tool call. You get that answer.
- The model calls one of your own function tools. You get that answer with your tool calls. RouterPlus removes server tool calls from the same answer. Run your tools and send the next request as usual.
- After 12 model calls, you get the last answer without its tool calls, and
server_tools.stoppedis"round_limit".
Your tool_choice applies to the first model call only.
Response
The response is an OpenAI chat completion. model is your model. usage is the sum over every model call: your model, the advisor and the helpers. usage.cost is present when the calls report a cost.
{
"model": "moonshotai/kimi-k3",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "..." }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 5210, "completion_tokens": 940, "total_tokens": 6150, "cost": 0.0182 },
"server_tools": {
"rounds": 3,
"stopped": "answer",
"calls": [
{ "type": "web_fetch", "url": "https://example.com/pricing", "status": "ok", "bytes": 48211 },
{ "type": "subagent", "model": "gpt-6-luna", "status": "ok", "usage": { "prompt_tokens": 900, "completion_tokens": 300, "total_tokens": 1200 } },
{ "type": "advisor", "model": "claude-opus-5-5", "status": "ok", "usage": { "prompt_tokens": 2100, "completion_tokens": 120, "total_tokens": 2220 } }
]
}
}server_tools.stopped is "answer", "buyer_tools" or "round_limit". Each entry in server_tools.calls has a status:
| Status | Meaning |
|---|---|
ok | The tool ran. |
error | The tool failed. error says why. The model got the error as the tool result. |
refused | web_fetch did not fetch the URL. error says why. |
limit | The tool had used its max_calls. |
A web_fetch entry has truncated: true when RouterPlus cut the page at max_bytes.
stream: true streams the final answer only. The last chunk before [DONE] carries usage and server_tools.
Web fetch rules
- RouterPlus fetches only
httpandhttpsURLs. It refuses URLs with a user name or password. - RouterPlus resolves the host name first. It refuses the URL when any address is private, loopback, link-local (cloud metadata addresses included), shared, multicast or reserved. This applies to IPv4, IPv6 and IPv4 addresses inside IPv6.
- The connection goes to the address RouterPlus checked.
- RouterPlus follows up to 3 redirects and checks each with the same rules,
allowed_domainsincluded. - HTML becomes plain text. Other text types come back as they are. Images and other binary types are refused.
- A fetch stops after 20 seconds.
Billing
RouterPlus bills each model call as a direct call to its model. Your key's limits and guardrails apply to each call. A request with server tools costs the sum of those calls. web_fetch has no charge of its own.
Errors
| Status | Cause |
|---|---|
400 invalid_request | A server tool is invalid. The message names the field. |
| 400 | n is above 1. Server tools answer with one choice. |
403 guardrail_blocked | A guardrail blocks server tools (checked before any model call), or does not allow the model, advisor model or helper model. |
Limits
- Server tools do not work with
routerplus/fusion,routerplus/autoor amodelslist. - When a call of your model fails, you get that error unchanged.
For agents: /docs/server-tools.md and /llms.txt