Meko provides a shared, persistent memory and knowledge layer for AI agents and teams. Store and retrieve conversation history, extract searchable facts, manage long-term memories, upload and search knowledge-base documents, share context across agents and teammates, and track agent execution traces across sessions and AI platforms.
Try asking
Encrypted at rest, isolated from the model
Resolved from an AES-256-GCM vault at the moment of the call and attached to the request — the model never sees the secrets.
Hybrid search across the knowledgebase. Invoke when the user asks to **search**, **find**, or **look up** information in their knowledgebase or uploaded documents. Combines semantic vector similarity with keyword full-text search over the ``datapacks.knowledge_bases`` table; each result is tagged with a ``match_type`` of ``"semantic"``, ``"keyword"``, or ``"hybrid"``.
Permanently delete ONE knowledge-base file (document) from a datapack. This cannot be undone: the document's chunks and metadata are removed in one transaction; deletion of the stored file itself is BEST-EFFORT — the response's ``s3_deleted`` says whether it happened, so report honestly when it is false (chunks gone, stored file possibly still present). Use ONLY when the user explicitly asks to delete/remove a knowledge-base file, and confirm with them before calling. Obtain ``document_id`` from ``knowledgebase_search`` hits (each hit carries ``document_id``; hits do NOT carry a filename) — never guess an id. When confirming, echo the id and the matched chunk text; the authoritative filename list is the platform's documents API / the Meko UI, not search hits. Errors carry the HTTP ``status``: 403 (not the datapack owner, a maintainer, or the file's uploader — report and stop), 409 with code ``DOCUMENT_PROCESSING`` (still indexing — wait for it to finish, then retry), 404 (no such document in this datapack).
One retrieval call across the conversation cache, memory, and the knowledgebase — queries every source ``force_source`` allows **in parallel** and returns each one's results in its own labeled bucket. Nothing here suppresses another source: a conversation-cache hit no longer hides a KB document that supersedes it, and a "good enough" memory no longer skips the KB either. Any source can legitimately come back empty — that means nothing relevant, not a broken call. Each source's own floor: - Conversation: CONVERSATION_HIT_DISTANCE gates the cache lookup itself (unchanged). - Memory: no absolute floor on the ``auto`` path. The public ``memory_search`` tool applies the runtime ``memory_search_min_score`` floor because it answers from memory alone; on the ``auto`` path this call keeps the full mem0 list because the KB and conversation buckets sit beside it and let the caller discount a weak row. That preserves hits whose BM25 or entity signal is strong and whose cosine is weak, which a dense floor would veto. The cost is that this bucket can be non-empty for a query with nothing relevant in memory, and nothing absorbs that when the other two sources come back empty. When ``force_source="memory"`` skips the other two sources entirely, this path reapplies the same runtime floor, because memory is then the sole bucket and there is nothing to discount against. - Knowledge base: CONTEXT_SEARCH_KB_MAX_DISTANCE, new here. knowledgebase_search's own trim is relative-to-the-top-match only and always keeps at least one result by design, so this adds the absolute cutoff that lets a genuinely irrelevant query return zero KB chunks instead of one weak one. Set ``force_source`` to query only one source instead of all three — ``"conversation"``, ``"memory"``, or ``"knowledge_base"`` skip the other two entirely (not just filter them from the response), for a caller that already knows which source it wants. ``memory_search`` / ``knowledgebase_search`` remain available directly too, for UUID lookups this tool doesn't surface.
Store a fact as a long-term memory. Invoke when the caller has an explicit fact to persist: the user has asked to save something, the fact appears only in the assistant's output or a tool result, or a prior stored memory must be overwritten with a correction. Memories are stored in a pgvector collection; mem0 also links each memory to the named entities it mentions (people, projects, tools) in a companion entity-store collection, which boosts later searches that name those entities.
Permanently delete a single memory by its UUID. This cannot be undone.
Hybrid search across stored memories. Combines semantic (vector) similarity with keyword matching and an entity boost: memories that mention the specific things named in the query (people, projects, tools) rank higher. Returns matching memories under a "results" key. Results below the runtime ``memory_search_min_score`` setting (mem0's raw, unfused cosine-similarity value — see _sufficiency_score — default 0.2, NOT the fused hybrid score results are ranked by) are dropped as weak matches rather than returned. A query with no memory above that floor can legitimately return an empty ``results`` list even when ``limit`` allowed more. Only this tool applies the floor. It answers from one bucket, so a weak hit becomes the answer. ``context_search`` calls the underlying mem0 search directly and keeps the unfiltered list, because its KB and conversation buckets sit beside the memory one and let the caller discount a weak row.
Retrieve a single memory by its UUID.
List memories for the current datapack, one page at a time. Each call returns one page plus ``total`` and ``total_pages``. To read every memory, call again with ``page`` = 2, 3, ... up to ``total_pages``.
Promote memories into the datapack's shared knowledge base. Moves each memory out of the agent's private mem0 store into the tenant knowledge base + promoted collection, then evicts it from mem0 — a one-way action. Only datapack owners and maintainers may promote; viewers and contributors get a permission error (403 FORBIDDEN).
Overwrite an existing memory's text by its UUID.
Permanently delete memories. This cannot be undone. Deletes every memory that matches ALL of: this ``agent_id``, the calling user, this ``datapack_id``, and, when given, this ``run_id``. Other agents' and other users' memories in the datapack are never touched. Two defaults widen or move the target without saying so in the call: an omitted ``agent_id`` means the ``meko_agent`` bucket, and an omitted ``datapack_id`` means your default datapack. The response's ``scope`` echoes the values actually used.
Create a new conversation to store a chat / dialog exchange. Invoke when the user asks to **store**, **save**, or **log a conversation**, **chat history**, or **query and response**. Creates a conversation container; use ``conversation_add_message`` to append each user-prompt / assistant-response pair.
Add a message (user prompt + assistant response) to a conversation. Call after ``conversation_create`` to append each message. A message represents one interaction: the user's input and the assistant's output, stored as a span inside the conversation's trace. The turn is queued for background writing and the tool returns immediately with the assigned message ID.
Retrieve a stored conversation by ID, optionally including its turns. Use this when the user asks to **recall**, **retrieve**, or **review** a previously stored conversation or chat history. By default returns only metadata and message count. Set ``include_messages=True`` to fetch the full message history with input, output, and reasoning.
List stored conversations for a datapack, ordered by most recently updated. Use this when the user asks to **list**, **show**, or **browse** the stored conversations or chat history for a datapack.
Update a conversation's title and/or metadata.
Permanently delete a conversation and all its messages. This is a hard delete — the conversation and all associated traces are removed from Langfuse. This cannot be undone. Only deletes if the conversation belongs to the specified agent.
Create a new Meko datapack — an isolated database environment with its own agent namespace. Use this when the user asks to **create**, **provision**, or **set up** a new datapack or workspace. This is a Meko platform operation. Direct SQL access against the underlying database is not part of the published MCP surface; use the Meko control plane (UI or REST) for schema and data work that needs raw queries.
List the Meko datapacks visible to the current user. Use this when the user asks to **list**, **show**, or **view all** datapacks, workspaces, or environments. To find one datapack's id by name, call ``datapack_search(query=...)`` instead: it is paged and works for accounts of any size. With no ``query`` and no ``limit`` this returns every datapack, up to ``DATAPACK_LIST_MAX_UNFILTERED`` (default 1000). Above that it returns ``{"error": "too_many_datapacks"}``; use ``datapack_search`` then. With ``query`` and no ``limit`` this returns every match, up to 100. When more than 100 datapacks match, it returns ``too_many_datapacks``.
Search the Meko datapacks visible to the current user, one page at a time. Use this to **find a datapack's id**, to show the user some datapacks to choose from, or to browse an account with many datapacks. It works for accounts of any size; prefer it over ``datapack_list``. - Find a datapack by part of its name: ``query="acme"``. - Find a datapack by its exact name: ``name="Acme Prod"``. - Next page: pass the previous result's ``next_cursor`` as ``cursor``, with the same ``query``, ``name``, ``grant`` and ``sort``. An empty ``next_cursor`` means there are no more pages you can fetch; if ``has_more`` is still true, narrow the search with ``query``. - Set ``include_total=True`` only when you must show "N of M"; it costs an extra count.
Describe a Meko datapack by id, optionally including status info. Use this when the user asks to **describe**, **get details**, or **inspect** a specific datapack. Set ``include_status=True`` to also retrieve agent count, knowledge base count, and provisioning status. The returned JSON exposes count fields aligned with the Meko UI's Datapack Constructs diagram: - ``memory_count``: total memories stored for the datapack (mem0). - ``collective_memory_count``: memories promoted into shared knowledge (UI label: "Collective Memories"). - ``learnings_count``: memories awaiting a promotion decision. - ``knowledge_base_file_count``: uploaded KB documents (UI label: "Knowledge Base"). ``null`` if the datapack status endpoint is unreachable. - ``knowledge_chunk_count``: RAG chunks across all KB documents. Not a user-facing metric — surfaced for debugging RAG behavior. - ``shared_knowledge_count``: ``collective_memory_count + knowledge_base_file_count`` (UI label: "Shared Knowledge"). ``null`` if ``knowledge_base_file_count`` is ``null``. Deprecated: - ``knowledge_count``: **deprecated** alias of ``knowledge_chunk_count``. Preserved for backward compatibility so existing consumers keep working; carries the same value. New callers should read ``knowledge_chunk_count``. The alias is scheduled for removal in a future major/breaking release; that removal will be called out separately.
Update a Meko datapack's name, description, and/or conversation-search opt-out. Use this when the user asks to **rename**, **update**, or **change the description of** a datapack, or to **opt out of** (or back into) conversation-history search. ``name``, ``description``, and ``conversation_search_opt_out`` are all optional; at least one must be provided. If none are provided the tool returns ``nothing_to_update`` without calling the Meko API. Conversation-history search is enabled by default for every datapack — pass ``conversation_search_opt_out=True`` to stop future conversation turns from being embedded into the search cache for this datapack, or ``False`` to re-enable. This never touches turns already embedded. Empty strings are treated as "not provided" — passing ``description=""`` will NOT clear an existing description; that operation is not supported via MCP.
Permanently delete a Meko datapack, dropping its database and all roles. Use this when the user asks to **delete**, **destroy**, or **remove** a datapack. This is irreversible — the database and all data are dropped.
Record a token-usage GENERATION observation under the conversation trace. Lets external callers (the inference gateway, future services) attribute LLM / embedding / extraction token spend so Meko's free-tier counters reflect real usage. Each call writes one Langfuse generation row with ``usage = {input, output, total}`` populated; the matching api_server query (``SumTokenUsageByUserAndAgent``) sums them per user.
Upload a file artifact to this datapack. Use this when an agent has generated a file (report, CSV, PDF, code output, etc.) and wants to persist it in Meko for later retrieval or cross-agent sharing. To make a file's content searchable by meaning instead, use knowledgebase_upload_document. Files smaller than 1 MB are stored inline in the database. Files 1 MB or larger are stored in the datapack's S3 bucket. Uploading the same bytes twice is idempotent — returns the existing artifact.
Retrieve a previously uploaded artifact by its content hash. Use this when the agent needs to read back a file it (or another agent) previously stored via artifact_put. Small files (< 1 MB): content is returned inline as content_base64. Large files (>= 1 MB): the file is written to ~/.meko/artifacts/<hash>/<filename> on the local machine and local_path is returned. The agent should read the file from that path using normal file-reading tools.
Request a presigned S3 URL for uploading a file to this datapack's Knowledge Base. Use this when the file's content should be searchable later: docs, manuals, policies or notes that people or agents will ask questions about. The file is chunked and indexed, and its passages come back from knowledgebase_search and context_search. To keep a file exactly as-is and fetch it back whole (a generated report, a result CSV), use artifact_put instead. If it is not clear whether the user needs semantic search or whole-file retrieval, ask. Before calling this, check that you can send the file's bytes in an HTTPS POST yourself. You need the bytes and a shell or code tool; with one, run `curl -sS -o /dev/null -m 10 -w '%{http_code}' https://s3.amazonaws.com`. Any HTTP status means you can reach S3; a connection, DNS or proxy error means you can't. If you have no shell or code tool, or the check fails, don't call this: the URL can't be used, and on a free or standard account the request holds the file's size against the storage quota for up to 15 minutes. Point the user to the Cloud UI's Add Knowledge instead. This tool does not touch the file's bytes — it only asks api_server for somewhere to put them. To upload, POST the file directly to the returned `url` as multipart/form-data: every key in `fields` as a form field (in order), then the file's bytes as the last field, named "file". With curl: curl -F key=<fields.key> -F policy=<fields.policy> ... \ -F file=@/local/path/to/report.pdf <url> (repeat -F for every key in `fields`, in the order given, file last). A background watcher notices the object once it lands in S3 and registers and indexes it; no follow-up call is needed. Poll knowledgebase_document_status with this response's `key` as its `document_key` to track progress. The URL accepts only a body of exactly `size` bytes whose SHA-256 is `content_hash`, for 5 minutes. If S3 answers 400 EntityTooSmall or EntityTooLarge, `size` was wrong: call this tool again with the right size and upload through the new URL. The earlier URL can never succeed and expires on its own. filename/size/content_hash are validated before api_server is called, so a bad request fails at once with VALIDATION_ERROR. content_head_base64 is required (content_head_base64_required when missing) and is sniffed against the extension before a URL is issued. Send the file's first 3072 bytes, or the whole file if it is shorter: a sample shorter than that, or longer than `size`, is rejected as VALIDATION_ERROR, since it means `size` is wrong. Text files must be UTF-8, since indexing reads nothing else. The sniff only catches obvious mismatches early (a renamed file); api_server checks the stored bytes again regardless. If identical content (by SHA-256) is already in this datapack, the response has already_uploaded=true, an empty url and no fields: nothing needs uploading. If that file's indexing never started or failed, asking again queues it again. On a free or standard account, an issued URL holds its `size` against the storage quota until the file is registered, or for up to 15 minutes if it is never uploaded. FREE_TIER_KB_STORAGE_LIMIT / STANDARD_TIER_KB_STORAGE_LIMIT (status 402) mean there is no room: tell the user to free space or upgrade rather than retrying. Accepted file types (by extension): .pdf, .txt, .text, .md, .json, .csv, .xml, .html, .htm. Maximum size per file: 5 MB on Free, 50 MB on Standard, 60 MB on Pro and above (VALIDATION_ERROR when larger).
Check the upload and indexing status of a file previously uploaded via knowledgebase_upload_document. Poll this with the `key` from knowledgebase_upload_document's response, passed here as document_key, until state reaches a terminal value. Poll every 10-30 seconds; indexing a large PDF can take minutes.
Create a cluster (a Postgres database) in a datapack. Use when the user asks to **create**, **provision**, or **spin up** a database/cluster. The datapack's AMP shared pool is created automatically on the first cluster; a default branch named "main" is created with the cluster. Two shapes: - Default (``with_writer=False``): the cluster only — no compute. Add an endpoint afterwards with ``amp_compute_create``. - ``with_writer=True``: one task also provisions a ``read_write`` endpoint on the ``main`` branch, sized by ``cpu``/``memory`` — a ready-to-connect database (what the UI wizard creates). When omitted, cpu/memory default to 0.5 vCPU / 4Gi (sized to fit the free tier); tell the user the default was applied and offer a different size. This shape reserves compute, so the account's tier vCPU cap applies (defaults: free 0.5 / standard 2 / pro 5 vCPU across all datapacks, deployment-tunable; enterprise uncapped) — exceeding it returns a 402 with a ``*_TIER_CORE_LIMIT`` code. Check remaining budget first with ``amp_core_budget``; on a limit error tell the user their tier's cap (or size down) instead of retrying.
List the clusters (databases) in a datapack. Use when the user asks to **list**, **show**, or **view** databases/clusters.
Get a single cluster (database) by id.
Delete a cluster (database), cascading to its branches and compute. Use when the user asks to **delete**, **drop**, or **remove** a database/cluster. Irreversible. Blocks until the operation completes.
Fork a branch in a cluster — a zero-copy, copy-on-write clone of the data. Use when the user asks to **branch**, **fork**, or **clone** a database so sub-agents can work on isolated copies in parallel.
List the branches in a cluster (the default branch plus its forks).
Get a single branch by id.
Delete a branch, cascading to its compute. Use when the user asks to **delete**, **drop**, or **remove** a branch. A branch that still has child branches is rejected. Blocks until complete.
Provision a compute instance (an endpoint) on a branch. Use when the user asks to **create**, **provision**, or **attach** compute / an endpoint so a branch is reachable. A branch admits at most one ``read_write`` compute instance. Adding an endpoint reserves compute, so the account's tier vCPU cap applies (defaults: free 0.5 / standard 2 / pro 5 vCPU across all datapacks, deployment-tunable; enterprise uncapped) — exceeding it returns a 402 with a ``*_TIER_CORE_LIMIT`` code. Check remaining budget first with ``amp_core_budget``; on a limit error tell the user their tier's cap (or size down) instead of retrying.
List the compute instances (endpoints) on a branch.
Get a single compute instance (endpoint) by id — including its address.
Retire a compute instance (endpoint) on a branch. Use when the user asks to **delete**, **stop**, or **remove** compute / an endpoint. Blocks until the operation completes.
Resize a compute instance (endpoint) — change its CPU and/or memory. Use when the user asks to **resize**, **scale**, or change the **CPU/memory** of an endpoint. At least one of ``cpu`` / ``memory`` is required; an omitted field keeps its current value (no defaults are filled in — unlike the create tools). Blocks until the AMP task completes. AMP requires 8 GiB of memory per vCPU, so growing cpu usually means growing memory in the same call. Growing CPU counts against the account's tier vCPU cap (defaults: free 0.5 / standard 2 / pro 5 vCPU across all datapacks, deployment-tunable; enterprise uncapped) — exceeding it returns a 402 with a ``*_TIER_CORE_LIMIT`` code. Check remaining budget first with ``amp_core_budget``; on a limit error tell the user their tier's cap (or size down) instead of retrying. Memory-only resizes never hit the cap.
Get the account's AMP vCPU budget: cores used across ALL datapacks vs the tier cap. Use BEFORE proposing a sized operation (``amp_cluster_create`` with ``with_writer=True``, ``amp_compute_create``, ``amp_compute_resize``) or when the user asks how much compute they have left. Read-only.
One endpoint, the same key, whichever client you use.
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) · %APPDATA%\Claude\claude_desktop_config.json (Windows)
Replace API_KEY with your own key.
Already have an "mcpServers" section in your config? Just add the server entry inside it.
Discovery, routing, credentials, tool scoping and execution logs all happen at the gateway→connections stay ACTIVE with no work from you
Meko MCP runs through a gateway that holds the credentials, scopes the access and records every call.
Managed auth, hosted MCP servers, and every Meko MCP tool your agent needs.
Free to start.