Noshy
Health Warn
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- rm -rf — Recursive force deletion command in install.sh
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Your agent has amnesia. Noshy fixes that. Persistent memory for AI agents — LLM extraction, hybrid search, zero deps.

Noshy — Persistent Memory for AI Agents
ICM-compatible. MCP-native. Works with any LLM.
Noshy gives your AI agent real memory — not note-taking, not context stuffing, not a vector database you have to manage. Store facts, search across sessions, build knowledge graphs. It's what ICM wanted to be, re-built to work everywhere.
Noshy
┌───────────┼───────────┐
│ MEMORIES │ MEMOIRS
│ (time-bound) │ (permanent)
│ │
│ ┌───┐ ┌───┐ ┌───┐ │ ┌───┐
│ │bug│ │fix│ │pref│ │ │doc│
│ └───┘ └───┘ └───┘ │ └───┘
│ │ │ │ │
│ └───┬───┘ │ │
│ ┌─────┴─────┐ │ │
│ │ GRAPH │ │ │
│ │ relations │ │ │
│ └───────────┘ │ │
└──────────────────┴─────┘
│
┌─────────┴──────────┐
│ HYBRID SEARCH │
│ keyword+semantic │
│ +graph │
└────────────────────┘
Why Noshy
- LLM-powered extraction — not regex. Uses any OpenAI-compatible API to extract structured facts from transcripts
- Hybrid search — keyword + semantic + graph recall in one query
- ICM compatible — import your existing ICM databases, uses the same schema
- MCP native — works with Claude Code, Hermes, Codex, Copilot, and any MCP client
- Any embedding provider — OpenAI, fastembed (local, free), or Hermes API server
- Zero dependencies — core runs on Python stdlib. fastembed and OpenAI are optional
- Single binary feel — one Python file does everything
- TOML config —
~/.noshy/config.tomlwith env var overrides, no code changes needed - Graceful shutdown — SIGTERM/SIGINT handlers WAL-checkpoint the database and close connections cleanly
- Retry with backoff — LLM extraction retries on 429/5xx with exponential backoff (3 attempts)
- Input validation — empty topics, summaries, and titles are rejected before hitting the database
- Session hooks — automatic memory extraction at session end, no manual calls required
- Numpy-vectorized cosine — cluster detection and semantic search are ~50x faster with numpy (optional, pure-Python fallback included)
- Rotating request logs — set
NOSHY_LOG_FILEor run in a container to get~/.noshy/noshy.log(5MB x 3 rotation) - Contradiction detection — scans memory pairs in a similarity band and asks the LLM whether they conflict; persists confirmed pairs as
contradictsedges so future recalls warn about them - Async extraction queue — hand off long transcripts without blocking on the LLM; a periodic sweep drains the queue in the background
Hermes vs Noshy
Hermes has built-in memory that persists across sessions, but it's small and limited to keyword matching. Noshy replaces that with a proper database that understands what you meant, not just what words you used.
What Noshy adds that Hermes doesn't have by default:
- Semantic search — finds memories by meaning, not just keyword matching. Ask about "that proxy issue" and it finds the entry about SOCKS5 configuration even if the word "proxy" isn't in it.
- Unbounded storage — Hermes caps memory at ~3,500 chars. Noshy stores unlimited entries in SQLite.
- Richer memory types — memories (facts/decisions), memoirs (permanent knowledge), and concepts (related ideas linked together). Hermes just has flat text entries.
- Graph relationships — links related memories so recalling one pulls up connected ones.
- Contradiction awareness — Noshy detects when two memories conflict (e.g. opposite preferences, replaced decisions) and surfaces warnings on recall so agents don't act on stale info.
- Session context injection — automatically surfaces what you were working on, recent decisions, and active projects when a session starts.
- Decision timeline — chronological log of what was decided and why, so you can trace back.
- Pattern detection — notices when the same solution keeps coming up and suggests turning it into a skill.
- Weight decay — older, less-referenced memories fade in relevance automatically instead of cluttering results.
Quick Start
# Install from PyPI (recommended)
pip install noshy
# Start the HTTP server + dashboard
noshy serve
# → http://127.0.0.1:8720/
# Or run as an MCP stdio server
noshy mcp
Or install from source:
curl -fsSL https://raw.githubusercontent.com/noshkoto/Noshy/main/install.sh | sh
Usage
CLI
# Store a memory (optional --ttl, --importance auto, --project)
python3 server.py store "deploy-config" "Deploy uses Cloudflare Pages with GitHub Actions"
# Recall (add --json for machine output)
python3 server.py recall "deployment config"
# List projects with counts and last activity
python3 server.py projects
# Delete: by id, by topic, or wipe an entire project
python3 server.py delete --id 01J...
python3 server.py delete --topic "old-bug" --scope onboarding
python3 server.py delete --project staging --yes
# Maintenance
python3 server.py purge # delete expired
python3 server.py consolidate-clusters # merge near-duplicates
python3 server.py find-contradictions # detect + link conflicting memory pairs
python3 server.py sweep # purge + decay + consolidate + drain queue
# Async extraction queue (hand off long transcripts without blocking on the LLM)
python3 server.py queue --file session.txt --session-id sess-2026-06-18
python3 server.py process-queue --limit 10
# Import from ICM
python3 server.py import /path/to/icm/memories.db
# Stats
python3 server.py stats
MCP Server (Claude Code, Hermes, Codex, Copilot)
Add to your MCP client config:
Claude Code (~/.claude/mcp_servers.json):
{
"mcpServers": {
"noshy": {
"command": "python3",
"args": ["/path/to/noshy/server.py", "mcp"],
"env": {
"NOSHY_EMBED_PROVIDER": "openai",
"OPENAI_API_KEY": "sk-..."
}
}
}
}
Hermes (config.yaml):
mcp_servers:
noshy:
command: "python3"
args: ["/path/to/noshy/server.py", "mcp"]
env:
NOSHY_EMBED_PROVIDER: "openai"
OPENAI_API_KEY: "sk-..."
Codex CLI (~/.codex/mcp.json):
{
"mcpServers": {
"noshy": {
"command": "python3",
"args": ["/path/to/noshy/server.py", "mcp"]
}
}
}
MCP Tools
| Tool | What it does |
|---|---|
noshy_store_memory |
Remember a fact, decision, or preference (optional ttl_seconds to auto-expire) |
noshy_store_memoir |
Store permanent knowledge (docs, reference) |
noshy_recall |
Search memories (keyword, semantic, hybrid) — also surfaces matching memoirs |
noshy_extract_session |
LLM-powered extraction from conversation transcripts |
noshy_stream_extract |
Incremental extraction for very long transcripts (chunked + overlap) |
noshy_session_context |
Generate context for a new session — critical memories, recent decisions, active work. Call at session start |
noshy_decision_timeline |
Chronological timeline of decisions, fixes, and resolutions. Answer "what did we decide about X?" |
noshy_detect_patterns |
Find repeated solutions across sessions — candidates for creating reusable skills |
noshy_consolidate |
Merge related memories on a topic |
noshy_delete |
Remove a memory by id, or all memories under a topic |
noshy_feedback |
Rate a memory +1/-1 to influence how long it survives |
noshy_list_projects |
List every project with per-project counts and last activity |
noshy_delete_project |
Wipe all memories and memoirs for a project (irreversible) |
noshy_predict_importance |
LLM-classify a candidate fact without storing it |
noshy_find_clusters |
Preview clusters of semantically near-duplicate memories |
noshy_consolidate_clusters |
Auto-merge those clusters in one pass |
noshy_find_contradictions |
Detect (and link) pairs of memories that assert conflicting facts |
noshy_queue_extraction |
Hand off a transcript for later LLM extraction without blocking |
noshy_process_queue |
Drain queued extractions through the LLM |
noshy_get_stats |
Database overview |
HTTP API
# Store
curl -X POST http://127.0.0.1:8720/tools/call \
-H 'Content-Type: application/json' \
-d '{"name":"noshy_store_memory","arguments":{"topic":"my-topic","summary":"What to remember"}}'
# Recall
curl -X POST http://127.0.0.1:8720/tools/call \
-H 'Content-Type: application/json' \
-d '{"name":"noshy_recall","arguments":{"query":"search keywords"}}'
# Stats
curl http://127.0.0.1:8720/stats
# Recent memories (JSON)
curl 'http://127.0.0.1:8720/memories?limit=25'
Web Dashboard
The HTTP server also serves a zero-dependency web dashboard. Start the server
and open the root URL in a browser:
python3 server.py http
# then visit http://127.0.0.1:8720/
Dashboard features:
- Hyrule color palette — Rupee emerald, Navi fairy blue, Sunset amber accents on a twilight dark background
- Animated gradient orbs — floating radial gradients with CSS grid background art
- Project picker — custom dropdown with gradient-tinted selection, animated chevron, count pills, click-outside/Esc to close
- Hybrid search — keyword + semantic + graph in one query box; memoirs included
- Cluster view — surface groups of near-duplicate memories and merge them in one click
- Inline delete — hover a card, click the trash icon to remove it (with custom confirm dialog)
- Dark / light theme — auto-detected, manually toggleable, persisted to
localStorage - Animated stat counters — live database stats with skeleton loaders on first paint
- Toast notifications — feedback on store/delete/consolidate actions
- Pagination —
?page=1&limit=25for large databases
When NOSHY_HTTP_TOKEN is set, the dashboard shows a token prompt modal on
first load. The token persists in localStorage across reloads. A "Forget"
button clears it. API routes enforce auth; / and /health stay public.
Session Hooks
Noshy can automatically extract memories when a session ends. Drop the hook
into your Hermes workflow or call it from any MCP client:
from hooks import on_session_end
result = on_session_end(transcript, project="my-project", max_memories=8)
# → {"extracted": 5, "ids": [...], "concepts": ["deploy", "ci"]}
The hook skips transcripts shorter than 100 characters and returns structured
results with extracted memory IDs and discovered concepts.
Python API
For scripts and apps, Noshy ships a small Python API with decorators that
make any function self-remembering:
import noshy
@noshy.remember(topic="deploy", importance="high")
def deploy(env):
return f"deployed to {env}"
deploy("prod") # auto-stores: deploy -> 'deployed to prod'
# Scope memories to a project (and inherit tags) for a block of code
with noshy.session(project="checkout-bugfix", tags=["sprint-23"]):
do_work() # every @remember inside picks up the project
noshy.recall("deploy") # hybrid search returns matching memories
Useful keyword arguments on @noshy.remember:
importance="auto"— let the LLM classify each memory (critical/high/medium/low)on_error=True(default) — exceptions are stored as high-importance memoriescapture_args=True— include arg names in the summary; arguments whose
names look like secrets (password,token,api_key, ...) are auto-redactedskip_if=lambda r: r is None— don't store certain return valuesttl_seconds=...— auto-expire after N seconds
For long-running sessions, noshy.extractor.stream_extract(chunks) yields
memories incrementally as transcript chunks arrive.
Embedding Providers
Noshy auto-detects the best available embedding provider. Set NOSHY_EMBED_PROVIDER to override:
| Provider | Env Var | API Key | Quality |
|---|---|---|---|
| OpenAI | NOSHY_EMBED_PROVIDER=openai |
OPENAI_API_KEY |
Best |
| fastembed | NOSHY_EMBED_PROVIDER=fastembed |
None (local) | Good |
| Hermes API | auto-detected | API_SERVER_KEY |
Varies |
| None | No embedding | None | Keyword only |
# With OpenAI
export OPENAI_API_KEY="sk-..."
python3 server.py http
# With free local embeddings
pip install fastembed
python3 server.py http
# Keyword-only (no embeddings)
NOSHY_EMBED_PROVIDER=none python3 server.py http
Platform Setup
macOS
# Install Python 3.10+ if needed
brew install [email protected]
# Install Noshy
curl -fsSL https://raw.githubusercontent.com/noshkoto/Noshy/main/install.sh | sh
# Optional: local embeddings
pip3 install fastembed
Linux
sudo apt install python3 # Debian/Ubuntu
sudo dnf install python3 # Fedora
curl -fsSL https://raw.githubusercontent.com/noshkoto/Noshy/main/install.sh | sh
Windows
# Install Python from python.org (check "Add to PATH")
# Download Noshy
Invoke-WebRequest -Uri https://github.com/noshkoto/Noshy/archive/refs/heads/main.zip -OutFile noshy.zip
Expand-Archive noshy.zip -DestinationPath $env:USERPROFILE\.noshy
Rename-Item $env:USERPROFILE\.noshy\Noshy-main $env:USERPROFILE\.noshy\src
# Run
python $env:USERPROFILE\.noshy\src\server.py http
Docker
# Build the image from the included Dockerfile
docker build -t noshy .
# Run it (data persists in a named volume)
docker run -d --name noshy \
-p 8720:8720 \
-v noshy-data:/data \
-e OPENAI_API_KEY=sk-... \
noshy
# Or with HTTP auth enabled
docker run -d --name noshy \
-p 8720:8720 \
-v noshy-data:/data \
-e NOSHY_HTTP_TOKEN=$(openssl rand -hex 32) \
noshy
# Optional build flags
docker build --build-arg WITH_FASTEMBED=1 -t noshy . # bake local embeddings
docker build --build-arg WITH_SQLITE_VEC=0 -t noshy . # skip the vec extension
The image runs as a non-root user, exposes a /health endpoint, and uses/data as a persistent volume.
HTTP authentication
By default the HTTP server is unauthenticated and binds to 127.0.0.1 only.
To expose it on a network or behind a proxy, set a bearer token:
export NOSHY_HTTP_TOKEN="$(openssl rand -hex 32)"
python3 server.py serve --host 0.0.0.0
Clients must then send Authorization: Bearer <token> on every request. The/health endpoint and the dashboard HTML at / stay public so probes and
human visitors still work.
Configuration
Noshy supports two configuration methods. Environment variables always take
precedence over the config file.
Config file
Create ~/.noshy/config.toml (or set NOSHY_CONFIG to a custom path):
[noshy]
db-path = "~/.noshy/memories.db"
embed-provider = "openai"
embed-model = ""
api-base = "http://127.0.0.1:8642/v1"
model = "hermes-agent"
http-host = "127.0.0.1"
http-port = 8720
Environment variables
| Env Variable | Default | Description |
|---|---|---|
NOSHY_CONFIG |
~/.noshy/config.toml |
Path to config file |
NOSHY_DB |
~/.noshy/memories.db |
Database path |
NOSHY_EMBED_PROVIDER |
auto | openai, fastembed, hermes, or none |
NOSHY_EMBED_MODEL |
provider default | Embedding model name |
NOSHY_EMBED_API_BASE |
provider default | Embedding API URL |
NOSHY_EMBED_API_KEY |
OPENAI_API_KEY |
Embedding API key |
NOSHY_API_BASE |
http://127.0.0.1:8642/v1 |
LLM API for extraction |
NOSHY_API_KEY |
API_SERVER_KEY |
LLM API key |
NOSHY_MODEL |
hermes-agent |
Model for extraction |
NOSHY_HTTP_TOKEN |
unset | If set, all HTTP routes require Authorization: Bearer *** (except /healthand/`) |
NOSHY_LOG_FILE |
unset | If set (or stderr is not a tty), rotating logs go to ~/.noshy/noshy.log (5MB x 3) |
Database migrations
Noshy auto-migrates the database schema on startup (v1 through v4). No manual
steps required. New columns are added transparently; existing data is preserved.
Architecture
┌─────────────────────────────────────────┐
│ Noshy MCP Server │
│ ┌──────────┐ ┌────────┐ ┌───────────┐ │
│ │Extractor │ │ Store │ │ Embedder │ │
│ │(LLM API) │ │(SQLite)│ │(OpenAI/ │ │
│ │ + retry │ │ +migrate│ │ fastembed) │ │
│ │ │ │ factory│ │ +numpy cos│ │
│ └──────────┘ └────────┘ └───────────┘ │
│ │ │ │ │
│ └──────────┼───────────┘ │
│ │ │
│ ┌───────────┴────────┐ │
│ │ Hybrid Search │ │
│ │ keyword semantic │ │
│ │ + graph │ │
│ └────────────────────┘ │
│ │ │
│ ┌────────┴───────┐ │
│ │ MCP / HTTP │ │
│ │ (stdio+API) │ │
│ └────────────────┘ │
│ │ │
│ ┌────────┴───────┐ │
│ │ Session Hooks │ │
│ │ (auto-extract)│ │
│ └────────────────┘ │
└─────────────────────────────────────────┘
Import from ICM
# Import memories from an existing ICM database
python3 server.py import ~/.config/icm/memories.db
# Verify
python3 server.py stats
The schema is compatible — memories, memoirs, concepts, and metadata all transfer. Graph edges and feedback are preserved when available.
Comparison
| ICM | Noshy | |
|---|---|---|
| Extraction | Rule-based regex | LLM-powered (any provider) |
| Search | Keyword + vector | Keyword + semantic + graph |
| Embeddings | fastembed only | OpenAI, fastembed, Hermes, none |
| Relationships | Memoir categories only | Full graph with weighted edges |
| Consolidation | Manual | LLM-assisted auto-merge |
| Deployment | Rust binary (compile) | Python stdlib (zero-deps core) |
| MCP | Yes | Yes |
| API | MCP only | MCP + HTTP + Python import |
| ICM import | N/A | Built-in |
| Config | Env vars only | TOML file + env var overrides |
| Lifecycle | Manual process management | Graceful shutdown, auto-migration, retry |
| Cosine similarity | Pure Python | Numpy-vectorized (~50x faster), pure-Python fallback |
| Contradiction detection | None | LLM-powered conflict scan with persistent contradicts edges |
| Extraction queue | Synchronous only | Async queue with background drain |
| Logs | stdout only | Rotating file logs (5MB x 3) |
| Dashboard auth | None | Token prompt modal, localStorage persistence |
Roadmap
- Web dashboard
- Semantic search over memoirs (auto-embedded on store)
- Automatic, importance-aware memory decay
- Consolidation that prunes merged duplicates
- Python decorator for automatic function memory (
@noshy.remember) - Memory importance prediction (
importance="auto") - Streaming extraction (
extractor.stream_extract) - Project isolation (
list_projects/delete_project) - Graph-based memory consolidation (
find_clusters/consolidate_clusters) - HTTP bearer-token auth (
NOSHY_HTTP_TOKEN) - Real Dockerfile (multi-stage, non-root, healthcheck)
- Integration test suite (
pytest tests/) - PyPI release (
pip install noshy) - Streaming extraction MCP tool (
noshy_stream_extract) - Dashboard polish (project picker, cluster view, inline delete, theme toggle)
- TOML config file (
~/.noshy/config.toml) - Schema auto-migration (v1-v4)
- Graceful shutdown (SIGTERM/SIGINT + WAL checkpoint)
- LLM extraction retry with exponential backoff
- Session context, decision timeline, and pattern detection MCP tools
- Session-end auto-extraction hooks
- Glassmorphism dashboard redesign
- Hyrule color palette (emerald, fairy blue, sunset amber)
- Numpy-vectorized cosine similarity (~50x faster)
- Dashboard extracted to dashboard.html (server.py 1832 -> 1012 lines)
- Dashboard auth UI (token prompt modal, localStorage, Forget button)
- Rotating HTTP request logs (
NOSHY_LOG_FILE) - Input validation and silent-except cleanup
- Contradiction detection (
noshy_find_contradictions+contradictsedges on recall) - Async extraction queue (
noshy_queue_extraction/noshy_process_queue) - 56 tests (was 47)
- Per-user database isolation (multi-tenant — one DB per token)
License
Apache 2.0 — same as ICM. Built as a drop-in improvement.
"Your agent shouldn't forget what you fixed last week."
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found