Arthaanu application built on Artha Engine.
Project description
memuron
An Arthaanu application built on Artha Engine.
Documentation: see docs/ for architecture, rich nodes, document ingest, Guardian/spaces, frontend workbench, deployment, Railway agent deploy guide, and troubleshooting.
Mental Model
Keep the engine small and generic. Put product memory behavior here:
- custom Arthaanu types in
memuron/representations.py - encoders that turn raw product input into meaning objects
- lifecycle steps that normalize, merge, dedupe, or retire objects
- projections that replay the event ledger into fast read models
- decoders/API routes that expose product-specific reads
The semantic event ledger is canonical. Projections are derived and rebuildable.
Memuron writes product semantics into that ledger, but keeps the engine model clean:
- memory create/update events stay product-specific:
memory.created,memory.updated - memory/link deletes use the canonical engine event type
delete - Memuron-specific delete meaning lives in metadata as
domain_event_type = memory.deletedorlink.removed - request identity is audit metadata, not hidden global state
Database
Production uses PostgreSQL (Railway project talented-exploration).
| Variable | Purpose |
|---|---|
ARTHA_DATABASE_URL |
PostgreSQL DSN for ledger + projections (preferred) |
ARTHA_DB_PATH |
Fallback SQLite path for local-only dev |
OPENROUTER_API_KEY |
OpenRouter key for Agno Guardian writes |
GUARDIAN_MODEL |
Guardian LLM model (default: inception/mercury-2) |
ARTHA_EMBEDDER |
fastembed (default) or deterministic |
ARTHA_EMBED_MODEL |
Nomic embed model (default: nomic-ai/nomic-embed-text-v1.5-Q) |
MEMURON_API_KEY |
Optional API key for /memuron/* and /engine/* routes |
Copy .env.example to .env and set ARTHA_DATABASE_URL to the Railway public Postgres URL for local development.
Run
Use two terminals, both starting from the memuron repo root (Documents/memuron), not frontend/.
Terminal 1 — backend
cd /Users/rakshithg/Documents/memuron
./scripts/dev-backend.sh
# or manually:
# source .env && uv run uvicorn memuron.application.api:create_app --factory --host 127.0.0.1 --port 8767
Terminal 2 — frontend
cd /Users/rakshithg/Documents/memuron
./scripts/dev-frontend.sh
# or: cd frontend && npm run dev
Open http://localhost:3000 — the workbench proxies to http://127.0.0.1:8767/engine; Memories uses http://127.0.0.1:8767/memuron.
frontend/.env.local must use the /engine suffix:
ARTHA_ENGINE_URL=http://127.0.0.1:8767/engine
MEMURON_API_URL=http://127.0.0.1:8767/memuron
If you see 502 on /api/engine/*, the backend is not running or the URL is wrong. Do not run source .env or uv run from inside frontend/ — .env lives in the repo root and uv must use the memuron project.
uv sync
cp .env.example .env # then edit ARTHA_DATABASE_URL
uv run pytest # fast local suite (SQLite, skips integration)
uv run pytest -m integration # Postgres job queue + live Guardian (needs .env)
uv run artha doctor
MCP and CLI
The stdio MCP server is intentionally restricted to one explicit Clerk user and organization. Configure its identity before starting it:
export MEMURON_MCP_ACTOR_ID=user_...
export MEMURON_MCP_TENANT_ID=org_...
export MEMURON_MCP_SCOPES=memory:read,memory:write,memory:delete,space:admin
uv run memuron-mcp
The compact MCP surface centers on memuron_help and memuron_query, with
memory ingest/get/update/delete/job polling and the complete space lifecycle.
memuron_document_source resolves a document, chunk, image, or document
collection node to the original uploaded file metadata and a short-lived
download URL.
Lower-level graph, list, collection, and bulk operations remain available
through HTTP and the broader CLI without overwhelming an agent's tool picker.
memuron_get bounds content by default and supports field selection, while
memuron_update exposes flat memory_id, content, and scope arguments.
Space arguments accept UUIDs, slugs, space.* tokens, and /spaces/space.*
paths.
uv run memuron --help
uv run memuron --tenant-id org_... query \
--cwd /spaces/space.personal \
--query 'semantic "deployment decisions" | head 5'
uv run memuron --tenant-id org_... space list
All direct-ID operations verify that the target belongs to the active organization. API-key and local CLI callers must therefore provide a tenant.
For editor login/logout, use the Railway-hosted Streamable HTTP endpoint:
{
"mcpServers": {
"memuron": {
"url": "https://memuron-production.up.railway.app/mcp"
}
}
}
Cursor discovers Clerk through OAuth protected-resource metadata, opens the
Clerk consent flow, and stores its own access and refresh tokens. The OAuth
application only needs the standard profile scope. Memuron resolves the
signed-in user's Clerk organization membership server-side and maps it to the
configured Memuron tenant. Enable Dynamic client registration in the Clerk
Dashboard under OAuth applications so MCP clients can register with PKCE
automatically.
For users who belong to several mapped Clerk organizations, set
MEMURON_MCP_DEFAULT_CLERK_ORG_ID to select one explicitly when the OAuth token
does not carry an active organization.
Document storage
Memuron keeps the searchable document graph in Postgres: normalized markdown, chunks, embeddings, links, metadata, and append-only events. Original uploads and extracted binary assets belong in S3-compatible object storage. This hybrid boundary preserves transactional graph queries without turning Postgres into a binary file store.
API (prefix /memuron)
Core routes (see docs/README.md for full detail):
| Method | Path | Description |
|---|---|---|
| POST | /memories |
Create memory (async Guardian ingest, returns job id) |
| POST | /nodes |
Rich node (text / image / document / collection) + optional auto-link |
| POST | /documents/ingest |
Multipart file → collection + source + chunks + filtered images |
| POST | /collections |
Collection node |
| POST | /collections/{id}/placements |
Place member in collection |
| GET | /collections/{id}/members |
List collection members |
| GET | /graph/export |
Graph for UI |
| GET | /memories |
List memories (scope, limit, offset) |
| POST | /memories/search |
Semantic search (query, k, optional scope) |
| GET | /memories/{id} |
Get one memory |
| POST | /memories/batch |
Get many by id |
| PUT | /memories/{id} |
Update content/scope (sync, no Guardian) |
| DELETE | /memories/{id} |
Delete one memory |
| POST | /memories/bulk-delete |
Delete by scope filter |
| POST | /memories/unlink |
Remove link between two memories |
| GET | /memories/count |
Count with optional filters |
| GET | /jobs/{id} |
Poll async ingest job status |
| GET | /spaces |
List org spaces |
Auth and Audit Metadata
Memuron uses bring-your-own API-key auth at the product boundary. When MEMURON_API_KEY is set, protected routes accept either:
Authorization: Bearer <key>
X-Memuron-Api-Key: <key>
Optional audit headers are copied into semantic event metadata:
X-Memuron-Actor-Id: agent_123
X-Memuron-Tenant-Id: workspace_456
X-Memuron-Scopes: memory:write,memory:delete
X-Request-Id: req_abc
This applies to Memuron writes and to the mounted Artha Engine API under /engine. The engine remains auth-provider agnostic; Memuron decides how API keys, actors, tenants, and scopes map to product permissions.
The mounted engine exposes profile discovery at:
GET /engine/runtime/capabilities
Example create → read flow:
# Create (async)
curl -s -X POST http://127.0.0.1:8767/memuron/memories \
-H 'Content-Type: application/json' \
-d '{"content":"User enjoys rock climbing on weekends.","scope":["fitness.climbing"]}'
# Poll job until completed, then read
curl -s http://127.0.0.1:8767/memuron/memories/{memory_id}
# List and search
curl -s 'http://127.0.0.1:8767/memuron/memories?limit=20'
curl -s -X POST http://127.0.0.1:8767/memuron/memories/search \
-H 'Content-Type: application/json' \
-d '{"query":"rock climbing","k":5}'
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memuron-0.1.2.tar.gz.
File metadata
- Download URL: memuron-0.1.2.tar.gz
- Upload date:
- Size: 130.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7455b44e10738aaf033adc95c4e8bf028bba91b494aa8e728b23056a02cc629d
|
|
| MD5 |
a313ce840e661df3d5148a773381af5d
|
|
| BLAKE2b-256 |
3e336bb726d31439d3868f596988af4c2782830bf3ae5b858974dcdf3689562b
|
File details
Details for the file memuron-0.1.2-py3-none-any.whl.
File metadata
- Download URL: memuron-0.1.2-py3-none-any.whl
- Upload date:
- Size: 160.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee208ca775ecc57ecd08e70273f9ac68b4dd4c7a33f0a6460b9689cf8cce2c3f
|
|
| MD5 |
74d3ab108921bdfd21533e502a951c9e
|
|
| BLAKE2b-256 |
900c20ed5ca3010f400d10a4dfcc6a24e0eb34c8c95613ec89d8dffd929dfb7c
|