Product
The right tools at runtime, over one MCP URL.
Give each user a session and hand its URL to Claude, Cursor or any MCP client. Four meta-tools let the model find, inspect and run any action without loading the whole catalog.
curl -X POST https://api.setuagent.com/v1/sessions \
-H "authorization: Bearer $SETU_API_KEY" \
-H "content-type: application/json" \
-d '{ "user_id": "user_1", "toolkits": ["github", "slack"] }'
# => { "mcp_url": "https://api.setuagent.com/v1/mcp/ses_..." }Four meta-tools instead of four hundred schemas.
In dynamic mode the model searches for a tool, reads its schema, runs it, and asks for a connect link if the app is not connected yet.
- SETU_SEARCH_TOOLS finds actions by describing the task
- SETU_GET_TOOL_SCHEMA returns one action's input schema
- SETU_EXECUTE_TOOL runs it
- SETU_CONNECT returns a link for an unconnected app
Dynamic mode
SETU_SEARCH_TOOLS | Find actions for a task |
SETU_GET_TOOL_SCHEMA | Read one input schema |
SETU_EXECUTE_TOOL | Run an action |
SETU_CONNECT | Get a connect link |
Search that ranks what you mean.
Tool search is keyword-ranked across names, descriptions and parameters, with toolkit filters. Ask for five and the model sees five.
- Restrict to the toolkits a user has connected
- OpenAI, Anthropic or raw JSON Schema output
- Results small enough to leave room for the task
const tools = await setu.tools.search("post a message", {
toolkits: ["slack"],
limit: 3,
format: "anthropic",
});Static mode for a fixed surface.
When you want a small, predictable tool list, pass an allow-list and each action is registered as its own MCP tool.
- Explicit actions per session
- Sessions expire on a timer you choose
- A session URL is a secret, treated like one
{
"user_id": "user_1",
"mode": "static",
"actions": ["github.create_issue", "slack.post_message"],
"ttl_seconds": 3600
}Give your agent real hands.
Connect an app, hand your agent the tools, and watch it finish the job.