Files
mnemosyne/validator/README.md
Robert Helewka 97a14fb03a feat(validator): add bare FastAgent + Pallas validator for Mnemosyne MCP
A self-contained sub-project under validator/ that wraps Mnemosyne's MCP
server in a single FastAgent. Use it to confirm — outside of Daedalus —
that Mnemosyne's MCP transport works, every tool registers, args/responses
round-trip, and an LLM can actually drive the tools.

The validator is its own Pallas-consuming project with its own pyproject
(pallas-mcp + fast-agent-mcp), agents.yaml, and fastagent.config.yaml —
matching the pattern used by Iolaus and other Pallas consumers. It does
not import Mnemosyne Python code; it only speaks MCP over HTTP.

The agent never sets workspace_id, so all calls run against the global
scope (libraries with workspace_id IS NULL). Workspace-scoped validation
will come once Daedalus's chat path is wired (Daedalus injects
workspace_id server-side, force-overwriting whatever the LLM produces).

Default model is openai.Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf served by
llama.cpp at nyx.helu.ca:22079/v1. Token provisioning via
`python manage.py create_mcp_token --user <u> --name validator`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 06:53:48 -04:00

4.5 KiB

Mnemosyne Validator

A bare FastAgent + Pallas project whose only purpose is to exercise Mnemosyne's MCP server end-to-end. Use it to confirm the transport works, every MCP tool registers, args/responses round-trip, and the local LLM can actually drive the tools.

This is not a production agent. It does not represent the long-term Daedalus integration — when Daedalus ships, it will inject workspace_id server-side. The validator never sets workspace_id, meaning all calls run against the global scope (libraries with workspace_id IS NULL).

Layout

validator/
├── pyproject.toml                 # pallas-mcp + fast-agent-mcp deps
├── agents.yaml                    # one-agent Pallas topology
├── fastagent.config.yaml          # default_model + mnemosyne MCP server
├── fastagent.secrets.yaml.example # template for the bearer token
├── .env.example                   # OPENAI_BASE_URL etc.
└── agents/
    └── mnemosyne_validator.py     # the FastAgent definition

Setup

cd validator/
uv venv .venv
source .venv/bin/activate
uv pip install -e .

Copy and fill the secrets/env templates:

cp fastagent.secrets.yaml.example fastagent.secrets.yaml
cp .env.example .env

Provision an MCP bearer token

Mnemosyne requires a bearer token when MCP_REQUIRE_AUTH=True (the default). Generate one for your user:

cd ../mnemosyne
python manage.py create_mcp_token --user <username> --name validator

The command prints the token once — paste it into validator/fastagent.secrets.yaml under mcp.servers.mnemosyne.headers.Authorization (keep the Bearer prefix).

Start Mnemosyne's MCP server

The validator hits the Mnemosyne ASGI endpoint, so Mnemosyne's MCP server must be running. From the Mnemosyne project:

cd mnemosyne/
uvicorn mnemosyne.asgi:app --host 0.0.0.0 --port 22091 --workers 1

By default the validator points at http://localhost:22091/mcp. If your Mnemosyne is on another host, override mcp.servers.mnemosyne.url in fastagent.secrets.yaml.

Run the validator

The mnemosyne-validator script is a thin alias for pallas:

# Start with the registry (Pallas mode):
mnemosyne-validator

# Or run the agent directly (no registry):
mnemosyne-validator --agent mnemosyne_validator

To chat with the agent directly without spinning up a Pallas registry, use the fast-agent CLI (provided by fast-agent-mcp):

fast-agent go --config-path fastagent.config.yaml --url http://localhost:24301/mcp mnemosyne_validator

What to test

These prompts exercise every Mnemosyne MCP tool. After each, the agent should call the named tool and surface the result.

Prompt Tool What to verify
"Run a health check on Mnemosyne." get_health Returns status: ok if Neo4j + S3 + embedding model are all reachable. degraded if one is down.
"List all libraries." list_libraries Returns the libraries seeded by load_library_types, each with library_type set.
"List collections in library <uid>." list_collections Returns collections inside the named library.
"List items in collection <uid>." list_items Returns items with chunk_count and embedding_status.
"Search the technical libraries for <query>." search Returns ranked candidates with chunk_uid, score, text_preview, library_type.
"Fetch the full text of chunk <chunk_uid>." get_chunk Returns the full chunk text from S3.

If a call errors, the agent surfaces it verbatim — that's the failure mode you want.

Troubleshooting

"Invalid MCP token" — token wasn't provisioned, was provisioned for a different user, or got mangled when pasted. Re-run create_mcp_token and paste again. Tokens are SHA-256 hashed at rest and can't be retrieved later.

"Couldn't connect to Mnemosyne" — the ASGI server isn't running, or it's bound to a different host/port than mcp.servers.mnemosyne.url says. Check curl http://localhost:22091/mcp/health returns {"status":"ok"}.

"No system embedding model configured" in get_healthLLMModel.get_system_embedding_model() returns nothing. Configure the embedding model via the Mnemosyne admin or manage.py before searches will work.

Search returns zero candidates with no error — Mnemosyne is reachable but has no embedded content yet. Upload an item and run embed_item, or use the Daedalus ingest endpoint, before re-testing search.