Skip to content

MCP Server — Connect AI Assistants and Agents to Glassy

Two origins, by design. The appliance is the full-power lane: all 42 tools, named per-agent keys with a pinned identity, and no tool-call budget. Cloud runs the same server in single-key mode: 37 tools (five are appliance-only), tier budgets, and no named keys. GET /api/capabilities tells an agent which one it is talking to. This page describes the appliance lane and notes where cloud differs; the decision record supersedes the old "no MCP on hosted instances" posture.

Glassy includes a built-in Model Context Protocol (MCP) server that exposes 42 tools on a self-host appliance (37 on cloud — five are appliance-only: glassy_notify and the four review tools), 4 prompts, and 9 resources, and lets AI assistants and agents — including Claude, Cursor, Windsurf, OpenCode, Hermes, Openclaw, Pi, and any other MCP-compatible client — search and interact with your knowledge base directly.

Updated September 22, 2026 (v2.40.0 — the agent-identity release): the agent is a principal. Named per-agent MCP keys pin a verified identity onto the session, so authorship, memory and notifications key off a real agent rather than a shared anonymous key. New surface: durable agent memory (glassy_remember / glassy_recall — notes tagged agent-memory), the owner's awareness lane (glassy_notify, self-host only, ≤10/min), first-class session digests (glassy_create_digest), federated search (glassy_search gains corpora + weights; every result carries its corpus; a failed corpus is named in degraded), backlink-aware ranking, and the four document tools for long-form work. Per-source embedding widths are pinned: a mismatched write raises EMBEDDING_DIMENSION_MISMATCH naming the source, and a query against a pinned-differently source answers 409.

Updated September 9, 2026 (v2.36.0-beta.26+): The vault becomes a knowledge graph your agents can traverse — 7 new graph tools (glassy_get_backlinks, glassy_get_forward_links, glassy_graph_context, glassy_find_paths, glassy_get_orphans, glassy_get_central_notes, glassy_graph_stats) built from the indexed [[wikilink]] corpus, working even when Obsidian is closed, plus 2 live-vault tools (glassy_vault_read, glassy_vault_append — concurrency-safe append via ETag) and 2 new resources (glassy://vault/{path}, glassy://graph/note/{path}). On the appliance there are no tool-call rate limits — deep agentic loops run unthrottled. MCP tool-call budgets (120/hr free, 1,200/hr Pro) are a cloud-era mechanism and no longer apply to the self-hosted appliance.

Updated September 2, 2026 (v2.36.0-beta.22+): Five new time tools — glassy_get_schedule, confirm-gated glassy_create_event (returns a proposal unless confirm: true — never a silent write), glassy_update_event, glassy_delete_event (destructive), and Pro-gated glassy_find_free_slots — plus the glassy_daily_briefing prompt and the glassy://calendar/today resource. Agent-created events broadcast events_updated SSE so open dashboard tabs update live. See the Calendar page for the full workflow.

Updated July 29, 2026 (v2.35.0-beta.11+): The server reached 15 tools — 5 new navigation and voice capture tools — plus 6 resources (3 new: notes/{id}, tags, folders), destructiveHint on delete tools, openWorldHint on all tools, human-readable title on every tool. Built on the official @modelcontextprotocol/sdk v2. The Glassy Capture extension (v2.20.1) exposes a copy-pasteable config snippet in Settings → AI Tools (MCP) with the live server URL. SSE streaming supported in the Obsidian proxy.

Note-type compatibility (beta.37+)

The note tools use the same canonical type universe as the application: text, checklist, draw, youtube, music, rss, spotify, and vimeo. Do not treat capture categories as note types or assume that all notes are only text/checklist/rich. Refresh your client's tool schemas after upgrading; use the advertised schema for each tool's supported arguments. See Content Types for legacy normalization.

What is MCP?

The Model Context Protocol is an open standard that lets AI applications connect to external data sources. Instead of copying text into a chat window, your AI tool can search your actual knowledge base — bookmarks, notes, vault files — and get real results with citations. The Glassy implementation uses the official @modelcontextprotocol/sdk v2 with McpServer + NodeStreamableHTTPServerTransport (stateless) + createMcpExpressApp (DNS rebinding protection).

Setup

1. Enable the Feature Flag

In your .env file:

ENABLE_MCP_SERVER=true

Restart Glassy after changing flags.

2. Generate an MCP Key

  1. Open Glassy and go to Settings → Integrations.
  2. Find the MCP Connection section.
  3. Click Generate MCP Key.
  4. Copy the key immediately — it is shown only once and cannot be retrieved later.

The key looks like: gky_mcp_1a2b3c4d5e6f...

3. Configure Your AI Tool

Each client takes a different setup. Settings → Connections & data → AI tools (MCP) in Glassy shows a ready-to-copy version for each, with your server's URL filled in.

Claude Desktop

Claude Desktop launches local (stdio) MCP servers only — a url entry in its config is ignored. It reaches Glassy through the mcp-remote bridge, so Node.js must be installed. Add this to your claude_desktop_config.json, then restart Claude Desktop:

{
  "mcpServers": {
    "glassy": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:3000/mcp", "--header", "Authorization:${GLASSY_AUTH}"],
      "env": {
        "GLASSY_AUTH": "Bearer gky_mcp_YOUR_KEY_HERE"
      }
    }
  }
}
  • The key sits in env because Claude Desktop on Windows does not escape spaces inside args.
  • mcp-remote accepts plain http:// only for localhost / 127.0.0.1. For an appliance reached at a LAN or tailnet address over plain HTTP, add "--allow-http" to args.

Config file locations: - macOS: ~/Library/Application Support/Claude/claude_desktop_config.json - Windows: %APPDATA%\Claude\claude_desktop_config.json

Claude Code

Run once in a terminal (add --scope project to share it through the repository's .mcp.json):

claude mcp add --transport http glassy http://localhost:3000/mcp --header "Authorization: Bearer gky_mcp_YOUR_KEY_HERE"

Cursor

Add to your Cursor MCP settings:

{
  "mcpServers": {
    "glassy": {
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Bearer gky_mcp_YOUR_KEY_HERE"
      }
    }
  }
}

Other MCP-compatible clients

Windsurf, OpenCode, Hermes, Openclaw, Pi, and any other MCP client that supports the Streamable HTTP transport with custom headers can use the Cursor-style url + headers configuration. A client that only launches local servers (like Claude Desktop) needs a bridge such as mcp-remote.

Remote Glassy instances

If Glassy is hosted on a remote server, replace http://localhost:3000 with your server's URL (e.g., https://app.glassy.fyi). Ensure the MCP endpoint is accessible — you may need to configure your reverse proxy or firewall.

4. Verify the Connection

Once configured, restart your AI tool. You should see Glassy's tools available. Try asking:

"Search my Glassy knowledge base for notes about deployment"

Your AI assistant or agent will call glassy_search and return results from your actual bookmarks, notes, and vault files.

Available Tools

Each tool has a human-readable title for client display (Claude Desktop, Cursor, etc. prefer title over the machine name). Read-only tools are marked; delete tools carry destructiveHint: true so clients show confirmation dialogs.

Tool Title What It Does
glassy_search Search Knowledge Base Search across bookmarks, notes, documents, vault files, and voice transcripts using hybrid text + semantic search
glassy_get_recent Recent Items Fetch your most recent bookmarks and notes
glassy_list_notes List Notes Paginated note listing with tag, type, color, and cursor filters
glassy_read_note Read Note Read a single note by ID — full content, tags, and metadata
glassy_get_tags Get Tags Unified tag cloud across notes, bookmarks, documents, and voice
glassy_get_folders Get Folders Bookmark collections and document folders with counts
glassy_obsidian_query Search Obsidian Vault Search your Obsidian vault files specifically
glassy_add_capture Save Bookmark Save a URL as a bookmark with optional title, note, and tags
glassy_capture_voice Capture Voice Memo Save a voice memo with transcribed text, indexed for semantic search
glassy_note_create Create Note Create a new note (text, checklist, or rich format)
glassy_note_update Update Note Update an existing note's title, body, tags, or metadata
glassy_note_delete Delete Note Delete an existing note (destructive)
glassy_bookmark_update Update Bookmark Update an existing bookmark's title, note, tags, or collection
glassy_bookmark_delete Delete Bookmark Delete an existing bookmark (destructive)
glassy_obsidian_proxy Obsidian Proxy Transparent proxy to your Obsidian Local REST API's /mcp/ endpoint
glassy_get_backlinks Get Backlinks Vault graph: notes linking TO this note (inbound wikilinks) — works from the indexed corpus, even when Obsidian is closed
glassy_get_forward_links Get Forward Links Vault graph: notes this note links TO (outbound wikilinks), with resolution status
glassy_graph_context Get Graph Context The N-hop neighborhood of a note, traversing links AND backlinks
glassy_find_paths Find Graph Paths All shortest wikilink paths between two notes — "how are these connected?"
glassy_get_orphans Get Orphan Notes Indexed vault notes with zero connections — capture candidates to integrate
glassy_get_central_notes Get Central Notes Hub notes ranked by link degree and PageRank — your MOCs and concept hubs
glassy_graph_stats Get Graph Stats Graph health: nodes, edges, density, orphans, top hub
glassy_vault_read Read Vault Note Read the CURRENT content of a note from the live vault (bridge-first, direct fallback)
glassy_vault_append Append to Vault Note Append markdown to a live note — under a heading (surgical PATCH) or end of file (If-Match concurrency-safe)
glassy_get_schedule Read Your Schedule Today / this week / next week or an explicit date range — events with calendar colors and linked notes
glassy_create_event Create Event Propose a calendar event; writes only with confirm: true (created with source='agent')
glassy_update_event Update Event Move or edit an existing calendar event (time, title, linked note)
glassy_delete_event Delete Event Delete a calendar event (destructive)
glassy_find_free_slots Find Free Slots Pro — invert the busy map into free 30-minute blocks within a range
glassy_create_document Create Document Create a long-form document (journal, plan, draft). Documents hold long-form content where notes hold short captures
glassy_update_document Update Document Update a document by ID. Partial — only the fields you pass change; use it to append, rewrite, retitle, tag, pin or publish
glassy_list_documents List Documents Documents in your library, newest-first, with excerpts
glassy_read_document Read Document A single document by ID — full content, tags, folder and authorship metadata
glassy_delete_document Delete Document Delete a document from your Glassy library. Defaults to soft-delete (moves to trash); set permanent: true for irreversible removal (destructive)
glassy_request_review Ask the Owner Ask the owner a question about your work and get a click back. Pass linked_type/linked_id (note or document) when the question is about a specific item so they can open it. Poll with glassy_get_review
glassy_get_review Poll Review Answer Poll a request you made: status plus the owner's answer_choice, answer_comment, answered_by and answered_at
glassy_withdraw_review Withdraw Review Request Withdraw an open request so the owner can no longer answer it. Refused with NOT_OPEN once they have answered
glassy_report_review_outcome Report Review Outcome After the owner answers your review request, record what you then DID with that answer (e.g. "published the note to the public window") — closes the decision loop so the queue reads as a control loop, not one-way feedback

Which of these are appliance-only? Five tools are withheld from the hosted cloud build: glassy_notify, the four review tools (glassy_request_review, glassy_get_review, glassy_withdraw_review, glassy_report_review_outcome). So an appliance serves 42 tools and cloud serves 37. The review tools are gated because the surface that answers them — the owner's approval queue — is appliance-only: a cloud agent could file a request, poll it, and wait forever on a queue nobody could open. The refusal is therefore 403 FEATURE_NOT_AVAILABLE naming the tool, not a hang. The document tools are available on both. What cloud also withholds is the surrounding identity and awareness surface: named per-agent MCP keys (POST /api/mcp-keys answers 403 FEATURE_NOT_AVAILABLE on cloud, and the manifest reports agentIdentity.mode as single-key rather than named-keys) and the notification store (notifications.available: false).

The withheld list is machine-readable rather than prose-only: cloudGatedTools in the manifest names every tool this instance refuses, so an agent can tell "this instance cannot do that" from "I guessed the name wrong".

Do not trust a table — ask the instance. curl -s <your-instance>/api/capabilities reports the tool count, which surfaces are actually mounted (not merely declared), the cloud/self-host split, and the per-surface renderer policy. See Agent Review and Approvals for the owner's side of the review loop.

Available Resources

Resources let LLMs read data via URI without a tool call — useful for context injection and automatic discovery.

There are 9, in two kinds, and the difference matters if your client builds a resource picker from resources/list:

  • 3 static resources are returned by resources/list and can be browsed: glassy://tags, glassy://folders, glassy://status.
  • 6 URI templates are addressable but not enumerable, because their URIs contain a parameter ({query}, {id}, {path}, …). A client that only reads resources/list will legitimately see three and conclude the other six do not exist. Construct their URIs directly.
Resource URI Kind What It Returns
glassy://tags static (listed) Unified tag cloud across all content types
glassy://folders static (listed) Bookmark collections and document folders
glassy://status static (listed) Corpus indexing status and embedding counts
glassy://kb/search/{query} template Search results for a given query
glassy://recent/{sourceType} template Recent items (bookmarks, notes, or all)
glassy://notes/{id} template Full note content by ID
glassy://calendar/today template Today's calendar events — meetings with colors and linked notes
glassy://vault/{path} template The CURRENT content of a vault note, read live (e.g. glassy://vault/Notes/OAuth.md)
glassy://graph/note/{path} template The 2-hop knowledge-graph neighborhood of a vault note (links + backlinks)

What agents can rely on when writing (beta.41+)

Since v2.36.0-beta.41 every note write goes through a single server-side service, which makes four behaviours dependable rather than incidental. If you are configuring an agent against an older appliance, refresh its tool schemas after upgrading.

  • Edits are attributed. glassy_note_update records MCP agent as the last editor, so an agent's change is distinguishable from the owner's own. Before beta.41 it was not.
  • Deletes are recoverable, and restore is owner-only. glassy_note_delete soft-deletes into the bin and is idempotent — retrying after a timeout is safe and will not 404. Restoring requires the note's owner and returns a real 403 if you are not, rather than a hollow success.
  • Tags keep their characters. Bookmark tags adopted the canonical note tag policy: up to 20 tags of up to 64 characters, lowercased and trimmed, with accents, internal spaces and punctuation preserved. Résumé stays résumé instead of becoming rsum.
  • Bad tags are refused, not rewritten. A write carrying an invalid tag returns 422 INVALID_TAGS naming every offender, what was accepted anyway, and the limits — so an agent can correct its input instead of discovering the silent difference on a later read.

See Content Types for the tag rules as they apply in the app, and GIVE-THIS-TO-YOUR-AI-AGENT.md for the full agent brief shipped with the appliance.

Managing Your Key

  • Regenerate — click "Regenerate Key" in Settings to create a new key (old key is revoked immediately).
  • Revoke — click "Revoke Key" to permanently disable MCP access. Any AI tools using the key will lose access.
  • Key status — the MCP Connection section shows whether a key is active and when it was last used.

The same key also reads the REST API

On a self-host instance, a named agent key authenticates GET /api/* directly. A script no longer has to POST /api/auth/login with the owner's email and password to obtain a session token:

curl -s http://localhost:3000/api/notes -H "Authorization: Bearer gky_mcp_..."

That matters operationally, not just cosmetically. A JWT dies whenever the install rotates its signing secret — which every clean install does — so scripted integrations used to break all at once and fall back to re-authenticating with the owner's raw password. A named key is rotated deliberately, one agent at a time, and revoking it touches nobody else.

The lane is deliberately narrow. The narrowness is the security argument:

Restriction Mechanism
Reads only A POST/PUT/PATCH/DELETE carrying a named key is refused 403 AGENT_KEY_READ_ONLY before the key is resolved. This does not mean the agent cannot write — the same key writes freely through the MCP tools above. See below.
Self-host only On cloud the lane is not attempted at all, and an invalid token gets the ordinary 401 AUTH_TOKEN_INVALID.
Pinned account mcp_keys.account_id decides which account the key acts in, exactly as it does on MCP. An X-Account-Id header will not move it, so an agent cannot roam accounts by editing a header.
Same gates password_must_change (the first-boot wall), the inactivity lock and the account PIN lock all apply to a key, so a key is never a way around them.

Read-only is a choice, and it is not a limit on what your agent can do

A named key already carries full write authority through MCP — glassy_note_create, glassy_note_update, glassy_note_delete, glassy_add_capture, documents and events, all attributed to your agent. So AGENT_KEY_READ_ONLY does not mean "this agent cannot write"; it means write through MCP, read through either. The REST lane is deliberately a second path to the same data, not a second write path: duplicating writes would mean maintaining the validation, warning and audit contracts twice for no capability gained — and that is the exact shape of a real past defect (PATCH /api/notes/:id once answered ok while silently discarding a field the MCP path handled). If you want REST writes, ask for them as a design request rather than reporting the refusal as a bug.

Check instead of probing: GET /api/capabilities → capabilities.agentIdentity.restReadLanes is true where the lane exists and false on cloud. A key is also never accepted from a query string — it would land in every access log and proxy log on the way, which is why the SSE lane exchanges a short-lived ticket rather than accepting ?token=.

Security

  • MCP keys use the gky_mcp_ prefix and are encrypted at rest in the database.
  • Each key use mints a short-lived JWT (5 minutes) for session tracking.
  • Keys can be revoked instantly from Settings.
  • The MCP endpoint requires Bearer token authentication — unauthenticated requests receive 401.

Troubleshooting

Problem Solution
"Invalid MCP API key format" Ensure your key starts with gky_mcp_ and is copied exactly
"Invalid MCP API key" The key may have been revoked. Generate a new one in Settings
403 AGENT_KEY_READ_ONLY on POST/PUT/PATCH/DELETE Named keys authenticate reads only on the REST API. Writes need an owner session — deliberate, so a leaked key cannot change anything
Every GET /api/* returns 403 PASSWORD_CHANGE_REQUIRED The account still carries the first-boot password flag. See Self-hosting → If you are scripting the install
"Account deactivated" Your account may have been inactivity-deleted. Contact support
Tool returns empty results Ensure ENABLE_CORPUS_INDEXER and ENABLE_KB_QUERY are enabled and a backfill has been run
Connection refused Verify Glassy is running and the URL in your config is correct

Obsidian MCP Proxy

If you use Obsidian with the Local REST API plugin, Glassy can proxy Obsidian's MCP endpoint through its own /mcp gateway. This gives your AI tools a single MCP connection that covers both Glassy and Obsidian content.

Enable with:

ENABLE_OBSIDIAN_MCP_PROXY=true

Configure your Obsidian connection in Settings → Obsidian first, then enable the proxy flag. All requests to /mcp/* are forwarded to your Obsidian instance with SSRF protection.

Glassy Capture extension

The Glassy Capture browser extension (v2.17.1+) includes an AI Tools (MCP) section in its Settings panel. Click Get MCP Key & Config to fetch your key and a ready-to-paste JSON config snippet for Claude Desktop, Cursor, Windsurf, or any MCP-compatible client. The snippet includes your live server URL and bearer token — just copy and paste into your AI tool's MCP settings.

This eliminates the need to manually construct the config or navigate to the dashboard Settings → Integrations page — the key and snippet are available directly in the extension popup.