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

opencode-graphiti

v0.1.2

Published

OpenCode plugin for persistent memory via Graphiti knowledge graph

Readme

opencode-graphiti

OpenCode plugin that provides persistent memory via a Graphiti knowledge graph.

Motivation

Long-running AI coding sessions depend on persistent memory to stay on track. Graphiti's MCP server is the intended backbone for this, but in practice it is unreliable — connections drop, queries time out, and ingestion silently fails. When the context window fills up and OpenCode triggers compaction, the summarizer discards details that were never persisted. The result is context rot: the agent loses track of recent decisions, re-explores solved problems, and drifts away from the original goal.

This plugin exists to close that gap. It captures chat histories and project facts into Graphiti when the server is healthy, then re-injects them at the start of every session and before every compaction so the agent is always reminded of recent project context — regardless of what survived the summary.

Overview

This plugin connects to a Graphiti MCP server and:

  • Injects relevant memories into the first user message of each session
  • Periodically re-injects project memories as the conversation progresses
  • Buffers user and assistant messages, flushing them to Graphiti on idle or before compaction
  • Preserves key facts during context compaction
  • Saves compaction summaries as episodes so knowledge survives across boundaries
  • Scopes memories per project (and per user) using directory-based group IDs

Prerequisites

A running Graphiti MCP server accessible over HTTP. The easiest way to set one up:

# Clone and start with Docker Compose
git clone https://github.com/getzep/graphiti.git
cd graphiti/mcp_server
docker compose up -d

This starts the MCP server at http://localhost:8000/mcp with a FalkorDB backend.

Installation

Option A: npm package (recommended)

Add the plugin to your opencode.json (or opencode.jsonc):

{
  "plugin": ["opencode-graphiti"]
}

Option B: Local build

Clone and build, then reference the built file:

git clone https://github.com/vicary/opencode-graphiti.git
cd opencode-graphiti
deno task build

Then add to your opencode.json:

{
  "plugin": ["file:///absolute/path/to/opencode-graphiti/dist/index.js"]
}

Option C: Plugin directory

Copy the built plugin into OpenCode's auto-loaded plugin directory:

# Global (all projects)
cp dist/index.js ~/.config/opencode/plugins/opencode-graphiti.js

# Or project-level
mkdir -p .opencode/plugins
cp dist/index.js .opencode/plugins/opencode-graphiti.js

No config entry needed — OpenCode loads plugins from these directories automatically.

Configuration

Create a config file at ~/.config/opencode/graphiti.jsonc:

{
  // Graphiti MCP server endpoint
  "endpoint": "http://localhost:8000/mcp",

  // Prefix for project group IDs (e.g. "opencode_my-project")
  "groupIdPrefix": "opencode",

  // Number of user messages between memory re-injections (0 = disabled)
  "injectionInterval": 10
}

All fields are optional — defaults (shown above) are used for any missing values.

How It Works

Memory Injection (chat.message)

On the first user message in a session, the plugin searches Graphiti for facts and entities relevant to the message content. Results are split into project and user scopes (70% / 30% budget split), formatted, and prepended to the conversation as a synthetic context block.

The injection budget is calculated dynamically: 5% of the model's context limit (resolved from the provider list) multiplied by 4 characters per token.

Re-injection (chat.message)

When injectionInterval is greater than 0, the plugin periodically re-injects project-scoped memories as the conversation progresses. After every N user messages (where N is injectionInterval), stale synthetic memory parts are replaced with fresh results. Re-injection uses the full character budget for project memories only (no user scope).

Message Buffering (event)

User and assistant messages are buffered in memory as they arrive. The plugin listens on message.part.updated to capture assistant text as it streams, and on message.updated to finalize completed assistant replies. Buffered messages are flushed to Graphiti as episodes:

  • On idle (session.idle): when the session becomes idle with at least 50 bytes of buffered content.
  • Before compaction (session.compacted): all buffered messages are flushed immediately (no minimum size) so nothing is lost.

If the last buffered message is from the user (i.e. no assistant reply was captured), the plugin fetches the latest assistant message from the session API as a fallback before flushing.

Compaction Preservation (session.compacted + experimental.session.compacting)

Compaction is handled entirely by OpenCode's native compaction mechanism. The plugin participates in two ways:

  1. Before compaction (experimental.session.compacting): The plugin injects known facts and entities into the compaction context using the same 70% / 30% project/user budget split, so the summarizer preserves important knowledge.
  2. After compaction (session.compacted): The compaction summary is saved as an episode to Graphiti, ensuring knowledge survives across compaction boundaries.

Project Scoping

Each project gets a unique group_id derived from its directory name (e.g. opencode_my-project). Group IDs only allow letters, numbers, dashes, and underscores (colons are not allowed). This ensures memories from different projects stay isolated.

Development

# Format
deno fmt

# Lint
deno lint

# Type check
deno check src/index.ts

# Build
deno task build

License

MIT

Acknowledgement

This project is inspired by opencode-openmemory