remnus — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited remnus (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Remnus is a Notion-like workspace. You interact with it through the `remnus` MCP server — a single connected workspace exposed via bearer-token auth. Every call already runs inside one fixed workspace; you never pass a workspace ID.
The server exposes all three MCP primitives:
remnus://… URIs.Use the right one: resources to pull context cheaply, tools to act, prompts to kick off a structured task.
Two kinds of things live in the workspace, side by side in one sidebar tree:
content. Can be nested under a parent (parentId). Link to another item with <a data-page-link href="/page/<id>">Title</a> (/db/<databaseId> for a database) — the link graph follows only that form; [[Title]] is plain text.schema (columns) plus rows. Each row is itself a page: it has a title, markdown content, an icon, AND a properties object keyed by column.So "a page" can mean a standalone page or a database row. Most read tools auto-detect which, so you rarely need to care — but when you create or update, the distinction matters (see below).
Column types: text | number | select | multi_select | status | user | multi_user | date | datetime | checkbox | url | email | phone. multi_select and multi_user values are arrays; checkbox is a boolean; user/multi_user hold workspace member ids (list_members); everything else is scalar. A status column's options can carry a group (todo | in_progress | complete).
Read (safe, always allowed):
prepare_context — start meaningful multi-page product/coding work with Context Pack v2; returns a token-budgeted, reviewed/fresh pack and a short-lived contextRunId.search_workspace — find pages/databases by text, best match first (case- and accent-insensitive: cozum finds "Çözüm"). The fallback when the workspace map has not already given you the id, not the first step.list_workspace — list items, optionally under a parentId. Paginated.get_page — full content of a page or row by ID. Auto-detects type. A dashboard comes back as its block spec (mode: "outline" → just the block ids/types/titles).get_pages — batch get_page: a specific known ID list (max 50), possibly across databases/types. One bad ID doesn't fail the rest — check each result's ok. For many rows in one database, prefer query_database instead.get_database_schema — columns only, no rows. Cheap; call before querying.query_database — schema + rows, with optional filters. Paginated.list_members — workspace members and roles.get_status — this connection's own state: workspace, scope, whether write tools are offered, when the token expires and what to do about it. Call it when Remnus tools are missing, a write is refused or a call fails with 401, before guessing at the cause.query_audit_log — history of MCP tool calls (yours and other agents').get_changes_since — the delta since a cursor (from the digest/map header or a previous call). The normal way to catch up; always returns a nextCursor to keep.get_related_pages — parent, children, outgoing links, backlinks, row siblings and source files, without bodies. With resource (a file path) instead of pageId: the pages written against that file — ask it before changing the file.Write (needs a write-scoped token):
create_page — new standalone page OR database row (see decision below).bulk_create_pages — up to 100 pages/rows in one call, created in order; nest pages created in the same call with ref/parentRef. Prefer it whenever you'd create more than a couple of items. Creating is not idempotent: if the connection drops before you get an answer, do not re-send the call — look first (get_changes_since / query_database / list_workspace) and create only what is missing, or you will make duplicates.update_page — change title/content/properties of one item. tick checks - [ ] tasks by their text and append adds to the end — neither resends the body.bulk_update_pages — many updates in one call. Prefer this over a loop. Every entry answers ok / error on its own and the ones that succeeded stay applied, so after a failure or a dropped connection re-send only the entries with ok: false (or, if you got no answer at all, check with get_changes_since / query_database first — repeating an update is safe).delete_page — delete a page, row, dashboard, or whole database (to the Trash — a person can restore it). Guarded.bulk_delete_pages — delete up to 100 pages/rows/databases in one call. Guarded, same preview/confirm shape as delete_page. Response reports each id's own ok/error — never all-or-nothing.move_item — reparent a sidebar item; newParentId: null → root. position (0 = first) sets its place among siblings; pass the current parent to reorder in place.bulk_move_items — move up to 100 items in one call: pass newParentId to reparent (batched move_item), or targetDatabaseId to move database rows to a different database. Cross-database moves are refused entirely if the target's columns don't cover the source's by name and type.create_database — new database with a custom schema; pass an icon and the views people will use (kanban on status, calendar on dates).update_database_schema — add/remove columns. Removing is guarded.create_dashboard — a live status screen (metrics, charts, lists, embedded views, text) over this workspace's databases, written as JSON blocks. Read remnus://dashboard/catalog first — it has the fields and three templates to fill in. Column fields take names. The result gives the page url to show the user and warnings for blocks that will render empty or broken — act on them, you cannot see the screen.update_dashboard — patch a dashboard by block id: add, update ({id, ...changed fields}, merged), remove, order. Never resend the whole spec. All-or-nothing.add_comment — leave a note or closure comment on a page/row, in a thread separate from its content. Append-only — you cannot edit or delete your own comment afterward, so use update_page instead if the content itself needs to change.If a write tool returns "This token only has read scope," the user connected a read-only token — tell them; do not retry.
remnus://…Resources are read-only and listable; many clients let you attach them directly as context, which is cheaper and cleaner than a tool round-trip when you just need to read:
remnus://workspace/{id}/schema — every database in the workspace plus its columns, in one document. Best first pull to understand what databases exist and their shapes.remnus://workspace/{id}/digest — token-cheap one-line map of titles, IDs, row counts, body sizes and update dates, headed by a sync cursor. In a project connected with remnus init, the same map is cached at .remnus/workspace-map.md, which you can grep without a round-trip — read that first and treat it as a snapshot verified up to its cursor.remnus://workspace/{id}/knowledge-health — compact link/freshness/lifecycle/review coverage report; heuristic, not a correctness certificate.remnus://database/{id}/schema — columns of one database (same data as get_database_schema).remnus://page/{id} — a page or row rendered as markdown (title + properties + content). Listing returns the 20 most recently updated; any page is reachable by its ID.remnus://dashboard/catalog — dashboard block types, their fields, and ready-made templates. Read it only when you are about to build or change a dashboard.remnus://audit-log/recent — the last 50 activity entries for this token.Rule of thumb: if the user just wants you to read/understand, prefer attaching the resource. If you need to filter, paginate, or act, use the equivalent tool (query_database, get_page, etc.). The schema resources and the get_database_schema tool return the same thing — either is fine.
The server ships seven prompt templates that pre-fetch the relevant Remnus data and hand you a ready-to-run instruction. When the client surfaces prompts, prefer them over assembling the same context by hand:
summarize-page — page_id, optional style (bullet | paragraph | tldr).weekly-status-report — database_id, optional period (e.g. "last week"). Groups by status, flags blockers/wins.kanban-triage — database_id. What needs attention, what's blocked, what to deprioritize, next 3 actions.extract-tasks — page_id. Pulls actionable items into a markdown checklist (action / owner / deadline / priority).search-and-create — title + query. Finds similar existing pages so a new one complements rather than duplicates.save-memory — content, optional memory_type (decision | preference | gotcha | fact) and tags. Persists a durable memory into your Agent Memory database as a structured, human-readable record.recall-context — topic, optional limit. Reloads the top matching pages as token-cheap outlines plus the link-graph neighborhood of the best match — use it to reload prior context instead of many search + get_page round-trips.These only fetch and format — the actual writing/analysis is yours. If a client doesn't expose prompts, reproduce them: query the data with the read tools, then do the summary/triage yourself.
Orient in this order: local map (`.remnus/workspace-map.md`) → `get_changes_since(cursor)` → targeted read → `search_workspace`. Grep the map instead of listing the tree; before writing, or when the map looks stale, take its cursor and pull the delta rather than re-crawling. With no map file, read the digest resource once and keep its cursor.
For meaningful multi-page product or coding work, start with prepare_context (normally 2,000 tokens) and reuse its contextRunId on related writes. Pass keywords: synonyms of the task's key terms and, when the task is in another language than the workspace, the workspace's own terms (English terms for a Turkish task) — retrieval is lexical, so the server cannot translate. Do not call it for greetings, formatting-only work, or a single known page. If a write returns CONTEXT_REQUIRED, prepare the concrete task and retry once with the returned ID. Don't guess IDs or column names: run get_database_schema before query_database / before writing rows. You need real column IDs and exact select option strings.
update_page MERGES properties — it never replacesPassing properties: { status: "Done" } changes only status; every other property is untouched. To clear a field, set it explicitly to null/"". Never re-send the whole property bag thinking you must preserve it — you don't, and doing so risks clobbering changes made since you read.
delete_page, bulk_delete_pages and update_database_schema (when removing columns) require confirm: true. That flag is a safety latch, not your decision to make:
confirm: true.A deleted page, row or database is recoverable. It moves to the Trash with its content and a person can restore it there for 30 days — so deleting what the user asked you to delete (archiving finished cards, clearing a scratch section) is not a one-way door. You cannot restore it yourself and there is no tool to read the Trash; tell the user what you deleted so they know where to look. Deleting a database or a parent page puts each item under it in the Trash too (each restores on its own). Removing a column is different: it destroys that column's data across all rows and the Trash does not bring it back.
query_database filters use column ID → value: { "col_status": "Done" }. For multi_select, pass an array: { "col_tags": ["Bug"] }. Get exact IDs/options from get_database_schema.hasMore: true, pass its nextCursor back as cursor to get the next page. Keep going until hasMore is false if the user asked for "all". Don't crank limit to a huge number to dodge pagination.title, content, optional parentId.databaseId (+ title, content, properties). The row is created inside that database.Don't pass both parentId and databaseId. Property keys must match the database's column IDs. Give pages and databases an icon (an emoji, or lucide:Name with an iconColor), and nest related pages under a parent instead of leaving everything at the root.
Creating several pages or rows? One bulk_create_pages call. Updating several rows (e.g. "mark all done")? One bulk_update_pages call. It's one audit entry and one round-trip instead of N.
content is plain markdown. Headings, lists, tables, checkboxes (- [ ]) all work. Write clean markdown, not HTML.
"Implement feature X using our product decisions" → prepare_context with the concrete task, keywords and a suitable maxTokens budget → keep contextRunId → get_page only for related IDs whose full detail is still needed → pass contextRunId to Remnus writes.
"Find X and show me" → the workspace map if you have one, else search_workspace → get_page on the best hit.
"What's in my Tasks database?" → the map (or search_workspace) for the DB id → get_database_schema → query_database (filter/paginate as needed).
"What changed since I last looked?" → get_changes_since with the cursor from the map header or your last call — not a fresh crawl.
"Mark these tasks done" / bulk edits → get_database_schema for the status column id and the "Done" option string → query_database to resolve row IDs → one bulk_update_pages.
"Read these N specific pages/rows" (IDs already known, e.g. from a prior search_workspace/get_related_pages/get_changes_since, possibly across databases) → one get_pages call instead of a get_page loop. If they all share one database, query_database with filters/fields is cheaper still.
"Add a new task" → resolve the database id → get_database_schema for property keys → create_page with databaseId + properties.
"Set up a database for X" → create_database with a sensible schema, an icon and the views people will use (a Title column is auto-prepended). Then one bulk_create_pages call for the rows.
Reports / triage / summaries → use the matching prompt (see the Prompts section). Fall back to read-tools + your own summary if prompts aren't exposed.
Ask the user which workspace item or database they mean rather than acting on a fuzzy match — titles repeat. Surface the audit log (query_audit_log) if they ask "what did the agent change?"
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.