# Quickstart

Make your first tool call through Jussora, approve it as your own customer, and collect the result.

In this tutorial you add an agent, connect your own GitHub account to it as if you were your own
customer, and make a tool call that Jussora holds until you approve it. You play both sides: the
developer who holds the agent's API key, and the person who decides what the agent may do.

By the end you will have seen the whole loop. Your agent asks, Jussora waits, the person approves,
Jussora places the call on GitHub, and your agent collects the result. At no point does your agent
hold a GitHub token.

## What you need

- **A GitHub account.** You connect it as your own customer. The only call this tutorial makes
  reads your own GitHub profile, so nothing in your account changes.
- **A terminal with `curl`.**
- **About 15 minutes.**
- **Nothing to pay.** Every account gets $20 of free credit each month, and a call costs $0.001 only
  when it succeeds. There is no card to enter.

:::caution[What GitHub will ask you to allow]
When you connect GitHub, GitHub's own screen asks you to give Jussora access to your repositories,
gists, notifications and projects, and to organization and enterprise administration. Jussora asks
for every scope that any of GitHub's tools needs, so that a tool your customer allows can work.
None of it is used without a choice: every tool starts at **Ask**, and this tutorial only reads
your profile.

You can disconnect GitHub in Jussora at any time, under **Settings** then **Connected accounts**.
To remove Jussora's access on GitHub's side too, open GitHub's **Settings**, then
**Applications**, then **Authorized OAuth Apps**.
:::

## How the pieces fit

Your agent never calls GitHub itself. It sends each call to Jussora over MCP, and Jussora calls
GitHub with your customer's own token, which you never see.

Your agent sends two things with every call. Its **API key** says which agent is calling. The
**`Jussora-Account`** header says which of your customers the call is for, using your own
identifier for them, whatever you already call them in your app.

Your customer connects their own GitHub account to Jussora and chooses, tool by tool, what happens
when your agent calls it:

| Their choice | What Jussora does with the call |
| --- | --- |
| **Allow** | Calls GitHub straight away and hands back GitHub's answer. |
| **Ask** | Holds the call and asks your customer. Calls GitHub only once they approve. |
| **Block** | Refuses the call. GitHub is never called. |

## 1. Add an agent

1. Sign in to the [Jussora console](https://console.jussora.com). The same form signs you up if
   you are new.
2. In **Set up your first agent**, click **Add agent**. If you closed that card, click
   **Add Agent** above the table of agents instead.
3. For **Name**, enter `My first agent`. For **Provider**, choose **GitHub**. Click
   **Create agent**.
4. Copy the key shown under **API key**. This is the only time it is shown.
5. Keep it in your terminal for the rest of the tutorial:

   ```sh
   export JUSSORA_API_KEY="paste-your-key-here"
   ```

6. Click **I have copied the key**. The agent's page opens.

:::tip[Lost the key?]
On the agent's page, click **Regenerate** to get a new one. The old key stops working at once.
:::

## 2. Get a link for your customer

Your customer is the person your agent acts for. Jussora knows them only by your identifier for
them, which in this tutorial is `my-first-customer`.

1. On the agent's page, click **Get a link**.
2. In **Your identifier for this person**, enter `my-first-customer`, then click **Get a link**.
3. Click **Copy link**.

The link can be opened once and expires after five minutes. If it expires, click **Another** and
get a new one. Getting a link costs nothing and creates nothing until someone opens it.

:::caution[In your product, a link stays inside your app]
Whoever opens a link connects their own Jussora account to your identifier. Here you open it
yourself. In your product, show it only to the customer it is for, inside your own app where they
are already signed in. Never email it or text it.
:::

## 3. Connect GitHub as your customer

Open the link in your browser. You are now your own customer.

1. The page says **Sign in to Jussora to give tool access to My first agent**. Sign in with the
   same email address you use for the console. It is one account, which can be a developer and a
   customer at once. Jussora emails you a code to type in, or you can continue with Google or
   Apple.

   If your browser is already signed in to Jussora, the page asks you to confirm instead. Click
   **Continue as** followed by your address.

2. On **Connect your accounts**, click **Connect GitHub**. GitHub asks you to authorize Jussora.
   Authorize it, and GitHub sends you back to the same page.
3. Click **Continue**.

   If you connected GitHub to Jussora before, these two steps are skipped and the next page opens
   on its own.

4. On **Choose tool access for My first agent**, every GitHub tool starts at **Ask**. Leave them
   all there and click **Connect agent**.
5. The page says **You are connected**.

**Ask** means Jussora asks the customer before it places a call to that tool. **Allow** places the
call straight away, and **Block** refuses it.

:::note
**Continue to My first agent** takes you to your agents in Jussora, because the console made this
link. A link your own backend makes sends your customer back to your app instead. The
[guide to inviting customers](https://jussora.com/docs/guides/invite-customers/) shows how.
:::

## 4. Check that calls will land

Ask Jussora whether a call for `my-first-customer` would go through. Your backend uses the same
request to know when a customer has finished connecting.

```sh
curl https://app.jussora.com/v1/connections/status \
  -H "Authorization: Bearer $JUSSORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-first-customer"}'
```

The answer:

```json
{
  "state": "connected",
  "calls_enabled": true,
  "requirements": [],
  "conflict": false
}
```

`"calls_enabled": true` means the customer has accepted the agent and given it at least one tool,
at **Allow** or **Ask**.

- If `state` is `"started"` and `requirements` is `["accept_connection"]`, the customer opened the
  link but did not finish. Go back to step 3.
- If `state` is `"unknown"`, nobody is connected under that identifier. Check its spelling, then
  get a new link in step 2.

curl prints each answer on one line. They are laid out here for reading. Add `| jq` to the end of a
command to do the same, if you have `jq`.

## 5. Make a call

Now your agent calls GitHub's `get_me` tool through Jussora. It reads your own GitHub profile and
changes nothing.

An MCP client builds this request for you. Here curl sends it by hand, so you can see every part.

```sh
curl https://app.jussora.com/mcp \
  -H "Authorization: Bearer $JUSSORA_API_KEY" \
  -H "Jussora-Account: my-first-customer" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: github__get_me" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "github__get_me",
      "arguments": {},
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28",
        "io.modelcontextprotocol/clientCapabilities": {}
      }
    }
  }'
```

| Header | What it says |
| --- | --- |
| `Authorization` | Which agent is calling, by its API key. |
| `Jussora-Account` | Which customer the call is for, by your own identifier for them. |
| `MCP-Protocol-Version`, `Mcp-Method`, `Mcp-Name` | The MCP version, the method and the tool. MCP 2026-07-28 asks for them, and they repeat what the body says. |

Every tool name carries its provider in front of two underscores, so `github__get_me` is GitHub's
`get_me`.

The answer:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Waiting for approval, request req_3f9a1c07e2b84d6a90c5f1e2. Jussora has not called GitHub. Call check_approval with this request id to collect the outcome — it stays answerable indefinitely, including from a new session."
      }
    ],
    "isError": false,
    "_meta": {
      "ai.jussora/status": {
        "request_id": "req_3f9a1c07e2b84d6a90c5f1e2",
        "approval_status": "pending",
        "tool_call_status": "waiting"
      },
      "io.modelcontextprotocol/serverInfo": {
        "name": "jussora",
        "version": "0.1.0"
      }
    },
    "resultType": "complete"
  }
}
```

**This is not an error.** `get_me` is at **Ask**, so Jussora has not called GitHub yet. It is
waiting for your customer. Copy the request id from your own answer, the part that starts with
`req_`. You need it in step 7.

## 6. Approve the call as your customer

Jussora emails the customer about the request, and in this tutorial the customer is you. The email
is titled **Approval needed: My first agent — Call get_me on GitHub**.

1. Open the link in the email. If no email has arrived, open
   [app.jussora.com](https://app.jussora.com), where the request is listed under **Pending**.
2. The page shows the agent, the tool, the arguments the call will be sent with, and GitHub's own
   description of the tool. Your customer approves the call exactly as it will be sent.
3. Click **Approve**. Jussora places the call on GitHub right away.

A request never expires. It waits under **Pending** until someone answers it, so there is no hurry.

## 7. Collect the result

Your agent asks Jussora how the request ended, with Jussora's `check_approval` tool. Put your own
request id in place of `req_3f9a1c07e2b84d6a90c5f1e2`.

```sh
curl https://app.jussora.com/mcp \
  -H "Authorization: Bearer $JUSSORA_API_KEY" \
  -H "Jussora-Account: my-first-customer" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: check_approval" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "check_approval",
      "arguments": {"request_id": "req_3f9a1c07e2b84d6a90c5f1e2"},
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28",
        "io.modelcontextprotocol/clientCapabilities": {}
      }
    }
  }'
```

The answer starts with a line saying how the request ended, followed by exactly what GitHub
answered. GitHub's answer is shortened here.

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Request req_3f9a1c07e2b84d6a90c5f1e2 was approved and the call succeeded."
      },
      {
        "type": "text",
        "text": "{\"login\":\"your-github-login\", …}"
      }
    ],
    "isError": false,
    "_meta": {
      "ai.jussora/status": {
        "request_id": "req_3f9a1c07e2b84d6a90c5f1e2",
        "approval_status": "approved",
        "tool_call_status": "succeeded",
        "error_code": null
      },
      "io.modelcontextprotocol/serverInfo": {
        "name": "jussora",
        "version": "0.1.0"
      }
    },
    "resultType": "complete"
  }
}
```

If you run this before approving, the first line says
`Request req_… is still waiting on a person.` and `approval_status` is `"pending"`. Approve the
request, then run it again.

## 8. Let the tool through without asking

This step is optional. It shows that your customer, not you, decides how each tool behaves.

1. At [app.jussora.com](https://app.jussora.com), click your avatar in the top corner to open
   **Settings**, then click **Agents**.
2. On **My first agent**, click **Edit**.
3. Set `get_me` to **Allow** and click **Save**.
4. Run the command from step 5 again.

This time GitHub's answer comes straight back, with no request and no email:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"login\":\"your-github-login\", …}"
      }
    ],
    "resultType": "complete",
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "jussora",
        "version": "0.1.0"
      }
    }
  }
}
```

## What you built

- An agent with an API key that reaches your customer's GitHub through Jussora, without ever
  holding a GitHub token.
- A customer, connected under your own identifier for them, who chose what the agent may do.
- A call that waited for that customer, was approved, was placed by Jussora, and was collected by
  the agent.

In the console, the dashboard's **Tool Calls** tab lists every call your agent made.

## If something goes wrong

### 401 Invalid API key

The answer is `401` with `{"detail":"Invalid API key"}`. The key was mistyped, or it was
regenerated. Set `JUSSORA_API_KEY` again, or click **Regenerate** on the agent's page.

### 400 Missing Jussora-Account

The answer is `400` with `Jussora-Account must carry the identifier you use for this person`. Add
the header, with the identifier you gave the link.

### 403 No connection for that name

The answer is `403` with `This agent has no connection for that name…`. Nobody is connected under
that identifier. Check its spelling against step 2, then run step 4.

### 403 Not finished connecting

The answer is `403` with `That person has not finished connecting yet…`. The customer opened the
link but did not click **Connect agent**. Finish step 3, or open a new link.

### 403 Agent archived

The answer is `403` with `This agent is archived…`. The agent was archived in the console. Unarchive
it on the agent's page.

### Tool not granted

The result has `"isError": true` and says the tool `is not granted to this agent`. The customer has
not given the agent that tool, or its name is misspelled. Check the name, then the tool's setting
under **Settings**, **Agents**, **Edit**.

### Link no longer works

The link page says the link no longer works. It was opened already, or five minutes passed. Get
another link in step 2.

### 429 Rate limit reached

The answer is `429` with `Rate limit reached`. Too many requests in a minute. Wait the number of
seconds the answer gives, then try again.

## Next steps

- **Invite customers.** Your backend makes the link for each customer and checks when
  they have connected. See the [guide to inviting customers](https://jussora.com/docs/guides/invite-customers/).
- **Point your agent at Jussora.** Any MCP client that can send HTTP headers works: the Claude Agent
  SDK, the OpenAI Agents SDK, Vercel's AI SDK, LangChain, Pydantic AI and Google's ADK among them.
  Give it `https://app.jussora.com/mcp` and the two headers from step 5. To try it from Claude Code:

  ```sh
  claude mcp add --transport http jussora https://app.jussora.com/mcp \
    --header "Authorization: Bearer $JUSSORA_API_KEY" \
    --header "Jussora-Account: my-first-customer"
  ```

  This puts the agent's key on your own computer, which is fine for trying Jussora and wrong for a
  product: the key belongs on your server, never with your customers.

## For coding agents

This page is also served as Markdown at
[jussora.com/docs/quickstart.md](https://jussora.com/docs/quickstart.md). If a coding agent is
building with Jussora for you, these rules belong in its instructions, such as your project's
`AGENTS.md` or `CLAUDE.md`:

```md
## Jussora
- Never put the Jussora API key in browser or mobile code. It stays on the server.
- Never send a connection link by email, text or chat. Show it only to the signed-in customer, inside the app.
- Never treat "Waiting for approval" as an error. Collect the outcome with check_approval and the request id.
- Never repeat a call that is waiting for approval. Each repeat raises another request for the person.
- An agent cannot connect an account or approve a call. Hand the link to the person, then wait until POST /v1/connections/status answers "calls_enabled": true.
```
