npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hypnodroid/cursor-conversations

v2.4.1

Published

Library for accessing Cursor conversation data - conversations, messages, code diffs, checkpoints, and more

Readme

@redaphid/cursor-conversations

A library for programmatically accessing Cursor IDE's conversation database. Query conversations, messages, code diffs, file snapshots, and context data.

Installation

# From GitHub Packages
npm install @redaphid/cursor-conversations --registry=https://npm.pkg.github.com

# Or link locally for development
pnpm link /path/to/mcp-cursor-conversations

Quick Start

import {
  listConversations,
  listMessages,
  searchConversations
} from '@redaphid/cursor-conversations'

// List recent conversations
const { conversations } = await listConversations({ limit: 10 })

// Get messages from a conversation
const { messages } = await listMessages(conversations[0].conversationId)

// Search across all conversations
const results = await searchConversations('authentication', 20)

CLI

# After installing globally
cursor-conversations list --limit 5
cursor-conversations search "authentication"
cursor-conversations messages <conversationId> --limit 10
cursor-conversations export <conversationId> --format markdown

# All commands
cursor-conversations --help

Commands:

  • list - List conversations
  • get <id> - Get single conversation
  • search <query> - Search by text
  • search-advanced - Search with filters (date, message count, status)
  • export <id> - Export to markdown/json
  • messages <id> - List messages
  • message <id> <msgId> - Get single message
  • snapshots <id> - List snapshots
  • diffs <id> - List code diffs
  • contexts <id> - List contexts
  • stats - Database statistics

API Reference

Conversations

listConversations(options?)

List all conversations from the Cursor database.

const { conversations, total } = await listConversations({
  limit: 50,           // Max results (default: 50)
  offset: 0,           // Skip N results (default: 0)
  sortBy: 'recent_activity', // 'recent_activity' | 'created' | 'updated'
  sortOrder: 'desc'    // 'asc' | 'desc'
})

// Returns: { conversations: ConversationSummary[], total: number }

getConversation(conversationId, format?)

Get a single conversation by ID.

// Get summary
const summary = await getConversation('abc-123')

// Get full raw data
const full = await getConversation('abc-123', 'full')

searchConversations(query, limit?)

Search conversations by text content.

const results = await searchConversations('refactor database', 20)

// Returns array of matches with context:
// [{ conversationId, messageCount, preview, matches: [...] }]

searchConversationsAdvanced(options?)

Advanced search with filters.

const { conversations, totalFound } = await searchConversationsAdvanced({
  date_from: '2024-01-01',
  date_to: '2024-12-31',
  min_messages: 5,
  max_messages: 100,
  status: 'completed',  // 'completed' | 'aborted' | 'all'
  sort_by: 'date',      // 'date' | 'message_count' | 'status'
  sort_order: 'desc',
  limit: 20
})

exportConversation(conversationId, format?)

Export a conversation to a file.

// Export as markdown
const mdPath = await exportConversation('abc-123', 'markdown')

// Export as JSON
const jsonPath = await exportConversation('abc-123', 'json')

// Returns: '/tmp/cursor-conversation-abc-123.md'

Messages

listMessages(conversationId, options?)

List all messages in a conversation.

const { messages, count } = await listMessages('abc-123', { limit: 100 })

// Each message includes:
// { messageId, role, text, hasCodeBlocks, hasToolResults, isAgentic, tokenCount }

getMessage(conversationId, messageId)

Get a single message with full data.

const message = await getMessage('abc-123', 'msg-456')

// Returns full Message object with:
// { messageId, type, text, codeBlocks, toolResults, thinking, ... }

getMessageStats()

Get statistics about messages across all conversations.

const stats = await getMessageStats()

// { totalMessages, sampleSize, sampleBreakdown: { userMessages, assistantMessages, ... } }

Snapshots

File state snapshots captured during conversations.

listSnapshots(conversationId, options?)

const { snapshots } = await listSnapshots('abc-123', { limit: 50 })

// [{ snapshotId, fileCount, newFoldersCount, hasInlineDiffs }]

getSnapshot(conversationId, snapshotId)

const snapshot = await getSnapshot('abc-123', 'snap-789')

// { snapshotId, files, nonExistentFiles, newlyCreatedFolders, activeInlineDiffs }

Diffs

Code changes applied during conversations.

listDiffs(conversationId, options?)

const { diffs } = await listDiffs('abc-123', { limit: 50 })

// [{ diffId, changesCount, changes: [{ startLine, endLine, linesAdded, preview }] }]

getDiff(conversationId, diffId)

const diff = await getDiff('abc-123', 'diff-101')

// { diffId, changes: [{ original, modified }] }

Context

Context data captured when messages were sent (git status, project layout, etc.).

listContexts(conversationId, options?)

const { contexts } = await listContexts('abc-123', { limit: 50 })

// [{ contextId, hasGitStatus, gitStatusPreview, cursorRulesCount, todosCount, ... }]

getContext(conversationId, contextId)

const ctx = await getContext('abc-123', 'ctx-202')

// { contextId, gitStatus, cursorRules, todos, projectLayouts, terminalFiles, ... }

Database Utilities

getDatabaseStats()

Get overall database statistics.

const stats = await getDatabaseStats()

// {
//   summary: { conversations, messages, snapshots, diffs, contexts },
//   keyPatterns: { conversation: 685, message: 19542, ... },
//   description: { ... }
// }

Direct Database Access

For custom queries:

import { queryAll, queryOne, KEY_PATTERNS } from '@redaphid/cursor-conversations/core'

// Run custom SQL
const rows = queryAll<{ key: string }>(`
  SELECT key FROM cursorDiskKV
  WHERE key LIKE ?
  LIMIT 10
`, [`${KEY_PATTERNS.MESSAGE}%`])

// Get single row
const row = queryOne<{ value: string }>(`
  SELECT value FROM cursorDiskKV WHERE key = ?
`, ['composerData:abc-123'])

Types

import type {
  // Conversations
  ConversationSummary,
  ConversationData,

  // Messages
  Message,
  MessageSummary,
  MessageRole,  // 'user' | 'assistant'

  // Snapshots
  Snapshot,

  // Diffs
  CodeDiff,

  // Context
  MessageContext,
} from '@redaphid/cursor-conversations'

Configuration

By default, the library reads from Cursor's default database location:

  • macOS: ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
  • Windows: %APPDATA%\Cursor\User\globalStorage\state.vscdb
  • Linux: ~/.config/Cursor/User/globalStorage/state.vscdb

Programmatic Configuration

import { setDatabasePath, resetDatabasePath } from '@redaphid/cursor-conversations'

// Set a custom database path
setDatabasePath('/path/to/state.vscdb')

// All subsequent calls will use this path
const { conversations } = await listConversations()

// Reset to default behavior
resetDatabasePath()

Environment Variable

CURSOR_DB_PATH=/path/to/state.vscdb node your-script.js

Priority order: setDatabasePath() > CURSOR_DB_PATH env var > platform default


MCP Server

This package also includes an MCP server for use with Claude Code. See MCP Setup for details.


License

MIT