Skip to main content

Persistent memory for AI agents — MCP-native, works with any LLM

Project description

Noshy Architecture Diagram

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.toml with 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_FILE or run in a container to get ~/.noshy/noshy.log (5MB x 3 rotation)

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.
  • 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=25 for 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 memories
  • capture_args=True — include arg names in the summary; arguments whose names look like secrets (password, token, api_key, ...) are auto-redacted
  • skip_if=lambda r: r is None — don't store certain return values
  • ttl_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 python@3.12

# 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
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
  • 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."

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

noshy-0.4.0.tar.gz (90.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

noshy-0.4.0-py3-none-any.whl (74.9 kB view details)

Uploaded Python 3

File details

Details for the file noshy-0.4.0.tar.gz.

File metadata

  • Download URL: noshy-0.4.0.tar.gz
  • Upload date:
  • Size: 90.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for noshy-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ff0f388a7c00eb4b80df20dcbf23dec2aab17bb81d7dc6f27990160c7641b502
MD5 080875bc676c96d15c967c603655f4dc
BLAKE2b-256 124f8f1611e4965ec7e9b43e5f9502d975f22143e80be0a845c4715ffbfed73b

See more details on using hashes here.

Provenance

The following attestation bundles were made for noshy-0.4.0.tar.gz:

Publisher: release.yml on Noshkoto/Noshy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file noshy-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: noshy-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 74.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for noshy-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c1f2a626815b1cd33ba04579447f6dedc72d40adfd0d8080c6f4a4227332462e
MD5 7f663410cea1801bb1b6706a0f2d162c
BLAKE2b-256 1361d22ecca52e9c9e36dc044ef2a4d39e2e2037dbbfcf658132fcd83c0ac64f

See more details on using hashes here.

Provenance

The following attestation bundles were made for noshy-0.4.0-py3-none-any.whl:

Publisher: release.yml on Noshkoto/Noshy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page