Integrations

An integration lets a change in your issue tracker start a coding agent on your machine. Someone moves a Jira ticket to In Progress, and Claude Code, Codex, or whichever CLI you use picks it up in the workspace you chose.

Connecting one takes a browser round-trip and nothing else. There is no API token to create, no webhook URL to paste, no signing secret to copy, and no tunnel to run — even though Open Run itself is only listening on localhost.


How it works

Jira  ──webhook──▶  openrun.sh  ──outbound WebSocket──▶  your machine
                    (owns the OAuth app,               (holds the connection
                     the tokens, the hook)              open, receives events)

Three properties fall out of that shape, and they are the reason it is built this way:

  • Your laptop is never addressable. It dials out to openrun.sh and keeps the socket open, so Jira never needs a route to it. No ngrok, no Cloudflare Tunnel, no port forwarding, no firewall change.
  • Vendor tokens never reach your machine. They are sealed at rest on the control plane (AES-GCM under a Worker secret that is not in the database) and only ever used from there. Your machine receives a normalized event — issue key, title, body, status, assignees — and nothing else.
  • Your code never leaves. Runs, prompts, diffs, and repositories stay local. The account carries integration events in one direction and nothing back.

Events that arrive while your machine is offline are queued for 24 hours and delivered when it reconnects.


Connect one

  1. Sign in. Integrations → any provider → Sign in and connect. If you are already signed in, this step is skipped.
  2. Approve at the vendor. You land on Jira's (or GitHub's, or Linear's) own consent screen. Approve, and — for GitLab, Bitbucket, Azure DevOps, and Jira — pick which project the webhook watches. GitHub asks in its own install screen. Linear watches the whole workspace.
  3. Finish setup. You come back to Open Run with the connection made. Pick a workspace and a runtime, adjust the events and the prompt if you want, and Create automation.

That third step is the one that matters: a connection on its own receives events and matches nothing. The automation is what turns a delivery into a run.

Check that it works

Open the provider's page and press Send test event. It reports how many automations matched. If the answer is zero, the automation's event list and the event you sent do not overlap.

Then change a real issue. The delivery shows up under Recent deliveries with the runs it started.


What each provider watches

Provider Hooks You pick a project
GitHub Issues and issue comments, per installation In GitHub's install screen
GitLab Issues and notes, per project Yes, after approving
Bitbucket Issues and comments, per repository Yes, after approving
Jira Issues and comments, one project or a whole site Yes, after approving
Linear Issues, comments, projects, cycles No — the whole workspace
Azure DevOps Work items, per project Yes, after approving

Every provider is normalized to the same event shape, so an automation's prompt reads the same whichever one fired it: {{issue.key}}, {{issue.title}}, {{issue.body}}, {{issue.status}}, {{issue.labels}}, {{issue.assignees}}, {{event.type}}.


Filters

An automation can narrow which deliveries actually run it — by label, project, status, previous status, or assignee. A common shape is "only issues labelled agent", so the agent stays out of everything else.


Disconnecting

Disconnect (the trash icon on the provider page) revokes the connection on the control plane, deletes the webhook at the vendor, and drops the local row. You have to be signed in — a 401 keeps the local row so a later attempt can still reach Atlassian.

If Jira refuses to delete the hook, the local row still goes away (deliveries already stopped) and the page tells you, so you can remove the leftover webhook in Jira if events keep arriving.

Connecting again without disconnecting first is also safe for Jira: the new connection retires any overlapping hook on that site (the old whole-site connection, or the same project). Two different projects stay independent.


Troubleshooting

"…is not available on this Open Run deployment yet." The provider's OAuth app is not registered on the control plane you are pointed at. Nothing you can do from the app; the deployment's operator adds it.

The connection says error with a message from the vendor. That text is the vendor's own. It usually means the hook could not be created or renewed — most often because your account lost admin rights on the project. Reconnect.

Deliveries arrive but nothing runs. The automation is paused, its event list does not include the event that fired, or a filter excluded it. The default Jira recipe only runs when a ticket carries the agent label — creating a ticket without that label will not start a run. Recent deliveries shows which event arrived.

Jira is connected but creating a ticket never shows a delivery. Disconnect and connect again, then pick the project (or the whole site) on the picker. Hosted Jira webhooks are JWTs signed with the OAuth app secret; an older connection that never received events needs that reconnect so the hook is registered against a real JQL filter.

Events stop after 30 days on Jira. Atlassian expires dynamically registered webhooks. The control plane renews them a week ahead on a daily schedule; if that stopped, reconnect and tell the operator.