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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ceris/opencode-graphiti

v0.1.0

Published

OpenCode plugin for persistent memory using Graphiti MCP server

Readme

@ceris/opencode-graphiti

OpenCode plugin for persistent memory using Graphiti MCP server.

Your agent remembers what you tell it - across sessions, across projects.

Installation

For Humans

bunx @ceris/opencode-graphiti@latest install

Then set your Graphiti server URL and user ID:

export GRAPHITI_URL="http://your-graphiti-server:8000/mcp/"
export GRAPHITI_USER_ID="your-user-id"

Or use explicit group ID:

export GRAPHITI_URL="http://your-graphiti-server:8000/mcp/"
export GRAPHITI_GROUP_ID="your-group-id"

Or let your agent do it - paste this into OpenCode:

Install @ceris/opencode-graphiti by following https://raw.githubusercontent.com/artemfomin/opencode-graphiti/main/README.md

For LLM Agents

If you're an LLM agent helping set up @ceris/opencode-graphiti, follow these steps:

Step 1: Run the installer

bunx @ceris/opencode-graphiti@latest install --no-tui

This will:

  • Register the plugin in ~/.config/opencode/opencode.jsonc
  • Create the /graphiti-init command

Step 2: Verify the config

cat ~/.config/opencode/opencode.jsonc

Should contain:

{
  "plugin": ["@ceris/opencode-graphiti"]
}

If not, add it manually:

JSONC:

{
  "plugin": [
    "@ceris/opencode-graphiti"
    // ... other plugins
  ]
}

JSON:

{
  "plugin": ["@ceris/opencode-graphiti"]
}

Step 3: Configure Graphiti connection

Set required environment variables:

export GRAPHITI_URL="http://your-graphiti-server:8000/mcp/"
export GRAPHITI_USER_ID="your-user-id"

Or create ~/.config/opencode/graphiti.jsonc:

{
  "graphitiUrl": "http://localhost:8000/mcp/",
  "userId": "your-user-id"
}

Step 4: Verify setup

Tell the user to restart OpenCode and run:

opencode -c

They should see graphiti in the tools list. If not, check:

  1. Is GRAPHITI_URL and (GRAPHITI_USER_ID or GRAPHITI_GROUP_ID) set?
  2. Is the plugin in opencode.jsonc?
  3. Check logs: tail ~/.@ceris/opencode-graphiti.log

Step 5: Initialize codebase memory (optional)

Run /graphiti-init to have the agent explore and memorize the codebase.

Features

Context Injection

On first message, the agent receives (invisible to user):

  • User profile (cross-project preferences)
  • Project memories (all project knowledge)
  • Relevant memories (semantic search)

Example of what the agent sees:

[GRAPHITI]

User Profile:
- Prefers concise responses
- Expert in TypeScript

Project Knowledge:
- Uses Bun, not Node.js
- Build: bun run build

Relevant Memories:
- Build fails if .env.local missing

The agent uses this context automatically - no manual prompting needed.

Keyword Detection

Say "remember", "save this", "don't forget" etc. and the agent auto-saves to memory.

You: "Remember that this project uses bun"
Agent: [saves to project memory]

Add custom triggers via keywordPatterns config.

Codebase Indexing

Run /graphiti-init to explore and memorize your codebase structure, patterns, and conventions.

Preemptive Compaction

When context hits 80% capacity:

  1. Triggers OpenCode's summarization
  2. Injects project memories into summary context
  3. Saves session summary as a memory

This preserves conversation context across compaction events.

Privacy

API key is <private>sk-abc123</private>

Content in <private> tags is never stored.

Tool Usage

The graphiti tool is available to the agent:

| Mode | Args | Description | |------|------|-------------| | add | content, type?, scope? | Store memory | | search | query, scope? | Search memories | | profile | query? | View user profile | | list | scope?, limit? | List memories | | forget | memoryId, scope? | Delete memory | | help | - | Show help text |

Examples:

// Add a project memory
graphiti({ mode: "add", content: "This project uses Bun", type: "project-config" })

// Search memories
graphiti({ mode: "search", query: "build command" })

// List memories
graphiti({ mode: "list", limit: 10 })

Scopes: user (cross-project), project (default)

Types: project-config, architecture, error-solution, preference, learned-pattern, conversation

Memory Scoping

| Scope | Namespace | Persists | |-------|-----------|----------| | User | {userId} or {groupId}_profile | All projects | | Project | {groupId}_{hash} | This project |

Project Hash

The project namespace uses a hash derived from the git remote URL (origin) combined with the relative path from the git root. This ensures:

  • The same project cloned on different machines produces identical namespaces
  • Different subdirectories in a monorepo get distinct namespaces
  • SSH and HTTPS remotes for the same repo produce the same hash

When no git remote is available (e.g., non-git directories), the plugin falls back to hashing the local directory path.

Configuration

Create ~/.config/opencode/graphiti.jsonc:

{
  // Graphiti MCP server URL (required)
  "graphitiUrl": "http://localhost:8000/mcp/",
  
  // User identifier for automatic namespacing (optional*)
  "userId": "john",
  
  // Base group ID for namespacing (optional*)
  // Auto-derived as {userId}_{projectName} if userId set but groupId not
  "groupId": "myteam",
  
  // Profile namespace (optional, default: "{userId}" or "{groupId}_profile")
  "profileGroupId": "myteam_profile",
  
  // Max memories injected per request (default: 5)
  "maxMemories": 5,
  
  // Max project memories listed (default: 10)
  "maxProjectMemories": 10,
  
  // Max profile facts injected (default: 5)
  "maxProfileItems": 5,
  
  // Include user profile in context (default: true)
  "injectProfile": true,
  
  // Extra keyword patterns for memory detection (regex)
  "keywordPatterns": ["log\\s+this", "write\\s+down"],
  
  // Context usage ratio that triggers compaction (default: 0.80)
  "compactionThreshold": 0.80
}

Required fields: graphitiUrl, (userId or groupId)

Either userId or groupId must be set. When userId is set without an explicit groupId, the groupId is automatically derived as {userId}_{projectName}.

Environment variables (take precedence over config file):

  • GRAPHITI_URL - MCP server URL
  • GRAPHITI_USER_ID - User identifier for automatic namespacing
  • GRAPHITI_GROUP_ID - Base group ID (or auto-derived from userId)

Automatic groupId Derivation

When userId is set but groupId is not explicitly provided, the plugin automatically derives groupId:

groupId = {userId}_{projectName}

Where projectName is extracted from package.json name field (or directory name as fallback), sanitized to remove special characters.

Example:

  • userId: "john"
  • Project name: "my-app"
  • Derived groupId: "john_my-app"

This allows you to configure userId once globally, and each project gets its own namespace automatically.

Priority order for groupId resolution:

  1. GRAPHITI_GROUP_ID environment variable (highest)
  2. Local config groupId (.opencode/graphiti.jsonc)
  3. Global config groupId (~/.config/opencode/graphiti.jsonc)
  4. Auto-derived from userId + project name (if userId is set)

Local Project Override

Create .opencode/graphiti.jsonc in your project root to override settings:

{
  "groupId": "project-specific-id",
  "maxProjectMemories": 20
}

Local config merges with global config. Environment variables take highest precedence.

Breaking Changes (v0.2.0)

  • Package renamed: opencode-graphiti@ceris/opencode-graphiti. Update your opencode.jsonc:
    { "plugin": ["@ceris/opencode-graphiti"] }
  • Project hash changed: The project namespace hash now uses the git remote URL instead of the local directory path. Existing memories stored under old hashes will not be automatically migrated. Run /graphiti-init to rebuild your project's memory.

Usage with Oh My OpenCode

If you're using Oh My OpenCode, disable its built-in auto-compact hook to let graphiti handle context compaction:

Add to ~/.config/opencode/oh-my-opencode.json:

{
  "disabled_hooks": ["anthropic-context-window-limit-recovery"]
}

Development

bun install
bun run build
bun run typecheck
bun test

Local install:

{
  "plugin": ["file:///path/to/@ceris/opencode-graphiti"]
}

Logs

tail -f ~/.opencode-graphiti.log

License

MIT