From remotelink
This skill provides domain knowledge for RemoteLink, a script execution and endpoint management platform. It should be used when the user asks about RemoteLink tasks, jobs, clients, groups, monitors, or patch profiles — for example: "why did this job fail", "what tasks run on this client", "show upcoming scheduled jobs", "find clients in a group", "what does this task do", "investigate job failures", or "query RemoteLink data". Also relevant when the user encounters naming confusion (e.g., Groups vs GroupBases) or needs to understand the execution activity chain. Requires a connected RemoteLink MCP server providing search, get_doc, query_database, and execute_script tools.
How this skill is triggered — by the user, by Claude, or both
Slash command
/remotelink:remotelinkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Domain wisdom, naming traps, and workflow guidance that the MCP tools can't tell you.
Domain wisdom, naming traps, and workflow guidance that the MCP tools can't tell you.
Use MCP tool descriptions for parameter details and get_doc for live schema — this skill covers what those sources miss.
SerializedScript JSON column and supplies parameters for each.SerializedScript JSON (each step has _actionId + params). For reverse lookup (find tasks by action type), use TaskActionVersionUsages join table.GroupBases, not Groups.Job (scheduled plan)
├─ what: Job → Tasks → Actions (via SerializedScript JSON, not FK)
├─ who: Job → ClientJobs → Clients (direct)
│ Job → JobGroupBases → GroupBases → ClientGroupBases → Clients (via groups)
└─ activity:
Job → JobRunRecord (one execution)
→ ClientJobRunRecord (one client's participation)
├─ ClientJobRunAttempt (one try; may retry)
│ → ClientJobRunAttemptLog (detailed output)
└─ ClientJobRunEvents (event type indicators)
Things that bite every agent on first encounter:
| You might try | Actual name | Why |
|---|---|---|
Groups | GroupBases | Groups doesn't exist as a queryable table. GroupBases unifies static and dynamic groups, with a Discriminator column ('StaticGroup'/'DynamicGroup'). |
Jobs → Clients (direct) | ClientJobs join table | Direct Job→Client assignment uses ClientJobs (columns: Client_Id, Job_Id). Not obvious from the Job entity. |
Groups → Clients | ClientGroupBases join table | Group membership is in ClientGroupBases (columns: GroupBase_Id, Client_Id), not ClientGroups. |
Reading Tasks.Actions via JOIN | SerializedScript column | Task→Action link is a JSON array in SerializedScript, not a relational FK. Each element has _actionId (GUID) and parameter values. For reverse lookup (tasks using an action), use TaskActionVersionUsages. |
Result / Status columns as strings | Always integers | All Result/Status columns are ints. Never assume meanings from column names — check actual values via get_doc or sample data. |
Tables the MCP won't surface through obvious searches:
ClientJobRunEvents — Has a Type column with event indicators (e.g., ClientAlreadyRunningJob, Failed, ClientConfirmTimeout). JOIN on ClientJobRunRecordId. Good for quick triage — for full failure details (exceptions, stack traces), use execute_script/getJobRunRecord with IncludeAttemptLogs: true.UpcomingJobRuns — Filter IsNextScheduledRun = 1 to get the actual next scheduled run. Without this filter, you'll also get future recovery runs.execute_script is for reads AND writes — It runs JavaScript in a Jint sandbox. getJobRunRecord with IncludeClientJobRunEvents: true returns richer data than raw SQL (human-readable result strings, event traces). Essential for failure diagnosis.execute_script is synchronous only — No top-level await. The Jint sandbox doesn't support it. All publicApi calls are synchronous.ClientJobRunAttemptLogs.LogData is varbinary — Can't read via SQL. Use execute_script with getJobRunRecord({ IncludeAttemptLogs: true }) instead.getTask API — There's no publicApi.getTask(). To read task content, use query_database on Tasks.SerializedScript.search with relevant keywords to find available publicApi methods. Method names are camelCase (e.g., getJobRunRecord, not GetJobRunRecord).query_database returns max 100 rows — Use COUNT(*), GROUP BY, or TOP N to work within this limit. Check for "truncated": true in results.log(JSON.stringify(fullResult)) can produce 700K+ characters. Select specific properties inside the script to keep output manageable.Failure investigation:
execute_script/getJobRunRecord with IncludeAttemptLogs: true — primary path for full failure details (exceptions, stack traces, script output). LogData is varbinary, not SQL-readable.query_database on ClientJobRunEvents (JOIN on ClientJobRunRecordId, check Type column for event indicators).FailCount/SuccessCount on JobRunRecords for reliable aggregates — avoids decoding Result integer values on ClientJobRunRecords.What does a task do?
query_database: SELECT Name, SerializedScript FROM Tasks WHERE Name LIKE '%keyword%'_actionId and parameterssearch for the action names to understand what each step doesUpcoming schedule + targets:
UpcomingJobRuns with IsNextScheduledRun = 1 → JOIN JobRunRecords → JobsJobs → ClientJobs → ClientsJobs → JobGroupBases → GroupBases → ClientGroupBases → ClientsFollow the activity chain for run investigation: Job → JobRunRecord → ClientJobRunRecord → ClientJobRunAttempt → ClientJobRunAttemptLog (each level adds detail)
npx claudepluginhub unwiredrevolution/uwr-marketplace --plugin remotelinkCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.