
Tinycontext
io.github.TinySuiteHQ由 GitHub 帳號 TinySuiteHQ 發布v0.5.4更新於 Oct 29, 2026
Token-light local memory with SQLite hybrid retrieval for MCP agents.
概覽
給 AI 代理用的本機記憶層:把記憶存進 SQLite,並以 BM25 與向量混合檢索只回傳符合 token 預算的相關內容。
- 可以做什麼
- 儲存長期事實、偏好、決策與研究筆記,支援情境記憶與全域個人檔案兩種類型
- 依語意查詢召回記憶,或依時間新到舊召回以維持上下文連續性,並依 token 預算裁剪
- 分頁瀏覽、依日期或關鍵字篩選、依冷門程度排序,並讀取單筆記憶全文
- 依參照更新或刪除單筆記憶
- 可選擇把管理檢視(記憶表格、概覽、服務統計)以 MCP 資源形式提供
- 適用情境
- 適合希望助理跨工作階段記住資訊、又不想依賴託管記憶服務的情境,尤其在上下文視窗或 token 成本敏感時。也適合希望檢索完全留在本機的本機或自架代理。
- 執行需求
- 以本機 stdio 程序執行,通常透過 uvx 與 Python 3.12 啟動,也可用 Docker 映像提供 HTTP。預設不需帳號或 API 金鑰;首次啟動會下載 ONNX 嵌入模型包,SQLite 資料庫在首次使用時建立。選用的可觀測性設定使用 OTEL_EXPORTER_OTLP_ENDPOINT 與 OTEL_EXPORTER_OTLP_HEADERS。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Tinycontext,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
TinyContext
Context that fits your local LLMs.
TinyContext is a token-light local memory layer for AI agents. It recalls only the memories that fit your token budget.
Documentation · Quick start · Python · Discord
[Website] [PyPI version] [PyPI Downloads] [CI] [License: MIT] [Python] [Release] [Last Commit] [Docker Pulls] [Discord] [MCP Server] [FastAPI]
TinyContext stores concise memories and their embeddings in SQLite, ranks them with hybrid BM25 and dense retrieval, and returns only the context that fits the requested token budget.
No hosted account. No giant context dumps. No required vector database.
TinyContext is part of TinySuite, small, practical open-source tools for AI workflows, built in Europe and maintained with care.
Choose a tier
The Python library contains the memory engine. MCP, FastAPI, and Docker are
adapters around the same save_memories, recall_memories, and
delete_memory operations.
One-command MCP
Add TinyContext to any stdio MCP client:
The no-argument tinycontext command runs stdio MCP. On its first launch,
TinyContext downloads the selected ONNX embedding bundle into its per-user data
directory. The database is created lazily on the first save or recall. Later
launches reuse both local assets.
Check the resolved configuration and storage readiness with:
TinyContext exposes six tools:
- Use
save_memoriesfor durable facts, preferences, decisions, and research notes. Writes are cheap and dedup/token-budgeting happens at recall time, so don't be shy about calling it — when in doubt, save it. - Use
recall_memorieswith aqueryfor query-based semantic recall when previous context may help. - Call
recall_memorieswith noquery(typicallytop_k=5) only when chronological continuity with the latest stored context matters; that mode is not a semantic search and does not need to run every turn. - Use
list_memoriesto browse the store newest-first, with pagination (limit/offset) and an optionalsince/untildate range oncreated_at. It does no embedding calls, no ranking, and no token-budget cutoff, so it's the answer to "what's actually in there" and "what did we do last week" — ground oncurrent_timefrom a recent recall/list response, compute the range, and page withoffsetuntilhas_moreis false. It's also how to see the rest of arecall_memoriesresponse that a token budget cut short (that response's<notice>says so, alongsidematched_count).sort="stale"lists the least-recalled, oldest memories first, to find ones worth merging withupdate_memoryor removing. - Use
get_memoryto read one memory's full content byref/id, bypassing ranking — e.g. afterlist_memoriesshows a truncated preview. - Use
delete_memoryto forget or correct a previously saved memory (find itsrefviarecall_memoriesorlist_memoriesfirst).
Each memory saved via save_memories can set kind to "episodic" (default)
or "profile". Profile memories are for durable identity/preference facts —
what to call the user, what they call you, how they like to work — and are
global to the store regardless of session_id. They're never semantically
ranked or searched; instead, every recall_memories call (query or no-query
alike) automatically attaches the full profile pool, trimmed to its own
profile_max_tokens budget, so there's no separate call or "remember this"
prompt needed to see them. To correct a profile fact, recall first to find
its ref, then use update_memory rather than saving a second, conflicting
one.
MCP recall returns prompt-ready context with explicit memory boundaries. The profile block (when non-empty) precedes the ranked/recent block:
Recent recall uses an explicit mode and newest-first indexes without fabricated semantic metadata:
ref is a short, deletion-safe reference derived from the memory's id --
stable across recalls, unlike index, which just reflects the current
ranking. Pass it straight to delete_memory; the full id also still works.
Python and FastAPI semantic recall remain structured and include relevance and
retrieval scores. Recent recall instead returns mode: "recent", the current
UTC time, newest-first rank, id, ref, creation timestamp, and token counts;
it omits semantic query, relevance, and similarity fields.
Python library
Install only the transport-independent core:
Programmatic configuration does not read environment variables or depend on the
checkout. Passing no config uses the per-user data directory returned by
platformdirs.
Docker
Run the published image as an MCP server over Streamable HTTP:
Connect an MCP client to:
The data volume persists /data/memories.db and /data/models.
Hosted multi-user deployment
compose.quickstart.yaml is deliberately a local, single-user example. Do
not expose it directly to multiple users. For an authenticated hosted service,
use compose.hosted.yaml behind a reverse proxy:
The proxy is the only component on tinycontext-proxy that may reach the
container. It must authenticate the caller, strip any incoming
X-TinyContext-User-Id header, and inject that header with a stable verified
user ID. Set TINYCONTEXT_TRUSTED_PROXY_CIDRS to the proxy's direct Docker or
private-network CIDR. TinyContext rejects requests from other peers and never
accepts a user ID in an MCP tool or API request body.
The proxy also sends X-TinyContext-Proxy-Token: <TINYCONTEXT_TRUSTED_PROXY_TOKEN>
on every request (at least 32 bytes; hosted mode refuses to start without it).
The address alone does not prove a request came from the proxy: anything else
that can send from that network, such as another container or a local program
when TinyContext listens on loopback, could otherwise name any user. A request
from a trusted address with a missing or wrong token is refused like one from
an untrusted address. Keep the token as secret as the proxy's own credentials.
Hosted tenancy stores each user in a separate SQLite file under
TINYCONTEXT_TENANT_STORE_DIR; filenames are HMAC-derived and do not expose
the source user ID. Existing /data/memories.db data is not migrated, because
it has no safe ownership attribution. session_id remains an optional scope
inside a single user's store.
The identity is checked on every MCP message, not once per session. A proxy or chat front end may reuse one MCP session for several users, and each message still lands in the store of the user its own header names.
Management views
A client UI (TinyWebUI's MCP panel, for one) can browse, search, edit and
delete a user's memories through the same MCP connection the tools use. Set
TINYCONTEXT_MANAGEMENT=on, and the server adds MCP resources following the
tinysuite.manage/1 contract: a manifest
(tinycontext://manage/manifest, media type
application/vnd.tinysuite.manage+json) that names the views, and the views
themselves.
- Memories: a paged table with keyword search (the BM25 index recall
uses, ranked best match first), type and order filters, and full detail per
memory. Edits and deletes call the ordinary
update_memoryanddelete_memorytools. - Overview: counts by type, never-recalled memories, and time bounds.
- Service (operators only): store count, disk use, embedding setup.
Every view shows only the caller's own store, under the same rules as the tools. Management is off by default. Over HTTP it also needs an authenticated caller, or the server refuses to start:
- In hosted mode, the trusted proxy's identity opens each caller's own user views, token or not: the proxy has already proven who they are.
TINYCONTEXT_MANAGEMENT_TOKEN(24+ characters), sent asAuthorization: Bearer <token>, opens the Service view, and outside hosted mode every management read. It is the operator's, so a proxy can send it on its own connection only and never on a user's.
A local stdio client is the operator and sees every view.
Stop the service with:
For a local image build:
The optional FastAPI profile uses the same image:
- MCP Streamable HTTP:
http://localhost:8000/mcp - FastAPI:
http://localhost:8001
How recall works
- Generate embeddings locally with the selected ONNX model.
- Save text, metadata, and float32 embedding BLOBs in the same SQLite row.
- Filter by
session_id, rank lexical matches with BM25, and calculate cosine similarity in SQLite throughsqlite-vec. - Fuse both rankings with weighted reciprocal rank fusion (RRF), normalized to
0..1using the same scoring convention as TinySearch. - Apply the optional normalized RRF cutoff, then return the highest-ranked memories within the count and token budgets.
Relevance labels summarize the normalized hybrid score: high is at least
0.90, medium is at least 0.75, and lower admitted results are low.
Existing TinyContext databases are upgraded in place with nullable embedding columns. The first recall backfills embeddings for legacy rows; no database migration command or separate vector service is required.
Benchmarks
Numbers below come from scripts/benchmark_index_recall_speed.py and
scripts/benchmark_token_savings.py, run against an isolated, throwaway
SQLite store (never a real database) with the default balanced ONNX embedding
model. Reproduce them yourself:
Write throughput and recall latency
Recall stays flat well past a few thousand memories: p95 only grows from 9.9ms to 12.5ms across a 200x increase in corpus size (100 to 20,000). Each retriever (BM25, dense) hands over its own top-scoring candidates rather than every stored memory being hydrated and ranked on each call; only that bounded, unioned pool is fused and scored. There's still no ANN index underneath — SQLite has to evaluate every candidate row to find those top-scoring matches, so this is bounded brute force rather than sublinear search, and will eventually bend upward again well beyond the sizes tested here. Write throughput holds steady regardless of corpus size.
Token savings vs. a naive "resend everything" agent
Against 300 synthetic memories and 8 queries: 96.7% fewer tokens than concatenating every stored memory raw, or roughly $16.42 saved per 1,000 recalls at $3/MTok input pricing (Claude Sonnet 5).
How this compares to the market
Published numbers from Mem0 (~90%+ token reduction, ~200ms p95 latency) and Zep (~65–200ms p95 latency) put TinyContext at or ahead on token compaction, and ahead on latency at the corpus sizes tested here (single-digit-to-low-teens ms p95 vs. 65-200ms). That's not an apples-to-apples claim, though — those figures come from real conversational benchmarks (LoCoMo, LongMemEval) with retrieval-accuracy grading in the loop, run against hosted vector databases at larger scale than tested above.
Retrieval accuracy — an open question, not a claim
scripts/benchmark_recall_accuracy.py plants 15 distinct facts inside a
growing pool of filler memories and queries each with a paraphrase, checking
whether hybrid recall returns the right memory id. Locally this comes back
at 100% recall@k and MRR 1.00 from 100 up to 5,000 filler memories — but
the planted facts are semantically distinct from the filler, so this mostly
shows the mechanism works, not that it holds up against confusable,
near-duplicate memories or a real labeled benchmark like LoCoMo/LongMemEval.
This is the one number here we're not standing behind as-is. If you run a harder or larger-scale accuracy eval against TinyContext — adversarial near-duplicates, a real conversational dataset, whatever — we'd genuinely like to see it, good or bad. Open an issue or a PR with what you found.
LoCoMo and LongMemEval (retrieval only)
scripts/benchmark_locomo.py and scripts/benchmark_longmemeval.py run
TinyContext against the two standard conversational-memory datasets, grading
whether recall_memories returns the turns or sessions the dataset labels as
evidence, within the configured token budget and top-k. They use no LLM, so the
results are deterministic and need no API key. Datasets are downloaded to
.cache/benchmarks/ on first run.
These are retrieval metrics, not the LLM-judged answer accuracy that Mem0, Zep and Letta publish, so they are not directly comparable to those figures.
Results: not yet run.
FastAPI
The optional HTTP API mirrors the MCP tools.
Install and run it directly:
When TINYCONTEXT_TENANCY=proxy-header is enabled, these endpoints require
the same trusted-proxy identity as hosted MCP. The health endpoint remains
available for liveness checks.
Save request
kind defaults to "episodic". Items with kind: "profile" are stored
globally (ignoring session_id) and returned in every recall response's
profile field rather than memories.
Recall request
Recent recall request
Omit query (or send it blank) to switch /recall_memories into chronological
mode:
This also accepts GET /recall_memories?session_id=optional-session&top_k=5.
The response uses mode: "recent" and contains only durable memory fields,
recency ranks, timestamps, token counts, and the configured token-budget result.
List request
limit defaults to 20 (capped at 200). The response is newest-first and
includes total_count, returned_count, and has_more for pagination, plus
a preview_truncated flag per entry (content is truncated to a short
preview; fetch the rest with /get_memory). This also accepts
GET /list_memories?since=...&until=...&limit=...&offset=.... Add
search (up to 200 characters) to keep only keyword matches from the BM25
index recall uses: every word must appear, and the last may be a prefix
(pyth finds python). Searched results default to sort=relevance, best
match first; recent and stale still apply.
Get request
Also accepts GET /get_memory?memory_id=fee1180f1c8f. Returns the memory's
full, untruncated content plus its lifecycle fields (recall_count,
last_recalled_at, superseded_by).
Error codes
OpenTelemetry
TinyContext can emit vendor-neutral OpenTelemetry traces and metrics over OTLP.
Telemetry is optional and disabled unless you configure a provider or OTLP
exporter. The Python library always uses the caller's current OpenTelemetry
providers; the standalone MCP and FastAPI entry points configure providers
from standard OTEL_* environment variables and flush them on shutdown.
Install the optional exporter dependencies for local MCP or Python services:
For uvx, include the extra in the package spec:
The Docker image includes the telemetry extra, but still exports nothing until you set OTLP configuration:
TinyContext supports the standard OTLP HTTP/protobuf and gRPC exporters. Signal specific settings take precedence over common OTLP settings, so the usual OpenTelemetry knobs work:
Emitted spans cover the memory lifecycle and internal stages, including
tinycontext.save_memories, tinycontext.recall_memories,
tinycontext.memory_recall, tinycontext.embed_texts,
tinycontext.rank, SQLite store fetch/write operations, update, delete,
list, and background reindex work. They are created below the transport layer,
so MCP and FastAPI calls produce the same core spans. Internal worker threads
inherit the active trace context where practical.
Metrics use the same names as TinySearch:
Attributes are intentionally small and low-cardinality. TinyContext records
operation names, candidate/result counts, SQLite as the database system,
known embedding presets, token counts already present in API responses, and
standard error status plus error.type on failures. Raw memory contents,
queries, prompts, session IDs, database paths, credentials, collector headers,
exception messages, and stack traces are not exported by default.
Where current OpenTelemetry semantic conventions fit, TinyContext uses them:
gen_ai.operation.name for memory and embedding operations,
gen_ai.memory.record.count for memory create/search/update/delete counts,
gen_ai.request.model for known embedding presets, and standard span error
status with error.type. MCP semantic spans are reserved for MCP protocol
instrumentation; TinyContext's spans are internal core spans that work with
both MCP and FastAPI transports. The relevant upstream references are the
OTLP exporter configuration,
error recording semantic conventions,
GenAI span conventions,
and GenAI MCP conventions.
Configuration
The core defaults are:
On macOS and Linux, memory databases (the single store, and each user's store
in hosted mode) are created owner-only (0600), in a folder created 0700;
an older store left readable by others is tightened on open. A folder you
point it at that already exists keeps its own permissions. On Windows the
per-user AppData folder already keeps them private.
| embedding_batch_size | 32 | Local ONNX inference batch size |
| recall_rrf_cutoff | 0.0 | Minimum normalized hybrid RRF score; zero disables filtering |
| recall_dense_weight | 0.5 | Dense contribution to weighted RRF |
| recall_rrf_k | 60 | RRF rank constant |
| recall_access_weight | 0.0 | Recall-frequency contribution to weighted RRF |
| dense_query_prefix | empty | Optional text prepended before embedding queries |
| dense_document_prefix | empty | Optional text prepended before embedding memories |
| dedup_similarity_threshold | 0.95 | Cosine similarity at/above which a new save is skipped as a duplicate |
| dedup_review_similarity_threshold | 0.80 | Cosine similarity at/above which a saved memory gets a similar_to notice instead of being skipped |
| save_length_notice_tokens | 800 | Content length above which a saved memory gets a "consider splitting" notice |
Server processes look for context_config.json in the per-user TinyContext
configuration directory. A relative memory_db_path inside a JSON config is
resolved relative to that file.
Changing embedding_model (or its dimensions) after memories already exist
doesn't require a manual re-embed: save_memories/recall_memories detect
the mismatch and start a background re-embed job automatically. While it's
running, tool responses include a notice field with progress and an ETA
instead of blocking the call until the whole store is caught up.
Environment overrides:
An existing checkout-local database remains usable:
Why TinyContext
- No vendor in the loop. No account, no required API key, no per-request billing, no hosted memory service. Memories stay in a SQLite file you own.
- Built around token efficiency. Ranking and budget trimming happen locally, so only the memories that fit the budget reach the model.
- No required vector database. Embeddings and BM25 live in the same SQLite
row;
sqlite-vechandles similarity. - Useful without paid infrastructure. Local ONNX embeddings are the default.
- Works where agents already work. Use MCP over stdio or Streamable HTTP, Python, FastAPI, or Docker.
Part of TinySuite
TinySuite is a product suite built around one idea: agents should spend tokens on useful work, not operational overhead.
Each tool focuses on a different part of the agent workflow. TinyContext handles the memory layer by recalling a small, ranked set of memories instead of resending history.
When not to use TinyContext
TinyContext is intentionally lightweight. Use a hosted memory service or a full vector database when you need:
- very large shared corpora or horizontal scaling
- managed hosting with an SLA
- enterprise access controls and audit trails
Development
TinyContext supports Python 3.12 and newer. CI tests Python 3.12, 3.13, and 3.14 across Linux, macOS, and Windows.
Source-checkout compatibility shims remain available:
Entrypoints
tinycontext.save_memories,tinycontext.recall_memories,tinycontext.list_memories,tinycontext.get_memory,tinycontext.update_memory, andtinycontext.delete_memory: Python APItinycontext/tinycontext mcp: stdio MCPtinycontext serve: Streamable HTTP MCPtinycontext doctor: configuration and storage readinesstinycontext.servers.fastapi_server:app: optional FastAPI application
Security
Release images are scanned with Trivy, run as a non-root user, and signed with Cosign. See SECURITY.md for details and how to report a vulnerability.
About
TinyContext is built and maintained from Vienna, Austria. The goal is simple: useful software, small enough to understand, and maintained long enough to rely on. See SUPPORT.md for the support policy and Releases for the release history.
Community
Questions, ideas, and bug reports are welcome:
License
來源:README.md,提交 68854ed
工具
0版本歷史
3- v0.5.4最新Oct 29, 2026
- v0.5.1Oct 8, 2026
- v0.5.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分