Cursor/sdk — getTeamRepos network call on every tool run causes ETIMEDOUT + STOPPED tools (local agent)

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

I’m using @cursor/sdk for local agents (via a long-running Node host — Traycer harness issue for context).

Before Read/Grep/Shell tools run, the SDK seems to call the dashboard API to check team repo blocklist (getTeamReposOrEmptyIfNotInTeam → checkRepoBlocked). When that call times out (read ETIMEDOUT), it throws as an unhandled promise rejection and tools show STOPPED. After that, more tools in the same agent run fail immediately — retrying or waiting a bit often works on the next message.

On @cursor/sdk 1.0.23. Same machine, Cursor IDE agent tools feel fine.

I dug into IDE logs on the same laptop: getTeamRepos shows up on a ~5 min background timer (pollRepoBlocklist), not before each tool. When the IDE does call it, I get a fast response like “Team repo blocklist feature is not enabled for this team” — tools keep working. The SDK path looks like it hits the network on the tool hot path instead.

Steps to Reproduce

  1. Use @cursor/sdk local agent with an API key (Agent.create or local executor), e.g.:
await Agent.create({
  apiKey: process.env.CURSOR_API_KEY,
  model: { id: "composer-2.5" },
  local: { cwd: "/path/to/git/repo" },
});

Send a prompt that triggers Read, Grep, or Shell tools.
Under flaky network (or when api.cursor.com is slow), tools intermittently show STOPPED.
Host log shows:

ConnectError: [unknown] [unavailable] read ETIMEDOUT
  at getTeamReposOrEmptyIfNotInTeam
  at checkRepoBlocked
  at shouldBlockRead / shouldEnforceShellInvariantBlocks
[host] unhandledRejection

More tools in the same run fail fast until a new message/run starts.

Expected Behavior

  • Transient getTeamRepos failures should not break tools (fail open when blocklist can’t be fetched).
  • Errors should be catchable by the host, not unhandled rejections.
  • Ideally: background fetch + local cache for blocklist checks (like IDE pollRepoBlocklist), not a live network call before every tool.

Operating System

MacOS

Version Information

@cursor/sdk: 1.0.23
Node.js: 22.x
Cursor IDE (same machine, for comparison): 3.11.19
Agent type: local (not cloud)
Auth: dashboard user API key via CURSOR_API_KEY

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey, thanks for the detailed report. The breakdown with logs and the comparison to the IDE behavior helped a lot.

Confirmed, this is a bug on our side in @cursor/sdk. The repo blocklist check before running tools fails closed on a transient ETIMEDOUT instead of failing open, and it can get stuck in that state for a while. That’s why you see a cascade of tools going into STOPPED, which clears after a retry or a new message. Your analysis is spot on. Fail open, catchable errors, and a background poll or cache like the IDE pollRepoBlocklist.

I’ve reported it internally. I can’t share an ETA for the fix yet.

For now, the only workaround is what you already found. Starting a new run or sending a new message resets the stuck state. Keeping a stable connection to api.cursor.com, without flaky VPN or proxy, reduces how often the timeouts happen. I’ll post an update in the thread once we have one.