Setu Recipes: reusable workflows across every app.Browse templates
Setuसेतु
Documentation menu

Quickstart

Connect one user's GitHub account and create an issue from code. It takes about five minutes if you already have a Setu account and an API key. You can create both on the API keys page of the Setu app, or ask for access at [email protected].

1. Install an SDK#

The TypeScript (@setu/sdk) and Python (setu, 3.10+) SDKs are in private beta and are not on npm or PyPI yet. Write to [email protected] for access. You can also skip the SDKs and call the REST API directly.

Both SDKs read SETU_API_KEY and SETU_BASE_URL from the environment. SETU_BASE_URL defaults to https://api.setuagent.com.

2. Connect a user#

user_id is any stable string that identifies your own user. Setu never asks your users to create a Setu account.

TypeScript
import { Setu } from "@setu/sdk";

const setu = new Setu(); // uses SETU_API_KEY

const conn = await setu.connections.initiate({ userId: "user_1", toolkit: "github" });
console.log("Ask the user to open:", conn.connectUrl);
await conn.waitUntilActive(); // polls until they approve
Python
from setu import Setu

setu = Setu()
conn = setu.connections.initiate(user_id="user_1", toolkit="github")
print("Ask the user to open:", conn.connect_url)
conn.wait_until_active()

The user lands on GitHub's own approval screen, approves, and is sent to the redirect_url you configured for your project (or shown a confirmation page).

3. Run an action#

TypeScript
const res = await setu.execute({
  userId: "user_1",
  action: "github.create_issue",
  input: { owner: "acme", repo: "app", title: "Login button is misaligned" },
});
console.log(res.data); // { number: 42, url: "https://github.com/acme/app/issues/42" }
Python
res = setu.execute(
    user_id="user_1",
    action="github.create_issue",
    input={"owner": "acme", "repo": "app", "title": "Login button is misaligned"},
)
print(res.data)

If the user has not connected GitHub yet, the call fails with NOT_FOUND (never connected) or CONNECTION_NEEDS_REAUTH (token no longer valid). In the TypeScript SDK, check error.needsConnection and send them through step 2.

4. Give the tools to a model#

Search the catalog so the model only sees the tools it needs, then let Setu run whatever it calls.

TypeScript
const tools = await setu.tools.search("create an issue", { format: "openai", limit: 5 });

const completion = await openai.chat.completions.create({
  model: "gpt-4o",
  messages,
  tools,
});

const calls = completion.choices[0].message.tool_calls ?? [];
const results = await setu.handleToolCalls({ userId: "user_1", format: "openai", toolCalls: calls });
messages.push(completion.choices[0].message, ...results);

Use format: "anthropic" for Claude. Failures come back as error results the model can read and recover from, not as exceptions. See Agent frameworks.

5. Or skip the SDK and use MCP#

Create a session and give its URL to Cursor, Claude Desktop or any MCP client. See MCP.

What next#