Atlas / MCP servers / raullenchai / Vnsh

VnshBLOCK

mcp/raullenchai/vnsh

One workspace all your AI agents can read and write. Encrypted client-side, model-agnostic, gone 24h after the last edit.

Verdict
BLOCK
Grade
F
Trust score
56 /100
Exposed tools
14 10r · 4w · 0d
Transport
stdio
License
MIT
Stars
157
01

Overview

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

vnsh

One workspace all your AI agents can read and write

Website • Get Started • Links • How It Works • API • Self-Hosting

Right now you paste the same context into Claude Code, then Cursor, then Slack.

vnsh gives that context one address instead. Drop it once and get a link; every agent and every person you hand it to opens the same living document, and can change it. Encrypted in your browser before upload, so vnsh never sees it, and deleted 24 hours after the last edit.

kubectl logs pod/app | vn
# https://vnsh.dev/w/k2p9xf...#w
Read from source at commit ca92245dac2eOBSERVED · 2026-10-07
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 (npm)
claude mcp add vnsh-mcp -- npx -y [email protected]
03

Exposed tools (14)

10 read · 4 write · 0 destructive.

ToolRiskDescription
vnsh_artifact_createwriteCreates a permanent, service-readable Account Artifact in the signed-in user’s Library.
vnsh_artifact_listreadLists permanent Account Artifacts available to the connected user. Use this instead of asking
vnsh_artifact_readreadReads the current content and version of one permanent Account Artifact. Pass the returned
vnsh_artifact_updatewriteCreates a new immutable version of an Account Artifact. Requires the base_version returned by
vnsh_readreadReads any vnsh URL: decrypts legacy vnsh.dev/v links locally, or directly fetches
vnsh_sharereadEncrypts text content locally and uploads it to vnsh, returning a shareable URL.
vnsh_share_filereadEncrypts a local file and uploads it to vnsh, returning a shareable URL.
vnsh_workspace_createwriteCreates a shared workspace and returns one link that any agent can read AND write.
vnsh_workspace_historyreadLists the retained versions of a workspace, newest first. Use this before restoring
vnsh_workspace_openreadDecrypts a vnsh workspace to a local temp file and opens it in the browser.
vnsh_workspace_readreadReads the current content of a workspace: encrypted /w/ links with #w= or #r=,
vnsh_workspace_renewreadExtends the expiry of a vnsh workspace without changing its content. Use this
vnsh_workspace_restorereadRestores a retained workspace version as a new latest version. This never moves the
vnsh_workspace_updatewriteReplaces the content of a vnsh workspace, keeping the same URL. Use this to record
04

Trust audit

BLOCKgrade F · trust 56/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)WARN
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
declared (9 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker/src/index.ts:4913
<li><strong>No eval()</strong>: The strict CSP means no dynamic code generation. All crypto runs through the built-in WebCrypto API.</li>
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
cli/npm/src/cli.ts:238
console.log(`\n${colors.green('Root secret:')} ${bufferToHex(secret)}`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
cli/npm/src/cli.ts:278
console.log(buildWorkspaceUrl(host, result.id, secret).replace('/w/', options.artifact ? '/artifact/' : '/w/'));
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
cli/npm/src/cli.ts:282
console.log(buildWorkspaceUrl(host, result.id, secret).replace('/w/', options.artifact ? '/artifact/' : '/w/'));
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
cli/npm/src/cli.ts:285
console.log(buildReadOnlyWorkspaceUrl(host, result.id, secret).replace('/w/', options.artifact ? '/artifact/' : '/w/'));
MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
worker/src/index.ts:5214
const OG_SITE_PNG = 'iVBORw0KGgoAAAANSUhEUgAABLAAAAJ2CAMAAAB4notuAAAAwFBMVEX////+/v78/Pz5+fn29vby8vLt7e3p6enk5OTe3t7U1NTHx8e7u7sixV4hwFy0tLSpqamjo6OhoaGgoKCcnJyXl5eRkZGJiYmDg4N9fX0+jFtzc3MXczlvb29ra2t
MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
worker/src/index.ts:5215
const OG_WORKSPACE_PNG = 'iVBORw0KGgoAAAANSUhEUgAABLAAAAJ2CAMAAAB4notuAAAAwFBMVEX////+///+/v78/Pz5+fn09PTv7+/r6+vm5uTb29rLy8kixV4hw12/vrm6urrDtIqvr66jo6OwlHOgoKCcm5aWlo9RoG+MjIiFhYKBgYFrfHF3dnRzc3Nzc2
MEDIUMPrompt injection · prompt.hidden_style · CWE-94, CWE-1427
docs/ux-fixes-v1.1.1.md:262
<input type="file" id="fileInput" style="display: none;" onchange="handleFileSelect(event)">
MEDIUMSupply chain · prompt.pipe_to_shell · CWE-829, CWE-1357
SKILL.md:25
command: "curl -sL vnsh.dev/i | sh"
MEDIUMSupply chain · prompt.pipe_to_shell · CWE-829, CWE-1357
SKILL.md:221
| `vn: command not found` | Run: `curl -sL vnsh.dev/i \| sh` |
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker/test/inline-scripts.test.ts:50
expect(() => new Function(body)).not.toThrow();
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker/test/inline-scripts.test.ts:57
expect(() => new Function('var re = /+/g;')).toThrow();
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker/test/inline-scripts.test.ts:58
expect(() => new Function('var re = /\\+/g;')).not.toThrow();
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker/test/inline-scripts.test.ts:76
return new Function('s', `${source![0]}\nreturn looksLikeHtml(s);`) as (s: string) => boolean;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cli/npm/src/branding.test.ts:16
const repo = (p: string) => fileURLToPath(new URL(`../../../${p}`, import.meta.url));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cli/npm/src/branding.test.ts:95
const mcpSource = readFileSync(new URL('../../../mcp/src/index.ts', import.meta.url), 'utf-8');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cli/npm/src/crypto.test.ts:4
import * as mcp from '../../../mcp/src/crypto.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cli/npm/src/crypto.test.ts:6
const vectors = JSON.parse(readFileSync(new URL('../../../test-vectors/vnsh-compat.json', import.meta.url), 'utf8')) as {
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cli/npm/src/filename.test.ts:116
['../../etc/passwd', 'passwd'],
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
worker/test/content-domain.test.ts:78
['the event beacon', 'POST', '/api/event'],
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
worker/test/event.test.ts:33
function beacon(body: unknown, headers: Record<string, string> = {}) {
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
worker/test/event.test.ts:45
const response = await beacon({ event: 'prompt_copy', ref: 'w' }, { 'X-Vnsh-Client': 'web' });
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
worker/test/event.test.ts:61
await beacon({ event: 'page_view', ref: 'home' });
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
worker/test/event.test.ts:70
const response = await beacon({ event, ref: 'w' });
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
docs/integration-tests.md:68
echo "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha ca92245dac2efull audit observations/trust-audit/mcp-server/raullenchai__vnsh.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-07ca92245dac2eBLOCKF56first audit
06

Questions

What is the Vnsh MCP server?

One workspace all your AI agents can read and write. Encrypted client-side, model-agnostic, gone 24h after the last edit.

What tools does Vnsh expose?

14 in total: 10 read-only, 4 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Vnsh safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (56/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.

What credentials does Vnsh need?

It reads CLOUDFLARE_API_TOKEN and VNSH_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 does Vnsh run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as vnsh-worker at 1.0.0.

How current is this page?

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

Advertisement