{"$schema":"https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json","_meta":{"me.stashr/manifest":"https://stashr.me/.well-known/mcp","me.stashr/oauth":{"authorizationServer":"https://stashr.me/api/auth","authorizationServerMetadata":"https://stashr.me/.well-known/oauth-authorization-server/api/auth","protectedResourceMetadata":"https://stashr.me/.well-known/oauth-protected-resource/mcp","scopes":["read","write","destructive","offline_access"]},"me.stashr/plan":"Requires a Stashr Pro plan or the 7-day card-free trial; sign up at /signup. Unauthenticated requests get 401 with WWW-Authenticate pointing at the protected-resource metadata."},"authentication":{"required":true,"schemes":["oauth2","bearer"]},"capabilities":{"tools":{"listChanged":false}},"description":"Hosted MCP server for a user's Stashr library: search saved posts by meaning, read them in full, view stored images, save URLs, and manage tags, notes, favorites, and collections. Interactive clients sign in with OAuth; non-interactive agents use a scoped stashr_ API key as a bearer token.","documentationUrl":"https://stashr.me/docs/mcp","homepage":"https://stashr.me/","iconUrl":"https://stashr.me/branding/logo512.png","instructions":"Stashr is the user's private bookmark library. Search before fetching when the user asks about saved knowledge. Fetch a bookmark for full content before quoting or summarizing it. Only save, edit, archive, restore, or delete when the user asks.","protocolVersion":"2025-11-25","serverInfo":{"name":"stashr","title":"Stashr","version":"1.0.0"},"tools":[{"description":"Search the user's Stashr bookmarks semantically. Use this before fetch when finding saved knowledge by meaning, wording, tag, author, platform, or content type. For visual queries (objects, colors, screenshots, layouts) set rankMode \"image\" to rank individual images by their captions; matched refs can be passed to view_media. Results include a nextCursor when more pages exist; a cursor only works with the exact same query, filters, and state. Ranking covers the top 200 candidates — narrow with filters rather than paging deep.","inputSchema":{"type":"object","properties":{"cursor":{"description":"Pass the nextCursor value from the previous page to continue paging","type":"string"},"filters":{"type":"object","properties":{"authorMode":{"type":"string","enum":["include","exclude"]},"authors":{"type":"array","items":{"type":"string","minLength":1,"description":"An author username (\"naval\"), optionally platform-scoped (\"twitter:naval\")"}},"capturedAfter":{"description":"Only bookmarks saved on/after this ISO date (inclusive)","type":"string"},"capturedBefore":{"description":"Only bookmarks saved before this ISO date (exclusive)","type":"string"},"contentTypeMode":{"type":"string","enum":["include","exclude"]},"contentTypes":{"type":"array","items":{"type":"string","description":"A content type (\"article\"), optionally platform-scoped (\"twitter:article\"). Valid types: image, post, video, comment, article, snippet"}},"favorite":{"description":"[\"favorite\"] = only favorites; [\"not-favorite\"] = only non-favorites","type":"array","items":{"type":"string","enum":["favorite","not-favorite"]}},"media":{"description":"Media presence: \"image\"/\"video\" = has that type, \"any-media\" = has any, \"text-only\" = has none (not combinable with the others)","type":"array","items":{"type":"string","enum":["image","video","any-media","text-only"]}},"mediaMode":{"type":"string","enum":["include","exclude"]},"note":{"description":"[\"has-note\"] = only bookmarks with a user note","type":"array","items":{"type":"string","enum":["has-note","no-note"]}},"platformMode":{"type":"string","enum":["include","exclude"]},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","reddit","tiktok","twitter","web","youtube"],"description":"Platform id — X/Twitter is \"twitter\""}},"tagMode":{"description":"include_any = OR (default), include_all = AND, exclude_any = none of these tags, exclude_all = not all of them","type":"string","enum":["include_any","include_all","exclude_any","exclude_all"]},"tags":{"type":"array","items":{"type":"string"}},"untagged":{"description":"true = only bookmarks with no tags at all","type":"boolean"}}},"limit":{"default":10,"type":"integer","minimum":1,"maximum":25},"query":{"type":"string","minLength":1,"maxLength":200},"rankMode":{"default":"post","description":"\"post\" ranks whole bookmarks; \"image\" ranks individual stored images by caption for visual queries","type":"string","enum":["post","image"]},"state":{"description":"Which bookmarks to search; defaults to active only","type":"string","enum":["active","archived","all"]}},"required":["query"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"search","title":"Search bookmarks"},{"description":"Fetch the complete content and metadata for one Stashr bookmark id returned by search or list_bookmarks. The text field is the full body rendered as Markdown (headings, lists, links, code, and inlined media preserved).","inputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"fetch","title":"Fetch bookmark"},{"description":"Fetch the complete content for up to 20 bookmark ids in one call — the same document shape as fetch. Use it when comparing or summarizing several saves from search or list results; missing lists ids that were not found. For a single id, prefer fetch.","inputSchema":{"type":"object","properties":{"ids":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["ids"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"fetch_many","title":"Fetch several bookmarks"},{"description":"View up to four selected stored images from a bookmark. Use refs returned by image-ranked search or fetch. Images are bounded previews; call only when visual inspection is useful.","inputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"refs":{"minItems":1,"maxItems":4,"type":"array","items":{"type":"string","minLength":1,"maxLength":500}}},"required":["id","refs"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"view_media","title":"View bookmark images"},{"description":"Browse bookmarks in reverse capture order with structured filters, or the contents of a saved collection via collectionId. Prefer search for free-text or semantic discovery. Results include a nextCursor when more pages exist.","inputSchema":{"type":"object","properties":{"collectionId":{"description":"List a saved collection's bookmarks: its stored filters are applied, with any explicit filters here overriding same-name ones","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"cursor":{"description":"Pass the nextCursor value from the previous page to continue paging","type":"string"},"filters":{"type":"object","properties":{"authorMode":{"type":"string","enum":["include","exclude"]},"authors":{"type":"array","items":{"type":"string","minLength":1,"description":"An author username (\"naval\"), optionally platform-scoped (\"twitter:naval\")"}},"capturedAfter":{"description":"Only bookmarks saved on/after this ISO date (inclusive)","type":"string"},"capturedBefore":{"description":"Only bookmarks saved before this ISO date (exclusive)","type":"string"},"contentTypeMode":{"type":"string","enum":["include","exclude"]},"contentTypes":{"type":"array","items":{"type":"string","description":"A content type (\"article\"), optionally platform-scoped (\"twitter:article\"). Valid types: image, post, video, comment, article, snippet"}},"favorite":{"description":"[\"favorite\"] = only favorites; [\"not-favorite\"] = only non-favorites","type":"array","items":{"type":"string","enum":["favorite","not-favorite"]}},"media":{"description":"Media presence: \"image\"/\"video\" = has that type, \"any-media\" = has any, \"text-only\" = has none (not combinable with the others)","type":"array","items":{"type":"string","enum":["image","video","any-media","text-only"]}},"mediaMode":{"type":"string","enum":["include","exclude"]},"note":{"description":"[\"has-note\"] = only bookmarks with a user note","type":"array","items":{"type":"string","enum":["has-note","no-note"]}},"platformMode":{"type":"string","enum":["include","exclude"]},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","reddit","tiktok","twitter","web","youtube"],"description":"Platform id — X/Twitter is \"twitter\""}},"tagMode":{"description":"include_any = OR (default), include_all = AND, exclude_any = none of these tags, exclude_all = not all of them","type":"string","enum":["include_any","include_all","exclude_any","exclude_all"]},"tags":{"type":"array","items":{"type":"string"}},"untagged":{"description":"true = only bookmarks with no tags at all","type":"boolean"}}},"limit":{"default":20,"type":"integer","minimum":1,"maximum":50},"state":{"default":"active","type":"string","enum":["active","archived","all"]}},"$schema":"http://json-schema.org/draft-07/schema#"},"name":"list_bookmarks","title":"List bookmarks"},{"description":"Save a public URL to Stashr. Repeated calls for the same URL are idempotent and return the existing bookmark.","inputSchema":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"}},"required":["url"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"save_bookmark","title":"Save bookmark"},{"description":"Update a bookmark's note, favorite state, tags, or reversible archive state. Tag values are tag names.","inputSchema":{"type":"object","properties":{"archived":{"type":"boolean"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"isFavorite":{"type":"boolean"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"tags":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string"}},"remove":{"type":"array","items":{"type":"string"}},"set":{"type":"array","items":{"type":"string"}}}}},"required":["id"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"update_bookmark","title":"Update bookmark"},{"description":"Archive or restore up to 200 bookmarks in one call. Archiving is reversible; returns the ids whose state actually changed.","inputSchema":{"type":"object","properties":{"archived":{"type":"boolean","description":"true archives the bookmarks, false restores them"},"ids":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["archived","ids"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"archive_bookmarks","title":"Archive or restore bookmarks"},{"description":"Aggregate counts over the user's library in one call: total plus breakdowns by platform, content type, and capture month, and favorite/untagged/note counts. Accepts the same filters as list_bookmarks. Use this for \"how many\" and overview questions instead of paging bookmarks.","inputSchema":{"type":"object","properties":{"filters":{"type":"object","properties":{"authorMode":{"type":"string","enum":["include","exclude"]},"authors":{"type":"array","items":{"type":"string","minLength":1,"description":"An author username (\"naval\"), optionally platform-scoped (\"twitter:naval\")"}},"capturedAfter":{"description":"Only bookmarks saved on/after this ISO date (inclusive)","type":"string"},"capturedBefore":{"description":"Only bookmarks saved before this ISO date (exclusive)","type":"string"},"contentTypeMode":{"type":"string","enum":["include","exclude"]},"contentTypes":{"type":"array","items":{"type":"string","description":"A content type (\"article\"), optionally platform-scoped (\"twitter:article\"). Valid types: image, post, video, comment, article, snippet"}},"favorite":{"description":"[\"favorite\"] = only favorites; [\"not-favorite\"] = only non-favorites","type":"array","items":{"type":"string","enum":["favorite","not-favorite"]}},"media":{"description":"Media presence: \"image\"/\"video\" = has that type, \"any-media\" = has any, \"text-only\" = has none (not combinable with the others)","type":"array","items":{"type":"string","enum":["image","video","any-media","text-only"]}},"mediaMode":{"type":"string","enum":["include","exclude"]},"note":{"description":"[\"has-note\"] = only bookmarks with a user note","type":"array","items":{"type":"string","enum":["has-note","no-note"]}},"platformMode":{"type":"string","enum":["include","exclude"]},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","reddit","tiktok","twitter","web","youtube"],"description":"Platform id — X/Twitter is \"twitter\""}},"tagMode":{"description":"include_any = OR (default), include_all = AND, exclude_any = none of these tags, exclude_all = not all of them","type":"string","enum":["include_any","include_all","exclude_any","exclude_all"]},"tags":{"type":"array","items":{"type":"string"}},"untagged":{"description":"true = only bookmarks with no tags at all","type":"boolean"}}},"state":{"default":"active","description":"Which bookmarks to count","type":"string","enum":["active","archived","all"]}},"$schema":"http://json-schema.org/draft-07/schema#"},"name":"library_stats","title":"Library stats"},{"description":"List the user's Stashr tags with usage counts. Use the returned tag names in bookmark filters and tag updates.","inputSchema":{"type":"object","properties":{},"$schema":"http://json-schema.org/draft-07/schema#"},"name":"list_tags","title":"List tags"},{"description":"Get the authenticated Stashr account: plan, trial status, and remaining AI-tag quota. Use this to explain payment_required errors or report account state.","inputSchema":{"type":"object","properties":{},"$schema":"http://json-schema.org/draft-07/schema#"},"name":"get_account","title":"Get account"},{"description":"List saved filter collections. Pass a collection id to list_bookmarks to read its contents.","inputSchema":{"type":"object","properties":{},"$schema":"http://json-schema.org/draft-07/schema#"},"name":"list_collections","title":"List collections"},{"description":"Create, update, or deliberately delete saved Stashr filter collections (use list_collections to read them). Create requires name; update and delete require id; delete also requires confirm=true.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["create","update","delete"]},"color":{"description":"A Stashr collection color id","type":"string"},"filters":{"type":"object","properties":{"authorMode":{"type":"string","enum":["include","exclude"]},"authors":{"type":"array","items":{"type":"string","minLength":1,"description":"An author username (\"naval\"), optionally platform-scoped (\"twitter:naval\")"}},"capturedAfter":{"description":"Only bookmarks saved on/after this ISO date (inclusive)","type":"string"},"capturedBefore":{"description":"Only bookmarks saved before this ISO date (exclusive)","type":"string"},"contentTypeMode":{"type":"string","enum":["include","exclude"]},"contentTypes":{"type":"array","items":{"type":"string","description":"A content type (\"article\"), optionally platform-scoped (\"twitter:article\"). Valid types: image, post, video, comment, article, snippet"}},"favorite":{"description":"[\"favorite\"] = only favorites; [\"not-favorite\"] = only non-favorites","type":"array","items":{"type":"string","enum":["favorite","not-favorite"]}},"media":{"description":"Media presence: \"image\"/\"video\" = has that type, \"any-media\" = has any, \"text-only\" = has none (not combinable with the others)","type":"array","items":{"type":"string","enum":["image","video","any-media","text-only"]}},"mediaMode":{"type":"string","enum":["include","exclude"]},"note":{"description":"[\"has-note\"] = only bookmarks with a user note","type":"array","items":{"type":"string","enum":["has-note","no-note"]}},"platformMode":{"type":"string","enum":["include","exclude"]},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","reddit","tiktok","twitter","web","youtube"],"description":"Platform id — X/Twitter is \"twitter\""}},"tagMode":{"description":"include_any = OR (default), include_all = AND, exclude_any = none of these tags, exclude_all = not all of them","type":"string","enum":["include_any","include_all","exclude_any","exclude_all"]},"tags":{"type":"array","items":{"type":"string"}},"untagged":{"description":"true = only bookmarks with no tags at all","type":"boolean"}}},"icon":{"description":"A Stashr collection icon id","type":"string"},"name":{"description":"Collection name, required for create","type":"string","minLength":1,"maxLength":50},"pinned":{"description":"Pin or unpin the collection in the sidebar (update only)","type":"boolean"},"confirm":{"description":"Must be true to delete a collection","type":"boolean"},"id":{"description":"Collection id, required for update and delete","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["action"],"$schema":"http://json-schema.org/draft-07/schema#"},"name":"manage_collection","title":"Manage collections"}],"transport":{"endpoint":"https://stashr.me/mcp","type":"streamable-http","url":"https://stashr.me/mcp"},"version":"1.0"}