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.
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 approvefrom 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#
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" }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.
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#
- Concepts: projects, users, toolkits, connections and sessions.
- API reference: every endpoint.
- Integrations: the actions you can call today.