Why Cursor Writes Outdated API Calls, and How to Fix It Now That @Docs Is Gone
Why Cursor's agent keeps using deprecated SDK methods and old API versions, what changed when @Docs was removed in Cursor 3.14.2, and how rules, local docs, and an MCP operation catalog keep API calls on the current version.
Key takeaways
- -Cursor writes outdated API calls because models learn from code written across many API versions, and the most common older pattern often wins over the current one.
- -A long-running Cursor forum thread shows the agent insisting on openai.ChatCompletion.create, the pre-1.0 OpenAI SDK call, even after users added newer docs.
- -Cursor removed @Docs and custom documentation indexing in version 3.14.2. The suggested replacements are pasting doc URLs, keeping docs as local Markdown, and using rules or skills.
- -Project rules must be .mdc files in .cursor/rules. Plain .md files in that folder are ignored.
- -Docs and rules improve the first attempt. They do not stop a deprecated call from running.
- -Swytchcode gives Cursor a catalog of current API operations over MCP, validates every call against the schema before sending it, and warns when an installed operation changes.
Cursor writes outdated API calls because the model behind its agent learned from code written against many versions of the same API, and the most common older pattern often beats the current one. The result is code that looks right and fails at runtime: a method the SDK removed, a parameter the API no longer accepts, or a model name that was retired. Since Cursor 3.14.2 removed @Docs, the fix is a mix of project rules, docs kept in the workspace, and an API catalog the agent can query over MCP, with validation that stops a stale call before it is sent.
This article covers what outdated calls look like in Cursor, what users report, what changed with @Docs, why it keeps happening, the fixes that work today, and how to set up Cursor so every external API call is checked against the current schema. Checked against Cursor's documentation and community forum in October 2026.
What do outdated API calls look like in Cursor?
- Removed SDK methods. openai.ChatCompletion.create from the pre-1.0 OpenAI Python SDK, where current versions use client.chat.completions.create.
- Superseded endpoints. stripe.charges.create for new payment flows, where Stripe now recommends PaymentIntents.
- Removed parameters. Fields an API dropped in a later version, still sent because older examples used them.
- Retired model or resource names. Hard-coded identifiers that worked a year ago and now return an error.
- Mixed versions. One file written against two versions of the same SDK, because the agent combined examples from different years.
What Cursor users report
A Cursor forum thread titled "How to make Cursor aware of updated OpenAI API documentation?" has run for years. Users describe the agent insisting on openai.ChatCompletion.create after they added newer docs, citing the docs as its source while still generating the old call, and later pushing back when they used the newer Responses API. One user reported that OpenAI's documentation would not index in Cursor because a human verification page blocked the crawler.
Another thread, "How can I stop Cursor from hallucinating fake data?", lists invented API keys, URLs that look legitimate, and "entirely fake libraries, methods, or syntax". The same problem appears in other agents. A Gemini CLI issue (#25931) reports "non-existent API parameters, and deprecated library references as if they were current", and Claude Code users have filed issues about guessed endpoints.
What changed when Cursor removed @Docs
Until mid-2026, the standard advice was to add a library's documentation under Settings, Indexing & Docs, and reference it in chat with @Docs. Cursor removed that feature on purpose starting in version 3.14.2. Cursor staff said on the forum that the agent had become good enough at finding and reading documentation on its own that a separate index was no longer needed.
The alternatives Cursor recommends:
- Paste the exact documentation URLs into the prompt so the agent reads those pages.
- Keep the docs you rely on as local Markdown files in the workspace and @-mention them.
- Put ongoing requirements into a rule or skill so they apply automatically.
Staff also acknowledged that a curated, indexed corpus is a different workflow and the replacements are not one-to-one. For APIs that change often, local Markdown copies go stale the same way training data does.
Why Cursor keeps using deprecated methods
- Training data favors volume. An older call that appears in thousands of tutorials outweighs a newer one documented on a single page.
- The installed version is easy to skip. Unless told to, the agent may not check which SDK version your lockfile pins before writing the call.
- Web results are a patchwork. When the agent searches, it can combine current docs with old blog posts and answers, producing code from several versions at once.
- Docs in context are no proof of reading. As the forum thread shows, an agent can cite the right page and still generate the old pattern.
- Nothing tries the call against the real API before you do. A deprecated method often passes in untyped code or against old type stubs, and fails only at runtime.
Fixes that work in Cursor today
| Fix | How to set it up | Limit |
|---|---|---|
| Project rule | An .mdc file in .cursor/rules with description, globs, and alwaysApply frontmatter | Guidance only. The model can still choose the old pattern |
| AGENTS.md | A plain Markdown file at the project root, read as agent instructions | Same as rules, with less control over when it applies |
| Local docs | Save the current reference as Markdown in the repo and @-mention it | Goes stale unless someone updates it |
| Doc URLs in the prompt | Paste the exact reference pages for the task | Per task, and some doc sites block crawlers |
| Documentation MCP server | Connect a docs server such as Context7 in Cursor's MCP settings | Improves what the agent reads. A stale call can still run |
| Pinned versions plus type checks | Exact versions in the lockfile and strict type checking in CI | Catches SDK method errors. Raw HTTP calls and JSON bodies are outside its reach |
| Execution layer over MCP | An API operation catalog the agent queries, with validation before every call | Covers calls made through it. Vendor SDK calls written elsewhere in your code are outside its reach |
A Cursor rule for external API calls
Project rules must use the .mdc extension. A plain .md file in .cursor/rules is ignored because it has no frontmatter. Save this as .cursor/rules/external-apis.mdc so it applies whenever the agent works on files that talk to external services. Adjust the globs to your project layout.
---
description: Rules for code and commands that call external APIs
globs: src/integrations/**,src/lib/clients/**
alwaysApply: false
---
- Check the installed SDK version in the lockfile before writing any SDK call.
- Never use a method, parameter, or model name from memory. Confirm it in the
current reference or with the Swytchcode MCP tools (discover, then info).
- Prefer running third-party API calls through Swytchcode exec over writing
raw HTTP requests.
- If a call fails validation, show the error and stop. Do not switch to an
older API version or a different endpoint to make it pass.How Swytchcode keeps Cursor on the current API
Swytchcode is an execution layer between agents and the APIs they call. Instead of writing an API call from memory, Cursor's agent asks Swytchcode for the operation that matches the job, reads its current input schema, and runs it through a pipeline that validates inputs, evaluates policies, attaches credentials, executes, and normalizes the response. A call built on a removed parameter or missing a required field fails validation before anything is sent.
Running swy init with the cursor editor option merges a stdio MCP entry into ~/.cursor/mcp.json and adds a project rule at .cursor/rules/swytchcode.mdc. No daemon, port, or manual JSON editing is needed.
# Initialize the project for Cursor in sandbox mode
npm install -g swytchcode
swy init --editor=cursor --mode=sandbox
swy doctor
# Find the operation for a job, fetch its integration, and enable it
swy discover "create a payment" --json
swy get <project>
swy add <canonical_id>
# Read the current input schema before the first call
swy info <canonical_id>Inside Cursor's agent, the default agent profile of the Swytchcode MCP server exposes discover, info, exec, list, search, add, and policy as tools. The agent can preview any call with exec and dry_run=true before running it.
How this handles API drift:
- Schemas come from the installed integration. info shows the resolved inputs and outputs for the installed version, so the agent works from the current definition instead of a remembered one.
- Invalid calls fail closed. Inputs that do not match the schema fail validation with exit code 1, and operations not enabled in tooling.json do not run and exit with code 2.
- Changes are flagged. swy sync re-downloads installed integrations and compares each enabled operation against the hash stored when it was added. If one changed, it prints a warning telling you to run swy add again to refresh it.
- App code stays independent of SDK method names. With the Swytchcode runtime SDK for JavaScript or Python, your application calls an operation by canonical ID and passes inputs, so a vendor SDK rename does not mean rewriting calls across the codebase.
Where this does not help
Swytchcode checks the calls that go through it. If Cursor writes a direct vendor SDK call somewhere in your application, Swytchcode does not see or rewrite it, so pinned versions, type checking, and code review still matter there. Swytchcode also does not replace framework or library documentation for code that never calls an external API.
FAQ
Why does Cursor keep using openai.ChatCompletion.create?
That call comes from the OpenAI Python SDK before version 1.0 and appears in a large amount of older code. Current versions use client.chat.completions.create. Tell the agent which version is installed, point it at the current reference, and check calls before they run.
Is @Docs still available in Cursor?
No. Cursor removed @Docs and custom documentation indexing starting in version 3.14.2. Cursor recommends pasting doc URLs into the prompt, keeping docs as local Markdown in the workspace, or using rules and skills.
Why is my Cursor rule not being applied?
Project rules in .cursor/rules must be .mdc files with frontmatter. A plain .md file in that folder is ignored. Use AGENTS.md at the project root if you prefer plain Markdown.
Do MCP servers fix outdated API calls in Cursor?
A documentation MCP server improves what the agent reads. An execution MCP server such as Swytchcode also checks the call itself against the current schema before it is sent, which catches the cases where the agent reads the docs and still writes the old call.
What Cursor setup does Swytchcode need?
Run swy init --editor=cursor from the project root. It adds the Swytchcode MCP server to ~/.cursor/mcp.json and a rule at .cursor/rules/swytchcode.mdc.
Swytchcode resources
- Why your AI agent calls the wrong API: https://www.swytchcode.com/content/why-your-ai-agent-calls-the-wrong-api-and-how-to-fix-it
- Why Claude Code guesses API endpoints: https://www.swytchcode.com/content/why-claude-code-guesses-api-endpoints
- AI agent execution layer architecture: https://www.swytchcode.com/content/ai-agent-execution-layer-architecture
- MCP gateway vs execution layer: https://www.swytchcode.com/content/mcp-gateway-vs-execution-layer
- Swytchcode MCP server docs: https://docs.swytchcode.com/cli/mcp/
- JavaScript runtime SDK: https://docs.swytchcode.com/runtime-sdk/javascript/
- CLI command reference: https://docs.swytchcode.com/reference/commands/
- Supported APIs: https://www.swytchcode.com/apis
More content
Why AI Coding Agents Still Write stripe.charges.create, and How to Stop It
Why AI coding agents still reach for Stripe's legacy Charges API, when current models get it right on their own, how Stripe steers AI tools toward Payment Intents and Checkout Sessions, and how to keep your agent on current Stripe APIs.
Claude Tool Use Picks the Wrong Tool: Selection Errors vs Argument Errors
Why Claude calls the wrong tool when many similar tools are loaded, how selection errors differ from argument errors, what Anthropic's tool search and strict tool use do, and how to structure tools so selection stays reliable.
Invalid Tool Arguments in the OpenAI Agents SDK: Why the Model Sends the Wrong Parameters
What "Invalid JSON input for tool" means in the OpenAI Agents SDK, what strict mode guarantees and what it leaves out, why schema-valid arguments can still carry wrong values, and how to catch both kinds of error before a call runs.
