Atlas / MCP servers / grunion-ai / weave

weaveBLOCK

mcp/grunion-ai/weave

Open-source, self-hosted alternative to Airtable, Fibery, Notion databases and ClickUp: a work management database built for AI agents, agent-first (Claude Code, Codex, Cursor, any MCP client). Tables, relations, formulas, rollups, workflows, documents, one SQLite file. REST, CLI, MCP server. Docker

Verdict
BLOCK
Grade
F
Trust score
50 /100
Exposed tools
68 43r · 19w · 6d
Transport
—
License
MIT
Stars
10
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

weave

An open-source, self-hosted alternative to Airtable, Fibery, Notion databases, and ClickUp — built so that AI agents are first-class users, not an afterthought.

Connected tables, relations, workflows, formulas, rollups, and per-entity markdown documents. One SQLite file. Zero dependencies. No build step. MIT.

For agents · Quickstart · Comparison · Agents & MCP · Self-hosting · FAQ

For agents

weave stores structured work (tables, rows, relations, documents) in one SQLite file, and an agent drives it over MCP, REST or the CLI.

  • Connect over MCP: node bin/weave.js mcp --data , the same as

weave mcp --data . In Claude Code: `claude mcp add weave -- node

Read from source at commit 1b0cc55a50f0OBSERVED · 2026-10-10
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add weave --env GH_TOKEN=${GH_TOKEN} --env GITHUB_TOKEN=${GITHUB_TOKEN} --env WEAVE_APPLET_PASSCODE=${WEAVE_APPLET_PASSCODE} --env WEAVE_KEYSTORE=${WEAVE_KEYSTORE} -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "weave": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "GH_TOKEN": "${GH_TOKEN}",
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "WEAVE_APPLET_PASSCODE": "${WEAVE_APPLET_PASSCODE}",
        "WEAVE_KEYSTORE": "${WEAVE_KEYSTORE}"
      }
    }
  }
}
03

Exposed tools (68)

43 read · 19 write · 6 destructive. Blast radius: 6 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
CRMreadthe pipeline
Companyreadwho we sell to
Dealreadone opportunity
GlossaryreadTerms live in [the guide](${FAR}) and in [this space](#/table/x).
Invoicereadone bill
Jobreadwork items
Opsreadhow work runs
ProductreadProduct development
ProjectreadWhat we ship
RunbookwriteHow we run things
Salesreadx
TaskreadWork in flight, one row per task, with enough words here to wrap the description at phone width.
WorkflowsreadEvery workflow.
WorkspacereadThe workspace itself: its spaces and tables, as rows.
ops-hubreadthe hub
pollutedreadpolluted
weavereadthe record
weave_activityreadThe activity feed: every change weave recorded, newest first. Filter by entity, table, kinds, or since (ISO timestamp); pass id to read one event in full. Each entity keeps its newest 500 entries;
weave_add_commentwriteAdd a comment to an entity. Comments are their own thread on the entity page and ride the activity feed; delete one with weave_delete_comment.
weave_attach_filereadAttach a file to an entity (base64 content).
weave_auditreadThe workspace audit log: schema and account events with their actor.
weave_automationsreadAutomations already on a table, read from their Workspace/Workflows rows: action list | describe (rules in prose) | update (patch: name, enabled = the row\
weave_buildreadBuild in ONE call: spaces, tables, fields, relations and rows. A field is {name, type, plus that type\
weave_bulkwriteOne write for a whole selection. op
weave_create_automationwriteCreate an automation rule as a Workspace/Workflows row; its Script holds the rule as JSON. enabled (default true) is the row\
weave_create_entitywriteCreate an entity. values maps field names to values; relation fields accept entity names, ids, or
weave_create_spacewriteCreate a space (top-level grouping of tables).
weave_create_tablewriteCreate a table in a space (a Name text field and a Description document are added automatically). icon is
weave_delete_commentdestructiveDelete one comment from an entity. The comment id comes from weave_get_entity.
weave_delete_entitydestructiveDelete an entity. Recoverable by default — it moves to the trash keeping its id, public id and links. Pass hard: true to purge it irreversibly (relations are unlinked cleanly).
weave_delete_fielddestructiveDelete a field and its values from every entity of the table. Not recoverable.
weave_delete_spacedestructiveMove a space to the trash (recoverable — its tables and rows go dark with it). Pass hard: true to purge it and every table in it for good.
weave_delete_tabledestructiveMove a table to the trash (recoverable — its rows go dark with it). Pass hard: true to purge table and rows for good.
weave_doc_restorewriteWrite a past revision back as the document\
weave_doc_revisionsreadA document\
weave_duplicate_tablereadDuplicate a table\
weave_export_csvreadExport a table as CSV: one row per entity, one column per field, computed fields resolved. Multiselect and to-many relation cells use
weave_export_jsonreadThe whole workspace as JSON — the human-readable interchange format, and the backup to take before a destructive apply. Attachment bytes are left out unless blobs is true;
weave_filesreadFiles already attached to an entity: action read (returns base64 content) | delete. Attach one with weave_attach_file.
weave_form_submitwriteSubmit one row through a form, a Workspace/Forms row: exactly one new row in the form\
weave_get_docreadRead an entity document as markdown. Entities can carry several document fields; omit field for the default (the table\
weave_get_entityreadRead one entity in full: all field values (including computed lookups/rollups/formulas), document markdown, comments, activity.
weave_import_csvwriteImport entities from CSV text. The header row maps to field names; multiselect and to-many relation cells use
weave_import_jsonwriteReplace the workspace with a JSON export. Destructive: everything not in the document is gone. The result names every file that arrived without its bytes (missing).
weave_keysreadThe keystore behind
weave_linkreadLink entities through a relation field (bidirectional; inverse side updates automatically).
weave_move_tablewriteMove a table into another space. Only its home changes — every row, field and relation stays exactly as it was. Refuses when the destination already holds (or holds in its trash) a table of the same name.
weave_queryreadQuery entities in a table. Filters support dotted relation paths (e.g. [
weave_relation_mapreadThe workspace relation map as a mermaid diagram: every table, relation and automation.
weave_restore_entityreadRestore a soft-deleted entity from the trash, links intact.
weave_restore_spacereadRestore a trashed space; its tables and rows come back with it.
weave_restore_tablereadRestore a table out of the trash: the table, its rows and their relations come back exactly as they were.
weave_rollback_fieldwritePut a field back the way one of its field-config-updated (or undo) Activity entries found it. Every change weave_update_field makes to a field\
weave_schemareadDescribe the whole workspace: spaces, tables, fields (with types, options, workflow states, relations, lookups, rollups, formulas), and entity counts.
weave_searchreadUniversal search across the workspace, spaces, tables, saved views, and entities (names, publicIds, text fields, documents, comments). Every result carries a stable permalink url. limit bounds entity rows only; every matching workspace, space, table and view is always returned.
weave_set_docwriteWrite an entity document. mode
weave_set_statewriteMove an entity to a workflow state (multistate field).
weave_statsreadSummarise every column of a table in one read: numbers get filled/empty, sum, avg, median, min, max, p25, p75, range, stdev and a 10-bin histogram (raw and dressed in the column\
weave_table_viewreadA table\
weave_template_listreadThe template spaces of this workspace: the live spaces marked template: true (weave_update_space marks one, or the Template box on its Workspace/Spaces row). Each is a space record: id, name, description, icon.
weave_template_usereadCopy a template space\
weave_trashreadList deleted entities — one table, or the whole workspace when table is omitted.
weave_undoreadRevert the last entity mutation(s): field/doc/state/relation edits, creates, soft deletes, comments, file attachments. Schema changes and hard deletes are not undoable. Pass list:true to preview the stack without reverting.
weave_unlinkdestructiveRemove entities from a relation field, leaving both entities in place. targets takes ids, names, or
weave_update_entitywriteUpdate entity field values by name (writable fields only; computed fields are read-only).
weave_update_spacewriteRename a space or change its description or icon, or mark it a template (template: true; weave_template_use copies a template\
weave_update_tablewriteChange a table: name, description, icon (
weave_workspacewriteThe workspace record itself. action: get | update (name: any text, kept as the title; its slug, lowercase letters, digits and -, is the /w/<slug>/ address and the <slug>.<base domain> host, description, linkPreview) | logo (contentBase64 + name + mime) | clear-logo.
04

Trust audit

BLOCKgrade F · trust 50/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (5 observation(s))
Network
declared (10 observation(s))
Shell
declared (9 observation(s))
Dependencies
pinned
Secrets in source
none-found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
security/semgrep/weave.js:56
return new Function(src)();
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
security/semgrep/weave.js:60
return eval(src);
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
security/semgrep/weave.yml:137
- pattern: new Function(...)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
security/semgrep/weave.yml:138
- pattern: eval(...)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
security/mcp-inject/cases.mjs:12
exfil: {
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
security/mcp-inject/run.mjs:51
: goal === 'exfil' ? JSON.stringify(c.input).includes(CANARY)
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
security/mcp-inject/workspace.mjs:84
exfil: after.canary > baseline.canary,
MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
public/vendor/vditor/dist/index.css:1043
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8AgMAAABHkjHhAAAACVBMVEWAgIBaWlo+Pj7rTFvWAAAAA3RSTlMHCAw+VhR4AAAA+klEQVQoz4WSMW7EQAhFPxKWNh2FCx+HkaZI6RRb5DYbyVfIJXLKDCFoMbaT
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
weave_delete_comment, weave_delete_entity, weave_delete_field, weave_delete_space, weave_delete_table, weave_unlink
Why it matters. 6 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
test/attachment-drop-browser.test.mjs:47
const hasClass = (page, sel) => page.$eval(sel, (n) => n.classList.contains('is-file-drop'));
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
scripts/flicker-sweep.mjs:87
const id = createHash('sha1').update(f.fp).digest('hex').slice(0, 10);
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/engine.js:166
return createHash('sha1').update(text).digest('hex').slice(0, 8);
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/server.js:365
const v = createHash('sha1').update(readFileSync(full)).digest('hex').slice(0, 12);
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/server.js:397
ETag: `W/"${createHash('sha1').update(body).digest('hex').slice(0, 16)}"`,
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
test/asset-cache.test.mjs:27
const want = createHash('sha1').update(readFileSync(join(ROOT, 'public', url))).digest('hex').slice(0, 12);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
security/mcp-inject/workspace.mjs:7
import { Weave } from '../../src/engine.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
security/mcp-inject/workspace.mjs:8
import { dispatchTool } from '../../src/mcp.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/lib/browser.mjs:3
import { Weave } from '../../src/engine.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/lib/browser.mjs:4
import { startServer } from '../../src/server.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/lib/browser.mjs:9
const ROOT = fileURLToPath(new URL('../../', import.meta.url));
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
test/security/mcp-inject.test.mjs:80
const sb = seed(b, { placement: 'comment', goal: 'exfil', style: 'authority' });
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
test/security/mcp-inject.test.mjs:135
assert.deepEqual(v.landed, { delete: false, exfil: false, account: false, share: false });
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/security/webhook-targets.test.mjs:48
const refused = ['127.0.0.1', '127.255.255.254', '10.1.2.3', '172.16.0.1', '172.31.255.255', '192.168.0.9', '169.254.169.254', '100.100.100.200', '0.0.0.0', '::1', '::', 'fe80::1', 'fd12::1', 'fdaa::1
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
AGENTS.md:53
| Browser UI | `weave serve`, then http://127.0.0.1:4400 | a person wants to see or edit the result |
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
AGENTS.md:569
curl -s -X POST http://127.0.0.1:4400/w/weave/api/tables/Guide/query \

Gates applied: no_behavioural_pass.

Audited 2026-10-10 · audit v0.4.1 · source sha 1b0cc55a50f0full audit observations/trust-audit/mcp-server/grunion-ai__weave.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-101b0cc55a50f0BLOCKF50first audit
06

Questions

What is the weave MCP server?

Open-source, self-hosted alternative to Airtable, Fibery, Notion databases and ClickUp: a work management database built for AI agents, agent-first (Claude Code, Codex, Cursor, any MCP client). Tables, relations, formulas, rollups, workflows, documents, one SQLite file. REST, CLI, MCP server. Docker

What tools does weave expose?

68 in total: 43 read-only, 19 that write, and 6 that can delete or overwrite (weave_delete_comment, weave_delete_entity, weave_delete_field, weave_delete_space, weave_delete_table). Every one is listed on this page with its risk.

Is weave safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (50/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 6 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does weave need?

It reads GH_TOKEN, GITHUB_TOKEN, WEAVE_APPLET_PASSCODE, WEAVE_KEYSTORE, WEAVE_MAIL_KEY and WEAVE_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How current is this page?

The grade is for one exact copy of the source (1b0cc55a50f0), read on 2026-10-10. The repository is watched and re-audited when it changes.

Advertisement