Pinako AI Bridge (teleomorph/pinako-mcp) is an MCP server listed on the M8ven Trust Index. It scores 51 out of 100, grade D. It declares 49 tools. No publisher has claimed this listing.
Pinako AI Bridge is the MCP server that connects Pinako, a Chromium extension for tab, window, library, and bookmark management, to local AI clients including Claude Desktop, Claude Code, Cursor, Windsurf, Cline, Roo Code, and Continue.dev. The real payoff comes when you already use a desktop AI client: because the bridge runs inside that client alongside its other connect
Caution. Specific findings reduced this grade. They are listed on the page. Grades reflect the full trust pyramid: code, verification depth, and reputation. New projects cap at C until adoption is earned.
How we verified
Verified is a snapshot. Live keeps it current, and builds your track record.
⚡ Connect GitHub → continuous verification on every pushwhy connect →Who stands behind it
teleomorph
Source: Glama
Claim it to get a verified publisher badge, a free copy of our full audit findings, and direct contact for any high-priority issues we find. Or connect your repo for our deepest verification, Live Monitored: read-only, revoke anytime. What we access →
Install from
The grade above is for the source repository. Registries can serve a different version, so we mark the ones we were not able to read.
These names and descriptions are the publisher's own, read from the source code. We print them as written. Our assessment is the findings above, not this list.
get_treesearch_tabssearch_pinakolist_librariesget_libraryget_main_tree_notesget_bookmarksfind_duplicatesget_tree_summarylist_browsersLists all Pinako installs currently connected to this MCP server. Each entry: browserBrand (human-readable name like "Chrome" or "Brave"), browserId (stable per-install id), updatedAt (timestamp of last data update — any tree mutation, memo edit, note write, etc.), windowCount (live windows), librar…
search_docsSearches the Pinako user guide. Returns ranked sections with title, anchor id, source ("user-guide" / "ai-connect" / "import" / "agent"), excerpt, and score. Bundled with this bridge, served from local cache (~10ms, no internet). Two RESERVED single-word queries address agent-only material and match…
set_tagsREPLACES the entire tag array on a node. Pass an empty array to clear all tags. Use add_tags / remove_tags for delta updates that preserve existing tags. Constraints: each tag max 50 chars; max 50 tags per node.
add_tagsAPPENDS tags to a node, deduping and preserving order of existing tags. Use this when the user says "tag X with Y" or "also add Z" — it preserves prior tags. Use set_tags for full replacement, remove_tags for deletion. Constraints: each tag max 50 chars; max 50 tags per node total (existing + append…
remove_tagsFilters specific tags off a node, preserving the rest. No-op for tags not present. Use this for "untag X from Y" requests. Constraints: each tag max 50 chars.
set_memoSets the memo (short plain-text annotation, max 2500 chars) on a node. Pass empty string to clear. Memos are per-node and concise; for richer rich-text documents use create_note / set_note_content (which target a library or the Main Notes, not individual nodes). The memo content field is named "text…
set_star_colorSets the row star color on a node. Accepts a named color (red, orange, yellow, green, blue, purple) OR its exact hex equivalent (#ff4d4f red, #fa8c16 orange, #fadb14 yellow, #52c41a green, #1890ff blue, #722ed1 purple). Arbitrary hex codes are NOT accepted — only the six pre-defined hex values. Pass…
set_row_colorSets the rowColor of a Window Group node or Folder node. NOT related to browser Tab Group color (a Tab Group's color is Chrome identity — use update_tab_group for that; tabgroup nodes are rejected here with INVALID_NODE_TYPE). Accepts: "accent2" (theme-tracking default), a named color ("blue", "red"…
set_titleSets a custom title on a tab, window, Window Group (type="group"), or folder node. Trimmed; max 200 chars. Sets customTitle=true so the title persists across browser restarts. Rejects tabgroup nodes with INVALID_TARGET (a Tab Group name is Chrome-coupled identity, not a customTitle overlay — use upd…
move_nodeMoves a node and its FULL subtree under newParentId (null = root, which auto-wraps a tab into a new window). To move a node WITHOUT its children, outdent its FIRST child first (sibling-adoption pulls the rest under it), then move the now-empty target — or wrap both in one bulk_apply. VALID PARENT BY…
move_node_to_libraryMoves a node and its FULL subtree OUT of one Library and INTO another (libraryId -> targetLibraryId). This is the ONLY tool that can cross a Library boundary in one step; move_node with scope:"library" moves within a single library and rejects a foreign destination. Both libraries change atomically,…
create_groupCreates a new Window Group node (type="group" — Pinako's organizational row for nesting windows). Window Groups can contain other Window Groups and windows but NOT tabs directly (tabs always live under a window, a tabgroup node, or another tab). Position defaults to TOP of the destination siblings (…
create_windowCreates a new window node by RELOCATING one or more existing tabs into it (tabIds, at least one; an empty window is invalid). Bundles loose tabs into a window in ONE atomic step instead of moving tabs to root one at a time. Scope "tree" (default) or "library" (libraryId required); NOT bookmarks. par…
create_tab_groupCreates a NEW browser Tab Group (the colored, named chip in the browser tab strip) by RELOCATING one or more existing tabs into a new type="tabgroup" node — create_window's contract one level down. The group forms in the FIRST listed tab's window, at that tab's position; tabs listed from OTHER windo…
update_tab_groupEdits a browser Tab Group's identity: title (rename; empty string "" clears back to untitled), color (Chrome's 9-color enum), and/or collapsed. At least one field required. This is the ONLY tool for tabgroup identity — set_title and set_row_color reject tabgroup nodes by design. LIVE groups: the cha…
ungroup_tab_groupDissolves a browser Tab Group: member tabs stay open (or stay saved, for a closed group) and keep their tree position — promoted in place where the group row was — and the group node is removed. Mirrors the UI's "Ungroup (keep tabs open)". NOT a delete: nothing closes and no data is lost, so no conf…
delete_nodeDESTRUCTIVE — permanently removes a GHOST node (chromeId=null) and its metadata (tags/memos/colors/title); for scope="bookmarks", removes the browser bookmark via chrome.bookmarks.remove. REFUSES subtrees containing any live tab (LIVE_NODE_REFUSED) — ghost_node first, then delete_node, or use delete…
ghost_nodeCloses the live browser tab(s) for this node and all live descendants, while preserving the tree node with chromeId=null on every ghosted node. Mirrors the manual "X" button. REVERSIBLE: the user can re-open from the tree later (URLs and metadata stay in the tree). Use this for "close these tabs but…
delete_live_nodeDESTRUCTIVE — closes the live browser tab(s) AND removes the tree node entirely (compound of ghost_node + delete_node, but bypasses delete_node's LIVE_NODE_REFUSED). Use when the user wants both the browser tabs gone AND the saved tree node gone. Mirrors the manual trash button on live nodes. SCOPE …
indent_nodeNests a node under its previous sibling (one level deeper). Rejects when the node has no prior sibling (INDENT_NO_PREV_SIBLING). Auto-expands the new parent. Works across tree, library, and bookmark scopes — a common pattern for quickly de-nesting then re-organizing tabs. For scope="bookmarks", the …
outdent_nodePromotes a node to its grandparent's level (one level shallower). Sibling-adoption preserves layout: the outdented node's younger siblings become its children, so visual row order is preserved. CHILD-EXTRACTION PATTERN: outdent the FIRST child of a target to free the target solo (target becomes empt…
create_libraryCreates a new empty library with an auto-seeded "Notes" note. Returns createdLibraryId and createdNoteId in the result. Use add_to_library afterwards to populate. For just creating an organizational umbrella over EXISTING libraries, use create_library_group instead. NOT IDEMPOTENT: each call creates…
add_to_libraryClones TREE nodes (windows/tabs/groups/folders) from a source surface into a library. Pass only source TREE ids (e.g. children[] from get_library), NOT note ids from notes[] (those will not resolve — duplicate a note via create_note instead). includeChildren default TRUE (subtree comes along, matchi…
add_to_bookmarksClones tree or library nodes INTO the browser bookmark tree (inverse of add_to_library). "save tab X as a bookmark" / "back up these to bookmarks" → this tool; "MOVE to bookmarks" → this tool then delete_node on the source (no atomic move in v1). sourceScope "tree" (default) or "library" (sourceLibr…
set_note_contentUpdates an existing note. mode "replace" (default) overwrites; "append" concatenates (the FINAL combined length is what's tier-gated: 50K Pro / 150K Pro+ / 250K Premium / 500K Enterprise). For prepend, read first then replace with the combined string. Content is sanitized (script / on* / javascript:…
create_noteCreates a new note in a library or in the Main Notes. Use this when the user says "create a note about X", "save these findings as a new note", etc. For UPDATING an existing note, use set_note_content. Returns createdNoteId. Char limit is tier-gated. Note content is sanitized at write time (HTML all…
delete_notePermanently deletes a note from a library or the main tree. Cloud-side delete is automatic on next persist (the per-scope notes sync diffs current ids against existing Supabase rows and removes missing ones). LAST-NOTE BEHAVIOR: this op allows deleting any note including the only note in a scope. Pi…
create_library_groupCreates a new library group (an organizational umbrella over multiple libraries). Returns createdGroupId. After creating, use add_library_to_group to add member libraries. NOT IDEMPOTENT: each call creates a new group. On transient failures, DO NOT auto-retry — call list_libraries to inspect existin…
delete_library_groupRemoves a library group. TWO MODES via cascadeMembers: (1) DEFAULT (cascadeMembers omitted/false) — DISSOLVE: member libraries are KEPT and re-appear in the standalone library card list at the position the group occupied. Safe; non-destructive. (2) cascadeMembers:true — DESTRUCTIVE: also deletes eac…
add_library_to_groupAdds an existing library to an existing group. A library can belong to at most one group; rejects with LIBRARY_ALREADY_IN_GROUP / LIBRARY_IN_OTHER_GROUP if it's already assigned somewhere.
remove_library_from_groupRemoves a library from a group, returning it to the standalone library card list right after the group. The library itself is preserved. No-op if the library wasn't in the group (removing a stale ref is valid cleanup).
set_library_group_titleRenames a library group. Trimmed, non-empty, max 200 chars.
set_library_group_descriptionUpdates a library group's description. Empty string clears it. Max 1000 chars.
set_library_titleRenames a library. Trimmed, non-empty, max 200 chars. THIS IS THE ONLY rename path for a library (the container) — set_title rejects the library container with INVALID_TARGET (the library root is type 'library', not a renamable tree node; in-library FOLDER nodes, type 'library-folder', ARE renamable…
set_library_descriptionUpdates a library's description (shown beneath the title on library cards). Empty string clears it. Max 1000 chars. Mirrors set_library_group_description for the umbrella-group case.
delete_libraryPermanently deletes a single library and ALL its content (tabs, notes, tags, memos, child windows/groups/folders). Removes the library from any group it belongs to AND from the panel order. DESTRUCTIVE: cannot be fully undone — Ctrl+Z restores the libraryData entry but does NOT restore the group/pan…
reorder_library_panelReorders the cards in the library panel (standalone library cards + library group cards). Pass the COMPLETE current list of entries in the desired order. Each entry is {type:"library"|"group", id:<id>}. ORDER ONLY — every existing entry must be present (rejects with PANEL_ORDER_MISMATCH if count dif…
create_folderCreates a new folder node in a library or in the browser bookmarks. NOT for the main tab tree (the main tree uses windows + groups, not folders). Required scope: "library" (with libraryId) or "bookmarks". Default position is TOP of the parent (matches manual UI). For bookmarks, the folder is also cr…
reorder_libraries_in_groupReorders the libraries within a single library group. Pass the COMPLETE current list of member library ids in the desired order. ORDER ONLY — every current member must be present (rejects with LIBRARY_ORDER_MISMATCH if count differs, LIBRARY_ORDER_UNKNOWN_MEMBER if an unknown id is introduced, LIBRA…
bulk_applyDisclosed vulnerabilities in this server's declared npm dependencies (via OSV). Whether each is reachable depends on the installed versions.
When Vitest UI server is listening, arbitrary file can be read and executed
GROK_HOMEHERMES_HOMEKIMI_CODE_HOMEOPENCLAW_STATE_DIRPINAKO_ALLOWED_HOSTSPINAKO_DEV_EXT_IDPINAKO_EXT_IDPINAKO_FORCE_BARE_MCP_URLPINAKO_MCP_PORTTool annotations
No tools have read-only/destructive annotations
Add readOnlyHint or destructiveHint annotations to every tool so hosts can warn users before invoking.
All four hints declared on every tool
49/49 tools missing one or more hints — get_tree (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint); search_tabs (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint); search_pinako (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint), +46 more. OpenAI's directory rejects tools where any of the four hints are missing or non-boolean.
For every tool, set all four hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) to explicit true/false values that match the handler’s actual behaviour.
Destructive tools are labelled
38 tools perform destructive updates without destructiveHint — set_tags deletes at line 269 (fs.rmSync(LOG_PATH + '.old', { force: true })); add_tags deletes at line 269 (fs.rmSync(LOG_PATH + '.old', { force: true })); remove_tags deletes at line 269 (fs.rmSync(LOG_PATH + '.old', { force: true }))
Add destructiveHint:true to any tool whose handler calls .delete(), .upsert(), .update(), unlink, rm, DELETE, DROP, REPLACE INTO, or any operation that overwrites existing data.
Descriptions match behaviour
2 tools describe read intent but their handlers mutate — add_to_bookmarks (line 255: fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true })); remove_library_from_group (line 255: fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true }))
Rename the tool, rewrite the description, or move the side-effect into a separate clearly-named tool.
Tool inputs are validated
48/49 tool handlers declare input schemas (98%)
Declare an inputSchema with zod/joi/yup on every tool definition.
Shell command execution
8 calls in production code run through a shell (setup/main.js:74, setup/main.js:78, setup/main.js:89)
Prefer library functions over shell-outs. If you must shell out, ensure all inputs are properly escaped.
Dev dependencies
1 critical/high in dev-only deps (does not ship to users)
Upgrade dev dependencies when convenient.
Tool description accuracy
3 tools have description/behavior mismatches: add_to_bookmarks: description implies read-only but handler writes/deletes/executes; remove_library_from_group: description implies read-only but handler writes/deletes/executes; reorder_libraries_in_group: description implies read-only but handler writes/deletes/executes
Update tool descriptions to accurately reflect all capabilities — especially write, delete, or execute operations.
Claim the listing to review these findings one by one and send us a correction where you disagree, straight to the team. Claiming also means we tell you when the grade moves, and reach you first if we find anything urgent.
[](https://m8ven.ai/mcp/teleomorph/pinako-mcp)?variant=verified from the URL.Vetting this one by hand? Tool Check is an MCP that scores other MCPs. Add it once and ask Claude, ChatGPT, or any MCP client to grade a server, surface CVEs, check the publisher, and suggest safer alternatives — before you install.
https://m8ven.ai/api/mcp/tool-check