reactive-resume
amruthpillai
A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever. Try it out today!
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:Piccolo123/url-manager-mcp
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
Deliver results as beautiful cards, not raw link dumps. A Model Context Protocol server for saving, organizing, searching, and sharing web resources — cross-device sync, categories, tags, full-text search, batch operations, and team sharing. 21 tools with auto-registration so no manual setup is required.
📖 Usage patterns and best practices → URL Manager Skill
The content human users want to save is everywhere — a YouTube workout video, an Amazon gear link, a Substack training plan — scattered across platforms with no connection.
URL Manager fixes this. Paste any link from any platform. AI auto-identifies the content and suggests a category — confirm and it's a footprint. All saves flow into one platform-agnostic library, organized and always findable. Then share in one click — hand your curated knowledge base to your team, and everyone stays in sync.
A structured, searchable record — a web link, a plain-text note, an idea, or anything worth saving.
| Field | Type | Description |
|---|---|---|
id |
UUID | Permanent unique identifier — use for all operations |
url |
string (8192) | Original link. Can be empty for text-only footprints |
title |
string (512) | Short title |
description |
string (1024) | Additional context or notes |
content_type |
string (50) | Free text (e.g. article, video, image). Use list_content_types() to see existing values |
category_ids |
list[int] | Which categories this belongs to — you assign |
tag_names |
list[str] | Free-form keywords — you assign |
A footprint can belong to multiple categories simultaneously.
Like a folder, but a footprint can be in several at once.
| Field | Type | Description |
|---|---|---|
id |
int | Permanent numeric identifier — always reference by ID |
name |
string (50) | Display name |
mode |
string | null | null = personal, "cocreate" = shared co-edit, "subscribe" = shared read-only |
A container that groups related categories. Every user starts with "My Categories" (personal) and "Shared Categories" (shared container).
Category Sets (workspaces)
└── Categories (labels like "Shopping", "Learning")
└── Footprints
└── Tags (free-form keywords)
| Personal | Shared | |
|---|---|---|
mode |
null |
"cocreate" or "subscribe" |
| Visible to | Only you | You + invited members |
| Members & invite links | No | Yes |
Cocreate — everyone adds/removes footprints. Subscribe — read-only for members (writing returns 403).
| Action | Owner | Admin | Member |
|---|---|---|---|
| Add/remove footprints (cocreate) | ✅ | ✅ | ✅ |
| Add/remove footprints (subscribe) | ✅ | ❌ | ❌ |
| Generate invite link (cocreate) | ✅ | ✅ | ✅ |
| Generate invite link (subscribe) | ✅ | ❌ | ❌ |
| Switch cocreate ↔ subscribe | ✅ | ❌ | ❌ |
| Manage members | Web UI only | — | — |
agent_register()
Create a new account. No parameters. Token is auto-applied for all subsequent calls.
⚠️ Call once only — each invocation creates a fresh account.
my_info()
Verify connection and token validity. Returns username and membership status.
search_footprints(query, limit, offset)
Full-text search across titles, descriptions, and URLs.
query (required) — Search keywordslimit — Results per page (default 10, max 100)offset — Pagination offset (default 0)list_footprints(category_id, limit, offset)
List bookmarks by category. category_id=0 returns all.
limit — Results per page (default 20, max 100)offset — Pagination offset (default 0)get_footprint(footprint_id)
Get full details of a single bookmark.
footprint_id (required) — From list_footprints or search_footprints results (field id)add_footprint(url, title, description, category_ids, tag_names)
Add a new bookmark. Call list_categories() and list_tags() first to discover existing structure.
url (required) — Web page URLtitle — Leave empty to auto-extract from the pagedescription — Summary or notescategory_ids — Comma-separated IDs, e.g. "1,3"tag_names — Comma-separated names, e.g. "AI,tutorial"update_footprint(footprint_id, title, description, category_ids, tag_names)
Update a bookmark. Omitted fields stay unchanged.
⚠️ category_ids replaces the entire list — not append. Call get_footprint() first, then merge IDs.
footprint_id (required) — From search or list resultslist_categories()
List all categories (personal + shared). Returns id, name, and mode fields.
mode=null → personal; mode="cocreate"/"subscribe" → shared.
create_category(name, category_set_id)
Create a new category. Check list_categories() first to avoid duplicates.
name (required) — Category namecategory_set_id — Parent category set (0 = default)list_tags()
List all tags used by this account.
list_content_types()
List all content types the user has used (e.g. article, video, image), ordered most-used first. Use before adding to pick a consistent content_type.
list_category_sets()
List all category sets.
create_category_set(name)
Create a new category set (a container of categories).
name (required) — Category set namecreate_shared_category(name, mode, description)
Create a shared category for team collaboration.
name (required)mode (required) — "cocreate" (multiple editors) or "subscribe" (read-only)description — Optional description
⚠️ In subscribe mode, adding bookmarks returns 403. Use "cocreate" for editable collaboration.create_invite_link(shared_category_id, duration_hours)
Generate an invite link for others to join.
shared_category_id (required) — From list_categories() (shared entries)duration_hours — Default 24join_shared_category(invite_code)
Join a shared category by invite code.
invite_code (required) — 8-character code from the invite linkadd_to_shared_category(shared_category_id, footprint_id)
Add one of your own bookmarks to a shared category.
remove_from_shared_category(shared_category_id, footprint_id)
Remove a bookmark from a shared category. Does not delete the bookmark itself.
copy_footprint(footprint_id, category_ids)
Copy a bookmark from a shared category into your personal collection.
batch_update_footprints(updates)
Bulk edit up to 50 bookmarks at once.
updates (required) — JSON string: [{"id":"...", "title":"New Title", "category_ids":"1,3"}, ...]
Each object may contain title, description, category_ids, tag_names; id is required.agent_magic_link()
🔑 The delivery loop core. After organizing, generate a link → send to user. They click to see a card-based interface with all their organized bookmarks. Valid for 30 days, reusable.
1. agent_register() → get token (auto-memorized)
2. add_footprint(url="...") × N → save bookmarks one by one
3. list_categories() → understand current structure
4. create_category(name="Learning") → create a category
5. update_footprint(id, category_ids="...") → categorize
6. agent_magic_link() → "Done! View your collection here → [link]"
1. my_info() → confirm identity
2. list_categories() + list_tags() → understand current structure
3. search_footprints(query) or list_footprints(category_id) → find targets
4. add_footprint / update_footprint → operate
5. agent_magic_link() → deliver results
1. create_shared_category(name="Team KB", mode="cocreate")
2. create_invite_link(shared_category_id=<returned ID>)
3. Send invite code to user → user shares with teammates
4. Teammates' agents join via join_shared_category(invite_code)
# ❌ Wrong: moving bookmark 42 to category 7 loses existing categories 3 and 5
update_footprint(42, category_ids="7")
# ✅ Right: fetch current categories first, then merge
get_footprint(42) → existing categories [3, 5]
update_footprint(42, category_ids="3,5,7")
Writing to a subscribe-mode shared category returns 403. If the user says "I subscribed but can't add anything", explain it's read-only — the creator needs to change it to cocreate.
Each call creates a fresh empty account. Always check for a saved token first. If unsure, call my_info() to verify the current token is valid.
Rapid consecutive calls may trigger HTTP 429. Add short delays between batch operations; on 429, wait a few seconds and retry.
Inviting or removing members from shared categories requires the web UI at https://ai.ocean94.com. You cannot do this programmatically.
search_footprints for targeted queries instead of dumping everythinglist_categories() and list_tags() before adding to avoid duplicatesURL Manager excels at saving and organizing. Pair it with tools that excel at discovering and fetching:
Fetch MCP scrapes web → add_footprint() → auto-categorized, permanent, searchable
Firecrawl crawls pages → add_footprint() → organized into cards
Brave Search finds URLs → add_footprint() → one-click save from search results
Agents just pass the upstream MCP's URL + title as params to add_footprint.
git clone https://github.com/Piccolo123/url-manager-mcp.git
cd url-manager-mcp
pip install -r requirements.txt
Or from PyPI:
uvx url-manager-mcp # or: pip install url-manager-mcp
https://ai.ocean94.comAdd to your profile's cordis.patch.yml (e.g. ~/.dsh/profiles/headless/cordis.patch.yml or the web profile):
- insert:
- id: mcp-url-manager
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: url_manager
transport: stdio
command: uvx
args: ['url-manager-mcp']
env:
FOOTPRINTS_ENDPOINT: 'https://ai.ocean94.com'
All 21 tools appear as mcp__url_manager__* (add_footprint, search_footprints, list_categories, agent_magic_link, …). The model auto-registers on first use — no API key needed. The companion skill (Piccolo123/url-manager) is also auto-discovered by dsh when cloned into ~/.dsh/skills/.
{
"mcpServers": {
"url-manager": {
"command": "python",
"args": ["path/to/url-manager-mcp/server.py"]
}
}
}
If the user has an existing account:
{
"mcpServers": {
"url-manager": {
"command": "python",
"args": ["path/to/url-manager-mcp/server.py"],
"env": {
"FOOTPRINTS_TOKEN": "FA_xxxxxxxxxxxx"
}
}
}
}
Same JSON structure as above. Works with any MCP-compatible client supporting STDIO transport.
This server supports both STDIO (default) and Streamable HTTP transports:
# STDIO (default)
python server.py
# Streamable HTTP (for Docker / Glama / hosted environments)
python server.py --http
docker build -t url-manager-mcp .
docker run -e FOOTPRINTS_TOKEN="FA_xxx" url-manager-mcp
One-click hosted deployment: url-manager-mcp
Browser bookmarks are flat lists with no organization, no search, and no sharing. URL Manager adds:
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: mcp、mcp-server。