Skip to main content
Glama

memo

Context7-style docs for your coding agent — free, unlimited, offline, private.

memo is a local MCP server that gives your agent up-to-date library documentation — the same idea as Context7, minus the strings attached: no billing meter, no API key, no rate limit, and your queries never leave your machine.

License: MIT Python MCP Version GitHub release Downloads Stars


Why memo?

LLMs hallucinate APIs. They answer from stale training data — and most "docs tools" fix that by sending your queries to someone else's server. memo fixes it on your machine:

memo

Context7

Price

$0, forever

Free tier is 1,000 API calls/month, then you're blocked (20 bonus calls/day); Pro is $10/seat/month, $10 per extra 1,000 calls (context7.com/plans)

API key

None. Works out of the box

OAuth setup that generates an API key, sent as a Bearer token to mcp.context7.com

Offline

Yes — one pre-built index (~16 MB) and you never touch the network again

Online only

Rate limit

None. Unlimited, always

1,000 calls/month on free tier

Privacy

Queries resolved locally from docs.db; nothing leaves your device (network only on a first-ever cache miss for an unindexed library)

Every query + library name is sent to Upstash's servers

Run anywhere

Python 3.10+, works on ARM (Raspberry Pi / Android-ish devices)

CLI needs Node.js 18+; backend runs on their infra

Honest caveat: nothing here beats a curated docs provider in coverage. memo ships with 65 pre-built libraries today, and adding one is a one-line PR (see Contributing).

Related MCP server: docs-mcp

Quickstart (60 seconds)

Requires Python 3.10+ and uv:

# 1) install
uv tool install git+https://github.com/ngabzar02/memo-server

# 2) optional but recommended: download the pre-built index (65 libraries, ~16 MB)
bash tools/fetch-cache.sh

# 3) register the server, then ask your agent about any library

opencode (opencode.json)

{
  "mcp": {
    "memo": {
      "type": "local",
      "command": ["memo"],
      "enabled": true
    }
  }
}

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "memo": {
      "command": "memo"
    }
  }
}

Cursor (.cursor/mcp.json)

{
  "mcpServers": {
    "memo": {
      "command": "memo"
    }
  }
}

Make sure the memo binary is on your PATH (uv installs it into ~/.local/bin). First call on a never-indexed library takes ~5–60 s (fetch + index once); every call after that is sub-millisecond.

How it works

One SQLite file, no services, no secrets:

  1. resolve_library_id — turns "flask" into candidate library IDs with trust scores: curated aliases → built-in stdlib (py:json, node:fs) → directory.llmstxt.cloud → npm/PyPI (trust = download counts) → GitHub search.

  2. get_docs — cache hit is sub-ms; on miss it crawls the docs (llms.txt → sitemap → README), extracts clean text with trafilatura, and chunks it (256 tokens, 50 overlap).

  3. Hybrid search — BM25 (SQLite FTS5) always, plus cosine similarity over embeddings (bge-small-en-v1.5 via fastembed/ONNX, stored in sqlite-vec) when vectors exist; normalized score fusion, top hits trimmed to a token budget. On-device the MCP path is FTS-first; full vectors come from the pre-built cache or memo --warmup.

  4. versions — version history from npm/PyPI when available.

  5. Pre-built cache — a GitHub Actions workflow ingests all 65 libraries on every push and publishes the resulting docs.db (~16 MB) as a release asset. One download, and you're fully offline.

registry → ingest (llms.txt/sitemap/crawl) → SQLite FTS5 + sqlite-vec
        → hybrid BM25+vector fusion → token-budget trim → MCP stdio → your agent

Data lives at ~/.local/share/memo/docs.db. Query it with any SQLite client.

Benchmark

20 real-world queries (frozen in bench/queries.md: 8 Python, 6 Node/TS, 3 web/frontend, 3 Go/other) scored binary hit/miss against Context7's public API:

#

Query

Target

memo

Context7

1

how to create a route with a path parameter

flask

TBD

TBD

2

how to use async tasks and queues

celery

TBD

TBD

3

how to make a HTTP request with a timeout

requests

TBD

TBD

4

how to paginate results in the sqlalchemy ORM

sqlalchemy

TBD

TBD

5

how to define a custom logger

logging

TBD

TBD

6

how to read a CSV file into a DataFrame

pandas

TBD

TBD

7

how to seed random numbers for reproducibility

numpy

TBD

TBD

8

how to send multipart file upload

httpx

TBD

TBD

9

how to use environment variables in a script

python-dotenv

TBD

TBD

10

how to handle websocket connections

websockets

TBD

TBD

11

how to write a custom middleware

express

TBD

TBD

12

how to validate an email address

validator

TBD

TBD

13

how to use async fs read in a script

fs-extra

TBD

TBD

14

how to emit typed events

node:events

TBD

TBD

15

how to parse a query string

qs

TBD

TBD

16

how to read environment variables

dotenv

TBD

TBD

17

how to render a list with keys

react

TBD

TBD

18

how to add global CSS

nextjs

TBD

TBD

19

how to create a custom hook

react

TBD

TBD

20

how to run a goroutine

go

TBD

TBD

TBD — the benchmark suite lives in bench/bench.py; results will be published to bench/report.md when it runs.

memo vs Context7 vs mcpdoc

memo

Context7

mcpdoc

Price

$0

Free 1,000 calls/mo, then Pro $10/seat (plans)

$0

API key / OAuth

No

Yes

No

Server

Local (stdio)

Remote (mcp.context7.com)

Local (stdio/SSE)

Offline-capable

Yes, pre-built index

No

No persistent index

Pre-built library index

Yes — 65 libs, ~16 MB

Yes (server-side)

No

Library registry / name resolution

Yes — aliases, stdlib, npm/PyPI, GitHub

Yes

No — you configure each llms.txt source manually

Search

Hybrid BM25 + vector embeddings

Server-side retrieval

None — fetches and parses on every call

Version history

Yes (npm/PyPI)

Yes

No

Rate limit

None

Yes (free tier)

None

Your query leaves your device

No

Yes

Only to the docs sites you configured

Language

Python 3.10+

CLI needs Node 18+

Python

Roadmap

  • MCP server: resolve_library_id / get_docs / versions (Context7-compatible API shape)

  • Hybrid retrieval: FTS5 BM25 + embeddings, one-file SQLite

  • Pre-built cache pipeline (65 libraries, GitHub Actions → release asset)

  • Publish bench/report.md — 20-query benchmark vs Context7

  • Publish memo to PyPI (currently install via git)

  • Self-service: add a library at runtime without a PR

  • More libraries every week — the list is cache-libs.txt, one line each

Contributing

One-line library additions, bugs, benchmarks — see CONTRIBUTING.md. Short version: add the library name to cache-libs.txt in a PR; CI builds and ships the new index automatically.

License

MIT — see LICENSE. Use it, fork it, ship it.

Available Tools

3 tools
get_docsA

Get relevant documentation chunks for a library and query. Cache hit: sub-ms. Cache miss: fetch+ingest+index once (~5-60s first time).

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
versionNo
library_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reveals a non-obvious behavioral trait: caching performance (sub-ms on hit, 5-60s on miss first time, with fetch+ingest+index). Since no annotations are provided, this adds valuable transparency about potential delays and internal caching side effects, though it does not fully detail side effects or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundant wording. It front-loads the core purpose and uses the second sentence for performance details, making it efficiently concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 3 parameters and an output schema, the description covers purpose and performance but misses key contextual details like version semantics and usage guidance. It is not fully complete for correct invocation, though output schema likely explains return structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It refers to 'library and query', mapping to library_id and query, but entirely omits the optional 'version' parameter, leaving the agent without clarity on its purpose or when to provide it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Get' with a clear resource 'relevant documentation chunks' and scope 'for a library and query'. It distinguishes from sibling tools 'versions' and 'resolve_library_id' by focusing on retrieving content rather than metadata or ID resolution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. Sibling tools exist, but the description does not mention them or any exclusions, leaving the agent without explicit usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_library_idA

Resolve a library name (e.g. 'flask', 'nextjs') to candidate library IDs with trust scores and latest version. query is optional context to disambiguate.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryNo
library_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and reveals the output includes 'candidate library IDs with trust scores and latest version', which goes beyond schema. It also notes that 'query' can disambiguate. It doesn't discuss side effects or error handling, but for a lookup-style tool this is reasonable behavior disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-structured sentence conveys the core purpose and both parameters without padding. The examples are front-loaded and every clause adds value, making it easily scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential purpose, parameter roles, and high-level output (trust scores, latest version). With an output schema present and only two simple parameters, this is adequate. It lacks explicit guidance on when to use vs. siblings, but that is partially covered by purpose clarity, so a 4 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It defines library_name with examples and explains query as optional disambiguating context. This adds meaningful semantics beyond the empty schema, though it could be more detailed (e.g., constraints on query).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Resolve' and identifies the resource: library name to candidate library IDs. It also gives concrete examples ('flask', 'nextjs') and distinguishes from sibling tools by clearly stating the mapping from name to IDs, which get_docs and versions do not do.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by stating the tool resolves library names and mentions optional query context for disambiguation. However, it does not explicitly state when to prefer this tool over siblings like get_docs or versions, nor does it provide exclusion criteria or alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

versionsA

List known versions for a library (history dari npm/PyPI bila tersedia).

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. It discloses that data comes from npm/PyPI and may be unavailable, which is useful. However, it does not mention behavior for unknown library_id or provide details beyond the output schema, leaving some gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the action and resource. It contains no unnecessary words, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter list tool with an output schema, the description covers the core action and a data availability caveat. However, it lacks explicit usage guidance and parameter details, and with no annotations, the overall context remains somewhat incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. 'for a library' indicates library_id identifies a library, but it does not specify the format, range, or how to obtain the ID (e.g., via resolve_library_id). This adds minimal semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'List known versions for a library' uses a specific verb and resource, and further specifies the data source (npm/PyPI). It clearly distinguishes from sibling tools get_docs and resolve_library_id, which serve different purposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'bila tersedia' (if available) implies when the tool might return no results, but it does not explicitly compare with alternatives or state when to prefer this tool over siblings. Usage context is only partially implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 3 tool updatesv1.0.0
    • First observedget_docs
    • First observedresolve_library_id
    • First observedversions

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: resolve_library_id maps names to IDs, versions lists available versions, and get_docs retrieves documentation chunks. There is no overlap or ambiguity between them.

Naming Consistency4/5

Tool names mostly follow a verb_noun pattern (get_docs, resolve_library_id), but 'versions' is a standalone noun, which is a minor deviation. Overall the names remain clear and predictable.

Tool Count5/5

With only 3 tools, the set is tightly scoped to the core documentation lookup workflow. No unnecessary tools, and all are essential to the purpose.

Completeness5/5

The tool set forms a complete pipeline: resolve a library name to an ID, check available versions, and fetch documentation chunks. There are no obvious gaps for the intended use case.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides a local MCP server for searching and retrieving documentation from 22+ open-source projects, enabling AI coding assistants to access up-to-date docs without network dependency.
    11
    2
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Local MCP server that indexes documentation from URLs/files into a vector database, enabling coding agents to search and use up-to-date library and API documentation.
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ngabzar02/memo-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server