Project Info
Inspiration
Every team building with AI hits the same wall: your AI tools are smart in isolation, but completely amnesiac across sessions and teammates. One engineer decides to go API-first in a Cursor chat, another picks a database in Claude, and a third makes a design call over Slack, and none of those decisions are accessible to anyone else's AI. The result is constant re-explaining, duplicated research, and contradictory choices that only surface during code review or a frustrated standup. We realized the bottleneck isn't intelligence, it's information. Modern AI agents lack a shared, persistent memory, and that gap gets worse the more agents and people you add. We wanted to build the connective tissue that lets an entire org's AI tools reason from the same evolving context.
What it does
Scope is a shared knowledge layer for teams using AI. You save decisions, context, and knowledge once, and any AI tool, Cursor, Claude Code, Poke, or custom agents can pull it back instantly with the right permissions. Memories are organized into workspaces with role-based access control, so managers control what's visible and to whom. Under the hood, Scope models memory as a knowledge graph: each memory is a node, and relationships, relevance scores, and temporal metadata are stored as edges. When a query comes in, vector search identifies entry points, then an LLM-guided traversal branches across the graph to pull in only the context that actually matters for that task, not just keyword matches, but semantically connected decisions and history. Scope tracks what changed and who's seen it, so teammates and agents always know what's new. It exposes everything as both a REST API and an MCP server, meaning any MCP-compatible tool can store and search team memory out of the box. We also built a CLI (scope init) that auto-configures Claude Code hooks so memories sync without any manual effort, engineers just code, and Scope keeps the org in sync behind the scenes.
How we built it
The backend is FastAPI with PostgreSQL for structured data and Neo4j + Graphiti for the knowledge graph layer. Graphiti gives us hybrid retrieval, vector similarity, BM25 keyword search, and graph traversal in one pipeline, powered by OpenAI embeddings. Auth uses bearer tokens with SHA-256 hashed API keys and full workspace-scoped ACLs. The frontend is Next.js 15 / React 19 with Shadcn UI, Zustand for state, and TanStack Query for data fetching, which lets you register, manage workspaces, search memories, and invite teammates from the browser. We also used Reagraph for graph visualization for memories. We built two MCP servers: one general-purpose server with 10 tools for Cursor and Claude Desktop (search, store, list workspaces), and a Poke-specific server with 15 tools that add team messaging, meeting scheduling suggestions, and daily summary generation. We also wrote a Python SDK and a CLI tool that configures Claude Code hooks to auto-push local AI memories to the shared workspace on every relevant file write.
Challenges we ran into
The hardest problem was bridging local and shared memory. Claude Code writes memories to local markdown files, getting those to sync upstream without duplicating, losing metadata, or breaking the user's workflow required building a diffing mechanism, a sync state tracker, and hooks that fire only on relevant file changes. Getting the granularity right (when is a memory "new" vs. "updated"?) was surprisingly tricky. Graphiti's search returns knowledge graph edges (extracted facts), not our original Memory records, so we had to work around a join gap where search results lost tags, scope, creator info, and timestamps. Reconciling the graph layer with the relational layer without sacrificing query speed was a constant tension. We also wrestled with per-user visibility of changes. "What's new" is relative, what's new to Alice isn't new to Bob, so we needed per-user read tracking across shared workspaces, which added real complexity to the access log and notification system.
Accomplishments we're proud of
We shipped a full product loop in a hackathon: API, SDK, CLI, two MCP servers, a frontend dashboard, and a working Poke integration. A developer can run scope init in any project, and from that point on, every AI tool they use shares the same memory, no config, no copy-pasting, no standups to re-sync. We're proud of the graph-based retrieval. It's not just semantic search, it's traversal. When you ask "why did we choose Postgres?", Scope doesn't just find that memory; it walks the graph to surface the performance benchmarks, the alternative options that were rejected, and the teammate who made the call. That kind of contextual depth is what separates a real memory system from a vector store with a search bar. We also got the Poke MCP integration working end-to-end: Poke users can ask conversational questions ("what did the team decide about the launch?"), Get daily "spokes" summarizing what everyone accomplished, and even have Poke suggest when a meeting is actually necessary based on disagreements or major code changes it detects in the shared memory.
What we learned
We learned that memory is not storage, it's structure. A flat vector database gives you recall, but teams need hierarchy (workspaces, permissions), temporality (what changed and when), and relationships (why decisions connect). Building that graph layer was the difference between a demo and something teams would actually trust. We also learned how powerful MCP as a distribution layer is. Instead of building integrations one-by-one, exposing Scope as an MCP server meant that Cursor, Claude Code, Poke, and any future MCP client could plug in immediately. The protocol did the distribution work for us. Finally, we learned that the real unlock isn't giving AI more memory, it's giving teams more memory. The moment two people's AI tools share context, the compounding effect is immediate: less repeated work, faster onboarding, and decisions that actually stick.
What's next
Short term: production deployment with proper auth (OAuth, not just API keys), a hosted version so teams don't need to self-host, and a polished scope watch daemon that continuously syncs in the background instead of relying on hooks. Medium term: expand integrations beyond dev tools, connect to Slack, Notion, and Google Docs so memories flow in from where decisions actually happen, not just where code gets written. We also want to build automatic memory agents that scan for stale or conflicting memories and suggest merges or pruning. Long term: We want Scope to be the default memory layer for every AI agent in an organization. Not just dev teams, sales, ops, product, support. Any team running parallel AI workflows hits the same information gap. Our vision is that every AI tool an org uses reads and writes to Scope, so the entire company's AI operates with one shared, evolving understanding. The era of containerized conversations is over.
Recall
A shared memory layer for teams that use AI at work.
Right now, important context ends up scattered across Slack, docs, and random AI chats — so people keep re-explaining the same background and redoing the same research. Recall is a place to save key decisions and context once, and then your AI tools can pull it back instantly later — for you or your teammates — with the right permissions.
- User-first: Your API key is tied to you (register once). You can be in multiple workspaces (teams); add teammates by email.
- Memories can be tagged as
decisionorcontext; responses include who can see what (visible_to_user_ids). - FastAPI backend, PostgreSQL + pgvector, Python SDK + MCP server for Cursor.
Quick start
-
Install (use a venv so you don’t hit system Python):
python3 -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate pip install -r requirements.txt # or: uv syncUse
pip install(notpip3) after activating the venv so you use the venv’s Python. -
Postgres with pgvector
docker run --name recall-db -e POSTGRES_USER=recall -e POSTGRES_PASSWORD=recall \ -e POSTGRES_DB=recall_dev -p 5433:5432 -d ankane/pgvector:latest -
Environment
cp env.example .env # Set OPENAI_API_KEY for embeddings; set RECALL_API_BASE_URL / RECALL_API_KEY if using MCP -
Run API
uvicorn api.main:app --reload
Or run everything with Docker:
docker compose up --build
API keys (per user)
-
Register to get a user and API key plus a default workspace:
curl -X POST http://localhost:8000/v1/register \ -H "Content-Type: application/json" \ -d '{"name": "Alice", "email": "alice@example.com"}'Response includes
user_id,workspace_id, andapi_key— save the key; it’s only returned once. -
Alternatively, create a workspace without registering (anonymous). Note: memory store/query require a user-linked key (from register).
Use the key on all other requests:
curl -H "Authorization: Bearer YOUR_API_KEY" http://localhost:8000/v1/workspaces
Smoke test
With the API running, run the smoke test harness (exits 0 only if all requests succeed):
./scripts/test_api.sh
See TESTING.md for more.
Main endpoints
- Auth & users:
POST /v1/register— register user, get API key + default workspace (no auth) - Workspaces (teams):
POST /v1/workspaces— create workspace;GET /v1/workspaces— list all workspaces you’re in (when using a user-linked key) - Members:
POST /v1/workspaces/{id}/members— add teammate byemailoruser_id;GET /v1/workspaces/{id}/members— list members;DELETE /v1/workspaces/{id}/members/{user_id}— remove - Agents (metadata):
POST /v1/workspaces/{id}/agents,GET /v1/workspaces/{id}/agents - Memories:
POST /v1/memories— store (optionalmemory_type:"decision"|"context");POST /v1/memories/query— semantic search;GET /v1/memories/{id}— get (responses includevisible_to_user_ids) - API keys:
POST /v1/workspaces/{id}/api-keys,GET,POST .../revoke
SDK
from sdk.client import RecallClient
client = RecallClient(base_url="http://localhost:8000")
# Option A: register (per-user key)
data = client.register("Alice", email="alice@example.com")
# client now has api_key set
# Option B: create workspace
# data = client.create_workspace("demo")
# client.set_api_key(data["api_key"])
client.store_memory(
workspace_id=data["workspace_id"],
content="Found the artifact in sector 7",
scope="private",
tags=["artifact"],
)
# optional: agent_id="cursor" to record which tool created it
results = client.query_memories(
workspace_id=data["workspace_id"],
query="artifact",
)
print(results)
client.close()
MCP (Cursor)
Set RECALL_API_BASE_URL and RECALL_API_KEY (e.g. from register or workspace creation), then point Cursor at the Recall MCP server. Tools: recall_search_memories, recall_store_memory, recall_get_memory, recall_smart_search, recall_list_workspaces, recall_list_agents, recall_create_agent.
Layout
api/— FastAPI app, routes, services, modelssdk/— Python clientmcp_server/— MCP tools for Cursor
Analysis
View
Metric
- 23
- 9
- 4
- 3
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- AnthropicClaimed
- DockerClaimed
8 of 10 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeConfig · Commits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
543 KB
Source files
162
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
batyr0601/treehacks26
182 files · 1.1 MB · @ d5d52d4
Structure
Interface
73 files · 40%Screens, components and styles rendered to the user.
API & routing
36 files · 20%Request entry points: routes, handlers and controllers.
Application logic
37 files · 20%Domain rules, services and shared utilities.
+3 more
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python50%
- TypeScript44%
- Markdown4%
- Shell1%
- CSS1%
- YAML0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
frontend/package.json
npm · 29- @hookform/resolvers
- @radix-ui/react-slot
- @tanstack/react-query
- axios
- class-variance-authority
- clsx
- cmdk
- lucide-react
- motion
- next
- next-themes
- radix-ui
- react
- react-dom
- react-hook-form
- reagraph
- sonner
- tailwind-merge
- +11 more
pyproject.toml
pypi · 12- alembic
- fastapi
- fastmcp
- graphiti-core
- httpx
- openai
- psycopg[binary]
- pydantic
- pydantic-core
- python-dotenv
- sqlalchemy
- uvicorn[standard]
requirements.txt
pypi · 12- alembic
- fastapi
- fastmcp
- graphiti-core
- httpx
- openai
- psycopg[binary]
- pydantic
- pydantic-core
- python-dotenv
- sqlalchemy
- uvicorn[standard]
poke_mcp/requirements.txt
pypi · 3- fastmcp
- httpx
- python-dotenv
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.