-
Notifications
You must be signed in to change notification settings - Fork 9
feat(mcp): auto-register MCP tools as first-class + RAG-aware prompt #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Smilez1985
wants to merge
24
commits into
turmyshevd:main
Choose a base branch
from
Smilez1985:feat/mcp-tool-auto-registration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
f27b003
feat(model): /model picker, live Ollama discovery, persistent choice
Smilez1985 40ae47f
docs(changelog): /model picker + live Ollama discovery + persistence
Smilez1985 ff4d67d
fix(prompts): respect BOT_LANGUAGE in system prompt
Smilez1985 f6d1cba
fix(onboarding): auto-complete when IDENTITY.md is already populated
Smilez1985 0f0a8c1
fix(display): respect BOT_LANGUAGE in error_screen SAY: text
Smilez1985 95d1f0c
docs(changelog): respect BOT_LANGUAGE end-to-end (prompt + display + …
Smilez1985 c965f22
feat(update): /update command + auto_update.sh with backup & rollback
Smilez1985 1d4b529
docs(changelog): /update command and auto_update.sh
Smilez1985 e0e941d
Merge branch 'fix/respect-bot-language' into deploy/all-features
Smilez1985 ff41a5b
Merge branch 'feat/self-update' into deploy/all-features
Smilez1985 ed08ac5
feat(battery): UPS HAT (C) monitoring + /battery command
Smilez1985 fe161de
Merge branch 'feat/ups-hat-battery' into deploy/all-features
Smilez1985 f13d9d9
feat(display): auto-detect Waveshare 2.13in V4 mono vs B (3-color) va…
Smilez1985 288aa3d
fix(heartbeat): reinforce BOT_LANGUAGE pin for the reflection prompt
Smilez1985 b5b427f
feat(rag): generic external RAG service integration on deploy
Smilez1985 6a39e35
feat(display): low-battery red accent on B variant
Smilez1985 4315a39
docs(display-skill): document variant + red-as-accent rule
Smilez1985 2fa300d
fix(battery): UPS HAT (C) is 1S not 2S — fix percentage formula
Smilez1985 9a3f5c1
fix: restore handlers + main + config after partial branch-checkout d…
Smilez1985 00462e4
fix(display): propagate BOT_NAME + move battery to footer centre
Smilez1985 140d3bd
fix(auto_mood): don't duplicate header metrics in the footer status text
Smilez1985 420539e
fix(heartbeat): pin language at BOTH ends of the reflection prompt
Smilez1985 5829c39
feat(mcp): bot as MCP client — minimal SSE client + LLM tools
Smilez1985 cd631b0
feat(mcp): auto-register MCP tools as first-class + RAG-aware system …
Smilez1985 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # OpenClawGotchi auto-update | ||
| # | ||
| # Fetches the configured upstream branch, fast-forwards if there are new | ||
| # commits, refreshes the venv's Python deps, restarts the systemd service, | ||
| # and rolls back automatically if the service fails to come back up. | ||
| # | ||
| # Idempotent and safe to run repeatedly (no-op when up-to-date). | ||
| # | ||
| # User state (.env, data/, .workspace/) is in .gitignore and never touched | ||
| # by `git pull`. As an extra safety net, gotchi.db + data/ + .env are | ||
| # tarballed to backups/ before each update; the last 3 are kept. | ||
| # | ||
| # Usage: | ||
| # bash scripts/auto_update.sh # update from origin/main | ||
| # bash scripts/auto_update.sh --check # exit 0 if updates available, 1 if not | ||
| # | ||
| # Env overrides: | ||
| # OCG_UPDATE_REMOTE (default: origin) | ||
| # OCG_UPDATE_BRANCH (default: main) | ||
| # OCG_SERVICE (default: gotchi-bot.service) | ||
| # OCG_BACKUP_KEEP (default: 3) — number of backups to retain | ||
| # OCG_NO_BACKUP=1 — skip the pre-update backup | ||
| # OCG_NO_ROLLBACK=1 — skip auto-rollback on service failure | ||
| # | ||
| # Cron suggestion (weekly, Sunday 04:00): | ||
| # 0 4 * * 0 /bin/bash /full/path/openclawgotchi/scripts/auto_update.sh \ | ||
| # >> /full/path/openclawgotchi/logs/update.log 2>&1 | ||
| # | ||
| # Exit codes: | ||
| # 0 success (updated or already up-to-date) | ||
| # 1 --check mode and no updates available | ||
| # 2 uncommitted changes block the update | ||
| # 3 service failed to start AND rollback was skipped/failed | ||
| # 4 service failed to start, rollback succeeded — manual review wanted | ||
| # | ||
| set -e | ||
|
|
||
| PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)" | ||
| cd "${PROJECT_DIR}" | ||
|
|
||
| REMOTE="${OCG_UPDATE_REMOTE:-origin}" | ||
| BRANCH="${OCG_UPDATE_BRANCH:-main}" | ||
| SERVICE="${OCG_SERVICE:-gotchi-bot.service}" | ||
| VENV_PIP="${PROJECT_DIR}/venv/bin/pip" | ||
| BACKUP_DIR="${PROJECT_DIR}/backups" | ||
| BACKUP_KEEP="${OCG_BACKUP_KEEP:-3}" | ||
|
|
||
| log() { echo "[$(date -Iseconds)] $*"; } | ||
|
|
||
| # --- Pre-flight: refuse if tracked files are modified (untracked is fine) --- | ||
| DIRTY_TRACKED="$(git status --porcelain | grep -v '^??' || true)" | ||
| if [ -n "${DIRTY_TRACKED}" ]; then | ||
| log "ERROR: tracked files have uncommitted changes. Commit/stash first." | ||
| echo "${DIRTY_TRACKED}" | ||
| exit 2 | ||
| fi | ||
|
|
||
| log "Fetching ${REMOTE}/${BRANCH}…" | ||
| git fetch --quiet "${REMOTE}" "${BRANCH}" | ||
|
|
||
| LOCAL_HEAD="$(git rev-parse HEAD)" | ||
| REMOTE_HEAD="$(git rev-parse "${REMOTE}/${BRANCH}")" | ||
| AHEAD_BY="$(git rev-list --count "HEAD..${REMOTE}/${BRANCH}")" | ||
|
|
||
| if [ "${AHEAD_BY}" = "0" ]; then | ||
| log "Up-to-date with ${REMOTE}/${BRANCH} (no new commits behind)." | ||
| [ "${1:-}" = "--check" ] && exit 1 || exit 0 | ||
| fi | ||
|
|
||
| log "${AHEAD_BY} new commit(s) on ${REMOTE}/${BRANCH}:" | ||
| git --no-pager log --oneline "HEAD..${REMOTE}/${BRANCH}" | head -20 | ||
|
|
||
| if [ "${1:-}" = "--check" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| # --- Backup user state (DB + small JSON state + .env) before pulling --- | ||
| BACKUP_FILE="" | ||
| if [ "${OCG_NO_BACKUP:-0}" != "1" ]; then | ||
| mkdir -p "${BACKUP_DIR}" | ||
| TS="$(date +%Y%m%d-%H%M%S)" | ||
| BACKUP_FILE="${BACKUP_DIR}/pre-update-${TS}-${LOCAL_HEAD:0:8}.tar.gz" | ||
| # Build list of things to back up that actually exist (no errors on first runs). | ||
| BACKUP_PATHS=() | ||
| [ -f gotchi.db ] && BACKUP_PATHS+=(gotchi.db) | ||
| [ -f .env ] && BACKUP_PATHS+=(.env) | ||
| [ -d data ] && BACKUP_PATHS+=(data) | ||
| if [ "${#BACKUP_PATHS[@]}" -gt 0 ]; then | ||
| log "Backing up user state to $(basename "${BACKUP_FILE}")…" | ||
| tar -czf "${BACKUP_FILE}" "${BACKUP_PATHS[@]}" 2>/dev/null | ||
| # Rolling retention — keep newest N | ||
| ls -1t "${BACKUP_DIR}"/pre-update-*.tar.gz 2>/dev/null \ | ||
| | tail -n +"$((BACKUP_KEEP + 1))" \ | ||
| | xargs -r rm -f | ||
| else | ||
| log "No user state to back up yet (skipping)." | ||
| BACKUP_FILE="" | ||
| fi | ||
| fi | ||
|
|
||
| # --- Track previous HEAD so we can roll back if the service fails --- | ||
| PREVIOUS_HEAD="${LOCAL_HEAD}" | ||
| REQS_CHANGED="$(git diff --name-only "HEAD..${REMOTE}/${BRANCH}" -- requirements.txt | head -1)" | ||
|
|
||
| log "Pulling ${REMOTE}/${BRANCH} (fast-forward only)…" | ||
| git pull --ff-only --quiet "${REMOTE}" "${BRANCH}" | ||
|
|
||
| if [ -n "${REQS_CHANGED}" ] && [ -x "${VENV_PIP}" ]; then | ||
| log "requirements.txt changed — refreshing venv dependencies…" | ||
| "${VENV_PIP}" install --quiet --upgrade -r requirements.txt | ||
| fi | ||
|
|
||
| # --- Restart and verify --- | ||
| restart_service() { | ||
| sudo systemctl restart "${SERVICE}" | ||
| sleep 4 | ||
| systemctl is-active --quiet "${SERVICE}" | ||
| } | ||
|
|
||
| if ! command -v systemctl >/dev/null 2>&1; then | ||
| log "systemctl not available, skipping service restart. Now at $(git rev-parse --short HEAD)." | ||
| exit 0 | ||
| fi | ||
|
|
||
| log "Restarting ${SERVICE}…" | ||
| if restart_service; then | ||
| log "OK — ${SERVICE} is active. Now at $(git rev-parse --short HEAD)." | ||
| [ -n "${BACKUP_FILE}" ] && log "Pre-update backup: $(basename "${BACKUP_FILE}")" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # --- Auto-rollback path --- | ||
| log "ERROR — ${SERVICE} failed to come back up after update." | ||
| journalctl -u "${SERVICE}" -n 20 --no-pager 2>&1 | sed 's/^/ | /' || true | ||
|
|
||
| if [ "${OCG_NO_ROLLBACK:-0}" = "1" ]; then | ||
| log "OCG_NO_ROLLBACK=1 — skipping rollback. Manual intervention needed." | ||
| exit 3 | ||
| fi | ||
|
|
||
| log "Rolling back to ${PREVIOUS_HEAD:0:8}…" | ||
| git reset --hard --quiet "${PREVIOUS_HEAD}" | ||
|
|
||
| if [ -n "${REQS_CHANGED}" ] && [ -x "${VENV_PIP}" ]; then | ||
| log "Reinstalling old requirements.txt…" | ||
| "${VENV_PIP}" install --quiet --upgrade -r requirements.txt | ||
| fi | ||
|
|
||
| if restart_service; then | ||
| log "Rollback succeeded — ${SERVICE} active at ${PREVIOUS_HEAD:0:8}." | ||
| log "The new version did not boot. Inspect with: journalctl -u ${SERVICE} -e" | ||
| exit 4 | ||
| else | ||
| log "FATAL — rollback also failed to start the service. Manual intervention required." | ||
| log "Last 20 service log lines:" | ||
| journalctl -u "${SERVICE}" -n 20 --no-pager 2>&1 | sed 's/^/ | /' || true | ||
| exit 3 | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document the MCP auto-registration feature.
The changelog describes the two generic tools (
mcp_list_tools,mcp_call_tool) but omits the auto-registration capability that is the main point of this PR. According to the PR objectives and test plan, whenRAG_TRANSPORT=mcpand the MCP server is reachable at startup, the code discovers advertised tools viatools/listand registers each as a first-class entry inTOOL_MAP, allowing the LLM to call them directly (e.g.,rag_search(query=..., top_k=3)) instead of the two-stepmcp_list_tools → mcp_call_toolflow.Additionally, the changelog doesn't mention the "External Memory (MCP)" system prompt section that is emitted when at least one MCP tool is registered, which instructs the agent when and how to use RAG tools.
📝 Suggested addition to document auto-registration
Consider adding a bullet point after line 11:
- New env var `RAG_TRANSPORT=rest|mcp` (default `rest`). When `mcp` is selected, `RAG_API_URL` is interpreted as the MCP-SSE base URL (e.g. `http://your-rag-host:8766`). +- **MCP tool auto-registration**: When `RAG_TRANSPORT=mcp` and the MCP server is reachable at startup, discovered tools (via `tools/list`) are automatically registered as first-class entries in `TOOL_MAP`. The LLM can call them directly (e.g., `rag_search(query, top_k)`) instead of using the generic two-step `mcp_list_tools` → `mcp_call_tool` flow. Colliding names are skipped; failures are gracefully logged. A "External Memory (MCP)" system prompt section is injected when registration succeeds, guiding the agent to search RAG before answering questions about preferences, project rules, or past context, and to persist durable lessons. - **`/model` Telegram command**: inline-keyboard model picker. Without args it opens buttons for every preset (gemini, glm, ollama). With an argument (`/model glm`) it falls through to the existing `/use` flow. `/use` and `/switch` remain as text aliases.🤖 Prompt for AI Agents