Skip to content

Quickstart

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.

  • 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.

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. Sign in to the Jussora console. 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:

    Terminal window
    export JUSSORA_API_KEY="paste-your-key-here"
  6. Click I have copied the key. The agent’s page opens.

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.

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.

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.

Terminal window
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:

{
"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.

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.

Terminal window
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:

{
"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.

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, 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.

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

Terminal window
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.

{
"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.

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

  1. At 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:

{
"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"
}
}
}
}
  • 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.

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.

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.

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.

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.

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

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.

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

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.

  • Invite customers. Your backend makes the link for each customer and checks when they have connected. See the guide to inviting 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:

    Terminal window
    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.

This page is also served as Markdown at 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:

## 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.