[Cursor](https://www.cursor.com/) is an AI-powered code editor designed to boost productivity by automating repetitive coding tasks. When paired with Prisma, a robust and type-safe toolkit for database workflows, it becomes a powerful solution for managing and optimizing database schemas, queries, and data seeding.

This guide provides detailed instructions for effectively using Prisma with Cursor to:

- Define project-specific best practices with `.cursorrules`.
- Using Cursor's context-aware capabilities.
- Generate schemas, queries, and seed data tailored to your database.

:::note

While this guide is focused on Cursor, these patterns should work with any AI editor. [Let us know on X](https://pris.ly/x?utm_source=docs&utm_medium=inline_text) if you'd like us to create guides for your preferred tool!

:::

## Prisma MCP server

Prisma provides its own [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server that lets you manage Prisma Postgres databases, model database schemas and chat through migrations. Learn more about how you can add it to Cursor [here](/postgres/integrations/mcp-server#cursor). You can also add the Prisma MCP server to Cursor using the [one-click installation](https://docs.cursor.com/context/model-context-protocol#one-click-installation) by clicking on the following link:

<a href="https://pris.ly/cursor-prisma-mcp-web" target="_blank" rel="noopener noreferrer" aria-label="Install Prisma MCP server in Cursor">
  <img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Install MCP Server" />
</a>

This will prompt you to open the Cursor app in your browser. Once opened, you'll be guided to install the Prisma MCP server directly into your Cursor configuration.

## Defining project-specific rules with `.cursorrules`

The [`.cursorrules` file](https://docs.cursor.com/context/rules-for-ai#cursorrules) in Cursor allows you to enforce best practices and development standards tailored to your Prisma projects. By defining clear and consistent rules, you can ensure that Cursor generates clean, maintainable, and project-specific code with minimal manual adjustments.

To implement these rules, create a `.cursorrules` file in the root of your project. Below is an example configuration:

<details>
<summary>
 Example `.cursorrules` file
</summary>

```text file=.cursorrules
You are a senior TypeScript/JavaScript programmer with expertise in Prisma, clean code principles, and modern backend development.
Generate code, corrections, and refactorings that comply with the following guidelines:
TypeScript General Guidelines
Basic Principles
- Use English for all code and documentation.
- Always declare explicit types for variables and functions.
  - Avoid using "any".
  - Create precise, descriptive types.
- Use JSDoc to document public classes and methods.
- Maintain a single export per file.
- Write self-documenting, intention-revealing code.
Nomenclature
- Use PascalCase for classes and interfaces.
- Use camelCase for variables, functions, methods.
- Use kebab-case for file and directory names.
- Use UPPERCASE for environment variables and constants.
- Start function names with a verb.
- Use verb-based names for boolean variables:
  - isLoading, hasError, canDelete
- Use complete words, avoiding unnecessary abbreviations.
  - Exceptions: standard abbreviations like API, URL
  - Accepted short forms: 
    - i, j for loop indices
    - err for errors
    - ctx for contexts
Functions
- Write concise, single-purpose functions.
  - Aim for less than 20 lines of code.
- Name functions descriptively with a verb.
- Minimize function complexity:
  - Use early returns.
  - Extract complex logic to utility functions.
- Leverage functional programming techniques:
  - Prefer map, filter, reduce.
  - Use arrow functions for simple operations.
  - Use named functions for complex logic.
- Use object parameters for multiple arguments.
- Maintain a single level of abstraction.
Data Handling
- Encapsulate data in composite types.
- Prefer immutability.
  - Use readonly for unchanging data.
  - Use as const for literal values.
- Validate data at the boundaries.
Error Handling
- Use specific, descriptive error types.
- Provide context in error messages.
- Use global error handling where appropriate.
- Log errors with sufficient context.
Prisma-Specific Guidelines
Schema Design
- Use meaningful, domain-driven model names.
- Leverage Prisma schema features:
  - Use @id for primary keys.
  - Use @unique for natural unique identifiers.
  - Utilize @relation for explicit relationship definitions.
- Keep schemas normalized and DRY.
- Use meaningful field names and types.
- Implement soft delete with deletedAt timestamp.
- Use Prisma's native type decorators.
Prisma Client Usage
- Always use type-safe Prisma client operations.
- Prefer transactions for complex, multi-step operations.
- Handle optional relations explicitly.
- Use Prisma's filtering and pagination capabilities.
Database Migrations
- Create migrations for schema changes.
- Use descriptive migration names.
- Review migrations before applying.
- Never modify existing migrations.
- Keep migrations idempotent.
Error Handling with Prisma
- Catch and handle Prisma-specific errors:
  - PrismaClientKnownRequestError
  - PrismaClientUnknownRequestError
  - PrismaClientValidationError
- Provide user-friendly error messages.
- Log detailed error information for debugging.
Testing Prisma Code
- Use in-memory database for unit tests.
- Mock Prisma client for isolated testing.
- Test different scenarios:
  - Successful operations
  - Error cases
  - Edge conditions
- Use factory methods for test data generation.
- Implement integration tests with actual database.
Performance Considerations
- Use select and include judiciously.
- Avoid N+1 query problems.
- Use findMany with take and skip for pagination.
- Leverage Prisma's distinct for unique results.
- Profile and optimize database queries.
Security Best Practices
- Never expose raw Prisma client in APIs.
- Use input validation before database operations.
- Implement row-level security.
- Sanitize and validate all user inputs.
- Use Prisma's built-in protections against SQL injection.
Coding Style
- Keep Prisma-related code in dedicated repositories/modules.
- Separate data access logic from business logic.
- Create repository patterns for complex queries.
- Use dependency injection for Prisma services.
Code Quality
- Follow SOLID principles.
- Prefer composition over inheritance.
- Write clean, readable, and maintainable code.
- Continuously refactor and improve code structure.
Development Workflow
- Use version control (Git).
- Implement comprehensive test coverage.
- Use continuous integration.
- Perform regular code reviews.
- Keep dependencies up to date.
```

</details>

This file ensures consistent and maintainable code generation, reducing manual intervention while improving project quality.

## Using Cursor's context-aware capabilities

Cursor's [context-aware](https://docs.cursor.com/context/) capabilities let you add specific websites, files, folders or documentation to enhance its understanding of your project. By adding your `schema.prisma` file as context, you enable Cursor to generate more accurate queries, tests, and seed data based on your database schema.

### Add Prisma docs `llm.txt` file as `@Docs` context

To improve Cursor's understanding of Prisma-related suggestions in your project, include the [`/llms.txt`](https://llmstxt.org/) markdown file as context. This file offers a concise overview, useful guidance, and links to detailed Prisma documentation—all optimized for LLM processing. Simply navigate to the [url](https://pris.ly/llms.txt) and add it as a `@Docs` resource in your Cursor configuration.

### Adding additional Prisma documentation

Cursor already includes built-in context from Prisma documentation, so you don't need to add anything to make us of our docs! 

To stay updated with the latest changes or incorporate additional context, add these resources as `@Docs` context:

- [Prisma Changelog](https://www.prisma.io/changelog) for updates and new features.
- [Prisma Blog](https://www.prisma.io/blog) for practical guides and best practices.

To learn how to add and manage documentation context, visit the [Cursor documentation](https://docs.cursor.com/context/@-symbols/@-docs#docs).

### Using schema as context

Add your `schema.prisma` file (or the entire codebase) as context using the [`@Files`](https://docs.cursor.com/context/@-symbols/@-files) syntax before requesting queries, tests, or seed scripts. This allows Cursor to generate precise, schema-driven outputs such as queries, tests, and seed data. For example, in [Cursor Chat](https://docs.cursor.com/chat/overview), you can include your schema by typing `@Files` followed by adding your `schema.prisma` file.

## Generating Prisma Schema

Cursor can generate Prisma schemas from high-level descriptions, enabling you to quickly establish a solid foundation for your database schema. By providing a clear and detailed prompt, Cursor creates Prisma schemas tailored to your requirements. Whether you need a general foundational schema or a highly specific one for detailed use cases, Cursor can deliver with precision. Here's an example prompt and its corresponding result:

:::note
If you run the prompts below, you may receive a different outputs because LLMs produce non-deterministic responses.
:::

<TabbedContent code>

<TabItem value="Prompt to generate Prisma schema">

```text copy
"Create a Prisma schema for a SaaS app using PostgreSQL as a provider with `User`, `Organization`, and `Subscription` models, ensuring all models include `createdAt` and `updatedAt` DateTime fields with defaults, a soft-delete `deletedAt` field, and proper relationships between entities."
```

</TabItem>
<TabItem value="Result">
```prisma file=schema.prisma
generator client {
  provider = "prisma-client"
  output   = "./generated"
}

datasource db {
  provider = "postgresql"
}


model User {
  id            Int           @id @default(autoincrement())
  email         String        @unique
  name          String
  password      String
  createdAt     DateTime      @default(now())
  updatedAt     DateTime      @updatedAt
  deletedAt     DateTime?
  organization  Organization  @relation(fields: [organizationId], references: [id])
  organizationId Int
  role          UserRole     @default(MEMBER)
}


model Organization {
  id            Int           @id @default(autoincrement())
  name          String
  slug          String        @unique
  subscription  Subscription?
  users         User[]
  createdAt     DateTime      @default(now())
  updatedAt     DateTime      @updatedAt
  deletedAt     DateTime?
}

model Subscription {
  id              Int           @id @default(autoincrement())
  organization    Organization  @relation(fields: [organizationId], references: [id])
  organizationId  Int          @unique
  plan           SubscriptionPlan
  status         SubscriptionStatus @default(ACTIVE)
  startDate      DateTime
  endDate        DateTime?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  deletedAt      DateTime?
}

enum UserRole {
  ADMIN
  MEMBER
}

enum SubscriptionPlan {
  FREE
  BASIC
  PREMIUM
  ENTERPRISE
}

enum SubscriptionStatus {
  ACTIVE
  CANCELED
  EXPIRED
  PAST_DUE
}
```

</TabItem>
</TabbedContent>

## Generating Prisma queries

Cursor can help you create queries tailored to your Prisma schema, whether for basic data retrieval or complex, optimized operations. To get the best results, focus on writing clear, specific prompts that define your requirements, such as the fields to include, conditions to apply, and relationships to traverse. This ensures Cursor generates accurate, performant, and type-safe queries. Here's an example prompt and its resulting query:

<TabbedContent code>
<TabItem value="Prompt to generate a database query">

```text copy
"Generate a query to retrieve all User records associated with an Organization that has an `active` Subscription, while excluding any records where the deletedAt field is set."
```

</TabItem>

<TabItem value="Result">

```typescript
const activeUsers = await prisma.user.findMany({
  where: {
    deletedAt: null,
    organization: {
      deletedAt: null,
      subscription: {
        deletedAt: null,
        status: 'ACTIVE'
      }
    }
  },
  include: {
    organization: {
      include: {
        subscription: true
      }
    }
  },
  orderBy: {
    createdAt: 'desc'
  },
  skip: 0,
  take: 10
});
```

</TabItem>
</TabbedContent>

## Creating seed files with Cursor

Writing seed scripts can be a tedious process, but Cursor simplifies it by quickly generating structured and organized seed code. By providing clear instructions, you can guide Cursor to create scripts that populate your database with realistic data, including handling relationships and complex structures defined in your schema. Here's an example prompt and its resulting seed script:

<TabbedContent code>
<TabItem value="Prompt to seed the database">

```text copy
"Generate code to populate the Prisma schema with realistic data for the User, Organization, and Subscription models, ensuring all necessary fields are included."
```

</TabItem>
<TabItem value="Result">

```ts file=seed.ts
import {
  PrismaClient,
  UserRole,
  SubscriptionPlan,
  SubscriptionStatus,
} from "../prisma/generated/client";

const prisma = new PrismaClient();

async function main() {
  // Clear existing data
  await prisma.user.deleteMany();
  await prisma.subscription.deleteMany();
  await prisma.organization.deleteMany();

  const organizations = [
    {
      name: "Tech Innovators",
      slug: "tech-innovators",
      subscription: {
        plan: SubscriptionPlan.ENTERPRISE,
        status: SubscriptionStatus.ACTIVE,
        startDate: new Date("2024-01-01"),
      },
      users: [
        {
          name: "Emma Thompson",
          email: "emma@techinnovators.com",
          role: UserRole.ADMIN,
          password: "password123",
        },
        {
          name: "Michael Chen",
          email: "michael@techinnovators.com",
          role: UserRole.MEMBER,
          password: "password123",
        },
      ],
    },
    {
      name: "Digital Solutions",
      slug: "digital-solutions",
      subscription: {
        plan: SubscriptionPlan.PREMIUM,
        status: SubscriptionStatus.ACTIVE,
        startDate: new Date("2024-01-15"),
      },
      users: [
        {
          name: "Sarah Wilson",
          email: "sarah@digitalsolutions.com",
          role: UserRole.ADMIN,
          password: "password123",
        },
        {
          name: "James Miller",
          email: "james@digitalsolutions.com",
          role: UserRole.MEMBER,
          password: "password123",
        },
      ],
    },
    {
      name: "Cloud Systems",
      slug: "cloud-systems",
      subscription: {
        plan: SubscriptionPlan.BASIC,
        status: SubscriptionStatus.ACTIVE,
        startDate: new Date("2024-02-01"),
      },
      users: [
        {
          name: "David Garcia",
          email: "david@cloudsystems.com",
          role: UserRole.ADMIN,
          password: "password123",
        },
        {
          name: "Lisa Wang",
          email: "lisa@cloudsystems.com",
          role: UserRole.MEMBER,
          password: "password123",
        },
      ],
    },
    {
      name: "Data Analytics Co",
      slug: "data-analytics",
      subscription: {
        plan: SubscriptionPlan.PREMIUM,
        status: SubscriptionStatus.ACTIVE,
        startDate: new Date("2024-01-10"),
      },
      users: [
        {
          name: "Alex Johnson",
          email: "alex@dataanalytics.com",
          role: UserRole.ADMIN,
          password: "password123",
        },
        {
          name: "Rachel Kim",
          email: "rachel@dataanalytics.com",
          role: UserRole.MEMBER,
          password: "password123",
        },
      ],
    },
    {
      name: "Smart Solutions",
      slug: "smart-solutions",
      subscription: {
        plan: SubscriptionPlan.FREE,
        status: SubscriptionStatus.ACTIVE,
        startDate: new Date("2024-02-15"),
      },
      users: [
        {
          name: "Daniel Brown",
          email: "daniel@smartsolutions.com",
          role: UserRole.ADMIN,
          password: "password123",
        },
        {
          name: "Maria Rodriguez",
          email: "maria@smartsolutions.com",
          role: UserRole.MEMBER,
          password: "password123",
        },
      ],
    },
  ];

  for (const org of organizations) {
    const createdOrg = await prisma.organization.create({
      data: {
        name: org.name,
        slug: org.slug,
        subscription: {
          create: {
            plan: org.subscription.plan,
            status: org.subscription.status,
            startDate: org.subscription.startDate,
          },
        },
      },
    });

    for (const user of org.users) {
      await prisma.user.create({
        data: {
          name: user.name,
          email: user.email,
          password: user.password,
          role: user.role,
          organizationId: createdOrg.id,
        },
      });
    }
  }

  console.log("Seed data created successfully");
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
```
</TabItem>
</TabbedContent>

## Using the Prisma VS Code extension to manage your database

The [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) is a powerful tool for building applications with [Prisma Postgres](/postgres). You can also use it in Cursor by installing the extension. It provides a dedicated UI for managing Prisma Postgres instances, both local and remote, making it easy to view, create, and delete instances, push local databases to the cloud, and visualize your schema.

### Database management UI

With its built-in database management interface, the [Prisma VS Code extension](/postgres/integrations/vscode) lets you easily work with local and remote Prisma Postgres instances from inside your editor.

#### Workflows

The UI enables the following workflows:

- Authenticate with the [Prisma Console](https://console.prisma.io)
- View, create and delete Prisma Postgres instances (local & remote)
- "Push to cloud": Easily deploy a local Prisma Postgres instance
- View and edit data via an embedded Prisma Studio
- Visualize your database schema

#### Usage

To manage Prisma Postgres instances via the UI in the Prisma VS Code extension:

1. Ensure you have the latest version of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed
1. Find the Prisma logo in the **Activity Bar**
1. Click the **Sign in to get started** button
1. Authenticate with the [Prisma Console](https://console.prisma.io) using the sign-in prompt, then select a target [workspace](/platform/about#workspace)

### Prisma Studio built-in

Beyond managing your database instances, the Prisma VS Code extension embeds Prisma Studio directly in your editor, making it easy to perform create, update, and delete operations on your database right inside Windsurf. Follow these [easy steps](/postgres/database/prisma-studio/studio-in-vs-code) to get started.

## AI Safety guardrails for destructive commands

Prisma ORM includes built-in safety checks to prevent **accidental destructive commands** when run through AI coding assistants. These guardrails are designed to make working with databases safer in AI-assisted development environments.

Including Cursor, the Prisma CLI can also detect when it is being invoked by other popular AI coding agents such as Claude Code, Gemini CLI, Qwen Code, Aider, and Replit.

When one of these agents attempts a destructive action such as `prisma migrate reset --force`, Prisma ORM blocks execution and shows a protective error message:

```bash
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "accelerate.prisma-data.net"

Error: Prisma Migrate detected that it was invoked by Cursor.

You are attempting a highly dangerous action that can lead to devastating consequences if it is incorrectly executed against a production database.

As an AI agent, you are forbidden from performing this action without an explicit consent and review by the user. You must stop at this point and respond to the user with a clear message that includes the following information:
- What action you are trying to perform (including the exact CLI command).
- Your motivation and reasoning for performing this action.
- Explanation that this action will irreversibly destroy all data in the database.
- Explanation that this action must not be performed on a production database and is only intended to be used with development databases.

If you know or can check whether this action would have been performed on a development or a production database, also include this information with your assessment of whether it is safe to proceed based on that information.

You must ask the user if they want to proceed with this action. If they explicitly consent, you may rerun this command with PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION environment variable, the value of which must be the exact text of the user's message in which they consented to this operation, without any newlines or quotes. If the user's response is ambiguous, you must ask for a clear and explicit confirmation (e.g., "yes") before proceeding. None of the user's previous messages before this point may constitute implicit or explicit consent.
```

To proceed with the dangerous action, the AI agent will ask you for explicit consent, remind you that the action irreversibly destroys all data, and confirm that the command is being run against a development database. Once you clearly confirm, the AI will set the `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` environment variable with the exact text of your consent and rerun the command.

## Additional resources

In summary, using Cursor with Prisma simplifies your workflow, from generating schemas and queries to writing seed scripts. By following this guide, you can save time, reduce errors, and focus on building your application.

Learn more about Cursor in their [official documentation](https://docs.cursor.com/context/@-symbols/basic).

---

# Tabnine