Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.4
bun-version: 1.3.6

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/publish-ai-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ jobs:

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Install dependencies
run: bun install
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/publish-memory-graph.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ jobs:

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Install dependencies
run: bun install
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/publish-tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ jobs:

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Install dependencies
run: bun install
Expand Down
32 changes: 27 additions & 5 deletions apps/mcp/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ type Props = {
name?: string
}

const CONTAINER_TAGS_TTL_MS = 5 * 60 * 1000

export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
private clientInfo: { name: string; version?: string } | null = null
private cachedContainerTags: string[] = []
private containerTagsLastFetchedAt: number | null = null

server = new McpServer({
name: "supermemory",
Expand Down Expand Up @@ -168,8 +171,8 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
"supermemory://projects",
{},
async () => {
const client = this.getClient()
const projects = await client.getProjects()
await this.ensureContainerTagsFresh()
const projects = this.cachedContainerTags

return {
contents: [
Expand All @@ -193,15 +196,19 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
refresh: z
.boolean()
.optional()
.default(true)
.describe("Refresh the list from the server (default: true)"),
.default(false)
.describe(
"Force refresh from the server (default: false; uses cache with TTL)",
),
}),
},
// @ts-expect-error - zod type inference issue with MCP SDK
async (args: { refresh?: boolean }) => {
try {
if (args.refresh !== false) {
if (args.refresh === true) {
await this.refreshContainerTags()
} else {
await this.ensureContainerTagsFresh()
}
const projects = this.cachedContainerTags

Expand Down Expand Up @@ -566,6 +573,10 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {

const result = await client.createMemory(content)

if (!this.cachedContainerTags.includes(result.containerTag)) {
await this.refreshContainerTags()
}

// Track memory added event
posthog
.memoryAdded({
Expand Down Expand Up @@ -758,10 +769,21 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
return this.ctx.id.name || "unknown"
}

private async ensureContainerTagsFresh(): Promise<void> {
const now = Date.now()
const needsRefresh =
this.containerTagsLastFetchedAt === null ||
now - this.containerTagsLastFetchedAt > CONTAINER_TAGS_TTL_MS
if (needsRefresh) {
await this.refreshContainerTags()
}
}

private async refreshContainerTags(): Promise<void> {
try {
const client = this.getClient()
this.cachedContainerTags = await client.getProjects()
this.containerTagsLastFetchedAt = Date.now()
} catch (error) {
console.error("Failed to fetch container tags:", error)
}
Expand Down
4 changes: 3 additions & 1 deletion apps/mcp/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"resolveJsonModule": true,
"outDir": "dist",
"rootDir": "src",
"baseUrl": "."
"paths": {
"*": ["./*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
Expand Down
6 changes: 6 additions & 0 deletions apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Suspense } from "react"
import { Toaster } from "@ui/components/sonner"
import { NuqsAdapter } from "nuqs/adapters/next/app"
import { ThemeProvider } from "@/lib/theme-provider"
import Script from "next/script"

const font = Space_Grotesk({
subsets: ["latin"],
Expand Down Expand Up @@ -69,6 +70,11 @@ export default function RootLayout({
</QueryProvider>
</AutumnProvider>
</ThemeProvider>
<Script
src="https://lobbyside.com/widget.js"
data-widget-id="e385c52f-4dd3-4fb2-81eb-da3a78059014"
strategy="lazyOnload"
/>
</body>
</html>
)
Expand Down
10 changes: 6 additions & 4 deletions apps/web/components/memory-graph/memory-graph-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ export function MemoryGraph({
maxNodes={maxNodes}
canvasRef={canvasRef}
totalCount={totalCount}
colors={{
bg: "transparent",
edgeDerives: "#9ca3af",
} as any}
colors={
{
bg: "transparent",
edgeDerives: "#9ca3af",
} as any
}
{...rest}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"engines": {
"node": ">=20"
},
"packageManager": "bun@1.3.4",
"packageManager": "bun@1.3.6",
"workspaces": [
"apps/*",
"!apps/raycast-extension",
Expand Down
20 changes: 13 additions & 7 deletions packages/memory-graph/src/components/memory-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,22 +197,29 @@ export function MemoryGraph({
setViewportVersion((v) => v + 1)
}

const { hasMore: more, isLoadingMore: loading, onLoadMore: load } = loadMoreRef.current
const {
hasMore: more,
isLoadingMore: loading,
onLoadMore: load,
} = loadMoreRef.current
if (!more || loading || !load || !viewportRef.current) return

const vp = viewportRef.current
const currentNodes = nodes
if (currentNodes.length === 0) return

const topLeft = vp.screenToWorld(0, 0)
const bottomRight = vp.screenToWorld(containerSize.width, containerSize.height)
const bottomRight = vp.screenToWorld(
containerSize.width,
containerSize.height,
)
const viewW = bottomRight.x - topLeft.x
const viewH = bottomRight.y - topLeft.y

let minX = Infinity
let minY = Infinity
let maxX = -Infinity
let maxY = -Infinity
let minX = Number.POSITIVE_INFINITY
let minY = Number.POSITIVE_INFINITY
let maxX = Number.NEGATIVE_INFINITY
let maxY = Number.NEGATIVE_INFINITY
for (const n of currentNodes) {
if (n.x < minX) minX = n.x
if (n.y < minY) minY = n.y
Expand Down Expand Up @@ -613,7 +620,6 @@ export function MemoryGraph({
colors={colors}
/>


{!isLoading && !nodes.some((n) => n.type === "document") && children && (
<div style={emptyStateStyle}>{children}</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@supermemory/tools",
"type": "module",
"version": "1.4.5",
"description": "Memory tools for AI SDK and OpenAI function calling with supermemory",
"description": "Memory tools for AI SDK, OpenAI, Voltagent and Mastra with supermemory",
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch --ignore-watch .turbo",
Expand Down
28 changes: 20 additions & 8 deletions packages/tools/test/claude-memory-real-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,16 @@ export async function realClaudeMemoryExample() {
const toolResults = []

if (responseData.content) {
const memoryToolCalls = responseData.content.filter(
(block: any): block is { type: 'tool_use'; id: string; name: 'memory'; input: { command: MemoryCommand; path: string } } =>
block.type === "tool_use" && block.name === "memory",
)
const memoryToolCalls = responseData.content.filter(
(
block: any,
): block is {
type: "tool_use"
id: string
name: "memory"
input: { command: MemoryCommand; path: string }
} => block.type === "tool_use" && block.name === "memory",
)

const results = await Promise.all(
memoryToolCalls.map((block: any) => {
Expand Down Expand Up @@ -196,10 +202,16 @@ export async function processClaudeResponse(
const toolResults = []

if (claudeResponseData.content) {
const memoryToolCalls = claudeResponseData.content.filter(
(block: any): block is { type: 'tool_use'; id: string; name: 'memory'; input: { command: MemoryCommand; path: string } } =>
block.type === "tool_use" && block.name === "memory",
)
const memoryToolCalls = claudeResponseData.content.filter(
(
block: any,
): block is {
type: "tool_use"
id: string
name: "memory"
input: { command: MemoryCommand; path: string }
} => block.type === "tool_use" && block.name === "memory",
)

const results = await Promise.all(
memoryToolCalls.map((block: any) =>
Expand Down
Loading