Telys — on-device memory

io.github.thyn-aiPublished by GitHub account thyn-aiv0.1.14Updated Nov 2, 2026

Private on-device memory & retrieval for AI assistants — offline vector + lexical search.

The publisher's own server: Memory.fit

VerifiedSTDIODesktop onlyKnowledge & MemoryDeveloper Tools

Overview

AI-generated overview

Telys gives an assistant a private, on-device memory store: it saves notes and facts, then recalls them with vector and keyword search, fully offline.

What you can do
  • Search and recall stored memories with semantic or BM25 keyword search, or fetch exact rows by id
  • Write and maintain memories: add texts, upsert by id, update existing ids, delete rows, compact storage
  • Manage collections: create, list, inspect stats, count rows and enumerate ids with optional filters
  • Index a local repository and search its chunks, with hits re-read from source files
  • Tune and build indexes (IVF vector index, BM25 lexical index, tuning plans) and report workspace info
When to use it
Useful when you want an assistant to remember decisions, notes and facts across sessions without sending data to a cloud service, or to search a local code repository by meaning and keywords.
Requirements
Runs locally over stdio as a PyPI package (pipx or pip), on macOS arm64 or Linux x86_64/arm64 (Windows via WSL2). A one-time free telys login (device authorization) fetches a signed on-device runtime; no API key goes in the client config. Tool listing works without credentials.
Before you install
Executing memory tools requires the signed runtime obtained through telys login and a free community license tied to an account; pricing and billing pages exist for other plans. Write tools add, replace and tombstone stored rows, and repo indexing reads local files into a collection, so point the workspace at a repository you are comfortable indexing.

Installation

In SourceWeft

  1. Open Telys — on-device memory in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

telys

Public SDK for Telys — embedded, on-device memory & retrieval. In-process, zero cloud roundtrips at query time.

This package contains the complete developer-facing surface: the Telys/Collection facades, query/filter types, the EmbeddingProvider interface, the Tuner/TuningPlan interfaces, the full MCP server (telys/mcp.py — 19 tools, protocol 2025-06-18, stdio), a runtime loader, and the telys CLI. The numerical kernel (libame_kernel) the tools drive is a separately distributed, signed on-device runtime fetched by telys login (free community license) — the same arrangement as MCP servers that front hosted or signed-binary backends.

Install

As a CLI (recommended — isolated env, on your PATH, not pinned to one Python):

bash
pipx install telys
telys login          # sign in → free device license + signed runtime; fully offline thereafter

As a library (to import telys in your own project):

bash
python -m venv .venv && . .venv/bin/activatepip install telys

Plain pip install --user telys works too, but pip may warn that its user-scripts dir isn't on your PATH (a macOS --user quirk) — pipx avoids that entirely. Runtime platforms: macOS arm64, Linux x86_64/arm64 (Windows: run under WSL2).

python
from telys import Telysdb = Telys("./memory")col = db.create_collection("docs", dim=768, partition_by="tenant_id")   # dim is arbitrary — 384/768/1024/1536/3072…col.add(vectors, ids=ids, metadata=metadata)          # bring your own vectors (embedding-agnostic, any dimension)hits = col.search(qvec, where={"tenant_id": "acme"}, top_k=10, explain=True)

The runtime is required for execution; the embedder is optional — col.add(vectors, …) and col.add_texts(…) both need the runtime, but only *_texts needs an embedder (bring your own via telys.embedding.CallableEmbedder, or use the on-device bigram embedder).

For local development, install the runtime as a package instead of via the CLI:

bash
pip install "telys[runtime]"   # or: pip install telys-runtime

MCP server

[MCP registry]

telys mcp runs Telys as a Model Context Protocol server over stdio, exposing 19 tools — the full memory surface (CRUD, filtered queries, lexical search, compaction / IVF / tuning, plus a repo auto-indexer) — to any MCP client (Claude Desktop/Code, Cursor, Codex, Qwen Code, …). Everything is local and offline. Introspection (initialize/tools/list) needs no credentials; executing memory tools requires the one-time free telys login (device authorization, free community plan) — fully offline thereafter, no API key in the client config.

bash
pipx install telystelys login            # free device license + signed on-device runtimetelys runtime verify   # confirm the runtime the tools drive is presenttelys mcp              # serve JSON-RPC 2.0 (protocol 2025-06-18) on stdin/stdout

You rarely start it by hand — telys mcp install writes the server entry into your clients — or add this block to a client's MCP config yourself:

json
{  "mcpServers": {    "telys": {      "command": "telys",      "args": ["mcp"]    }  }}

Registry: io.github.thyn-ai/telys on the Official MCP Registry. Server source: packages/telys-sdk/telys/mcp.py. MCP docs: docs.telys.ai/mcp.

ToolWhat it doesRequired arguments
telys_searchSemantic + lexical search over a memory collectioncollection, query
telys_addAdd text documents (collection auto-created if absent)collection, texts
telys_create_collectionCreate a collection (fix name + partition key up front)name
telys_list_collectionsList saved collections in the active store—
telys_statsRow counts and index state for one collectioncollection
telys_upsertAdd-or-replace rows by id (the idempotent write)collection, texts, ids
telys_updateRe-embed/replace EXISTING ids (strict: ids required)collection, texts, ids
telys_deleteTombstone rows by idcollection, ids
telys_idsList live external ids, optionally where-scopedcollection
telys_countLive row count, optionally where-scopedcollection
telys_getExact row lookup by id (re-reads repo source slices)collection, ids
telys_search_lexicalOn-device BM25 keyword searchcollection, query
telys_compactFlush tombstones, merge delta into the base layoutcollection
telys_build_ivfBuild per-partition IVF indexes (recall-floor calibrated)collection
telys_build_lexicalFit the BM25 lexical indexcollection
telys_tuneProduce (and optionally apply) a TuningPlancollection
telys_index_repoWalk + chunk + ingest a repo, incrementally refreshed—
telys_repo_searchSearch the auto-indexed repo (re-indexes first, always fresh)query
telys_workspace_infoReport the configured workspace, repo_id and file count—

Every tool ships a rich description (what it does, when to use it, parameters with defaults, failure modes) and static MCP annotations (readOnlyHint / destructiveHint / idempotentHint / openWorldHint) — openWorldHint: false throughout: the server makes no network calls. Listing the tools needs no credentials and no runtime: initialize + tools/list answer from the static tool registry; only actual tool calls load the signed runtime lazily.

Documentation

Full documentation lives at docs.telys.ai:

Links

Source: README.md at commit 7ccd8cf

Tools

19

telys_add

Add text documents to a Telys memory collection: each text is embedded on-device, inserted as a new row, and persisted; the collection is auto-created (partition_by='scope') when absent. Use to store new memories. Required: collection, texts. Optional: ids (one per text; auto-generated when omitted — an id that already exists raises a conflict, so use telys_upsert to replace) and metadata (one object per text; set a `scope` value to route partitions and enable where-filtering later). Fails on empty texts, ids/texts length mismatch, or duplicate ids. NOT idempotent: omitted ids are freshly generated per call, so a repeat call inserts additional new rows.

Parametersidstextsrequiredmetadatacollectionrequired

telys_create_collection

Create a named Telys memory collection in the active store, wired to the built-in embedder. Optional — telys_add auto-creates on first write — but use it to fix the name and partition key up front. Required: name. Optional: partition_by (default 'scope'; a single metadata key name — compose compound keys into one string yourself). Collections created through MCP are automatically text-retaining and lexical-capable: stored text is returned by telys_get and telys_search, and telys_build_lexical / telys_search_lexical work out of the box. The new collection is built but NOT persisted, so telys_list_collections shows it only after a mutating tool (telys_add, telys_upsert, …) writes to it. Repeating with the same name returns the existing collection unchanged.

Parametersnamerequiredpartition_by

telys_list_collections

List the Telys memory collections saved in the active store ($TELYS_MEMORY_PATH, default ~/.telys/memory). Use to discover what exists before searching or writing. Takes no arguments and returns sorted names; an empty store yields an empty list, not an error. Collections created but never written to by a mutating tool do not appear — if names you expect are missing, check the client points at the right store.

Takes no parameters.

telys_stats

Report stats for one Telys memory collection: name, partition key name, and live external-id count, plus runtime-provided counters (row counts, dimension, index state) that vary by runtime version. Use to confirm a collection exists and gauge its size. Siblings: telys_list_collections enumerates collections; telys_count returns cardinality only. Required: collection. Fails when the collection does not exist.

Parameterscollectionrequired

telys_upsert

Add-or-replace text rows by external id: new ids are inserted; existing ids are re-embedded and replaced as a versioned update (never a duplicate physical row), then persisted. Use when the caller owns the ids and a repeated call must converge instead of conflicting — this is the idempotent write path. Required: collection, texts, ids (explicit JSON null is treated as omitted = plain telys_add with generated ids). Optional: metadata (one object per text) and partition_by (default 'scope'; the collection is auto-created when absent). Fails on ids/texts length mismatch.

Parametersidsrequiredtextsrequiredmetadatacollectionrequiredpartition_by

telys_update

Replace the vectors/metadata of EXISTING ids by re-embedding new texts, then persist. Use for deliberate corrections to known rows. Required: collection, texts, ids — strict by contract: missing or null ids fail with 'update requires ids' (use telys_upsert to insert-or-replace instead). Optional: metadata (one object per text; the collection's partition key is defaulted when omitted). Fails when the collection does not exist or on ids/texts length mismatch.

Parametersidsrequiredtextsrequiredmetadatacollectionrequired

telys_delete

Tombstone rows by external id so they no longer appear in queries or id listings; the store is persisted and the space is physically reclaimed later by telys_compact. Use to forget memories. Required: collection, ids. Repeating the same delete is a no-op. Fails when the collection does not exist.

Parametersidsrequiredcollectionrequired

telys_ids

Return the live (non-tombstoned) external ids in a collection, optionally scoped by a where filter — enumeration without ranking. Siblings: telys_search returns ranked hits with scores for a query; telys_count returns just the cardinality. Required: collection. Optional: where — a single-key equality filter such as scope=project:acme (one key only). Result: the full id list in a single response (no pagination); the order is the engine's internal row order — neither sorted nor insertion order — so sort client-side when a stable display order matters. Fails when the collection does not exist or when `where` carries more than one key.

Parameterswherecollectionrequired

telys_count

Return the live row count (post-tombstone) for a collection — cardinality only, optionally where-scoped. Siblings: telys_stats for aggregate stats (partition key, live id count, runtime index counters); telys_ids to enumerate the ids themselves. Required: collection — the name of an existing collection in the active store; the call fails when it does not exist (write first via telys_add or telys_create_collection). Optional: where — a single-key equality filter (one key only); more than one key fails.

Parameterswherecollectionrequired

telys_get

Exact row lookup by external id — no similarity search. Returns one entry per requested id with a found flag plus stored metadata; for auto-indexed repo rows the exact source slice is re-read from disk via the row's path + line range. For memory rows created through MCP, the stored raw text is also returned. Use to fetch known rows or read the code behind a telys_repo_search hit. Required: collection, ids. Optional: with_metadata (default true) and with_text (default true; re-read the source slice for repo-index rows, or return stored text for memory rows). Unknown ids come back as found:false, not an error; fails only when the collection does not exist.

Parametersidsrequiredwith_textcollectionrequiredwith_metadata

telys_search_lexical

On-device BM25 lexical (keyword) search — exact-term matching for identifiers and rare tokens where semantic search is fuzzy. Sibling: use telys_search for embedding-ranked (vector) retrieval; this tool is the BM25 path, no embedding involved. Collections created through MCP are lexical-capable; run telys_build_lexical once after bulk ingestion, then telys_search_lexical returns hits including the stored text. Required: collection, query. Optional: top_k (default 5), where (single-key equality filter), explain (default false; include per-hit score explanations). Fails when the collection does not exist or the lexical index was never built.

Parametersqueryrequiredtop_kwhereexplaincollectionrequired

telys_compact

Flush tombstones and merge the delta segment into the base layout, physically reclaiming space from deleted/updated rows; the store is persisted. Use after large delete or update batches. Alternatives: telys_delete to remove rows, telys_tune for index tuning. Required: collection. Repeating with no pending changes is a no-op. Fails when the collection does not exist.

Parameterscollectionrequired

telys_build_ivf

Build per-partition IVF indexes and calibrate nprobe to a recall floor — approximate search for partitions that have outgrown exact scans. Maintenance sibling of telys_compact (physically reclaim space from deletes) and telys_tune (plan and optionally apply tuning automatically). Required: collection. Optional: min_rows (default 20000; only partitions with at least this many rows get an IVF index — smaller ones keep exact scans) and target_recall (default 0.98). Fails when the collection does not exist; needs the optional faiss dependency — the error names the fix (pipx: `pipx inject telys faiss-cpu`; venv: `pip install faiss-cpu`).

Parametersmin_rowscollectionrequiredtarget_recall

telys_build_lexical

Fit the BM25 lexical index over the collection's retained tokens and persist it. Collections created through MCP are lexical-capable, so this works out of the box after ingestion. This builds the lexical BM25 index; telys_build_ivf builds the IVF vector index. Run after bulk ingestion and before telys_search_lexical. Required: collection. Optional: k1 (default 1.8; term-frequency saturation) and b (default 1.0; document-length normalization). Fails when the collection does not exist.

Parametersbk1collectionrequired

telys_tune

Produce a TuningPlan for a collection via its Tuner, and optionally apply it. Use to inspect or apply index/maintenance recommendations. Sibling: telys_build_ivf builds the IVF index directly; this tool plans and optionally applies tuning. Applying (dry_run=false) sets the default target recall + exact↔quantized crossover and IVF-builds oversized partitions (already-built ones are skipped) — instant settings plus a faiss-requiring build that grows with partition size, applied live in-process (this handler does not persist to disk) and not atomically, so a mid-apply failure can leave earlier settings in place. Verify the after-state with telys_stats. Required: collection. Optional: dry_run (plan-only vs apply; values on the parameter). Fails when the collection does not exist.

Parametersdry_runcollectionrequired

telys_index_repo

Walk a repo directory — respecting .gitignore on git checkouts, else skipping common build/dep dirs; binaries and symlinks escaping the root are refused — chunk every text file, and ingest the chunks into a collection for telys_repo_search. Incremental: re-calls re-fingerprint each file (size, mtime), re-embed only changed files, tombstone removed ones, and no-op fast when nothing changed. Routing: telys_repo_search queries the index; telys_add/telys_upsert store manual memories. Returns status (built/refreshed/hit), repo_id, and file/chunk counts. All arguments optional: path (repo root; default: the server workspace, else CWD), collection (default 'repo_symbols'), mode ('windowed' default or 'file'), window_lines (48), window_overlap_lines (8), max_file_bytes / max_files / max_seconds (0 = unlimited), force (default false; rebuild every file). Fails when path is not a directory or the collection already exists with a partition key other than repo_id.

Parametersmodepathforcemax_filescollectionmax_secondswindow_linesmax_file_byteswindow_overlap_lines

telys_workspace_info

Report the server's configured workspace: resolved path, repo_id, the auto-index collection name, tracked file count, and whether the fingerprint cache is persisted across restarts. Use to verify which repo telys_repo_search will index before calling it. Takes no arguments; the workspace fields are null when no workspace is configured — that is a report, not an error.

Takes no parameters.

Version history

5
  1. v0.1.14LatestOct 26, 2026
  2. v0.1.9Sep 25, 2026
  3. v0.1.6Sep 24, 2026
  4. v0.1.5Sep 23, 2026
  5. v0.1.4Sep 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

Other Memory integrations