Skip to content

Commit 78b3361

Browse files
authored
feat(skill): add safari reference card for AI-SRE Customize self-management (#60)
* feat(skill): add `safari` reference card for AI-SRE Customize self-management The `fduty safari` group (mcp-server-*, skill-*, a2a-agent-*, session-*) had no reference card, so the flashduty skill could not route install/configure intents to it — agents fell back to a tool search (wrong tool) and --help-dance. Seed `reference/safari.md` (skilldoc fence auto-filled from the cobra tree) + a SKILL.md domain-index row. Hot flows cover stdio and remote MCP install; key concepts document transport/scope/auth_mode and the per_user_oauth model: empty oauth_metadata is normal — the runtime auto-discovers + DCRs on first authorization; no OAuth client config is collected up front. `skilldoc check` passes (fence in sync; examples valid). * card(safari): drop skill-download, add session-delete (sync to current safari surface) Merge feat/ai-sre and regenerate the safari command card against the current cli: /safari/skill/download was reclassified jwt (console-only) and dropped from the public surface, while session-delete was added. The GENERATED fence syncs automatically; also update the hand-written intent table (remove the skill-download routing line, add session-delete to the session line).
1 parent 814a217 commit 78b3361

2 files changed

Lines changed: 232 additions & 0 deletions

File tree

skills/flashduty/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ Some asks span several commands. For those the skill ships a script that fetches
7171
| route / 分派路由 / alert routing 告警路由 / integration routing 集成路由 / routing case 路由用例 | **`reference/route.md`** |
7272
| RUM / real user monitoring / 真实用户监控 / frontend 前端 / application 应用 / issue | **`reference/rum.md`** |
7373
| status page / 状态页 / public incident 公开事件 / public timeline 公开时间线 / maintenance window 维护窗口 / subscriber 订阅者 | **`reference/status-page.md`** |
74+
| AI-SRE platform / customize / 安装配置 MCP server (connector) 连接器 / install mcp / skill upload 上传技能 / A2A agent / session export 会话导出 | **`reference/safari.md`** |
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# fduty safari — command card
2+
3+
Prereq: `SKILL.md` read. This is the **AI-SRE platform self-management** group: install/configure the account's own **MCP servers (connectors)**, **skills**, and **A2A agents**, plus inspect **sessions**. Mutating verbs (`create`, `update`, `delete`, `upload`) change account configuration — confirm before running. `delete` is **irreversible**.
4+
5+
> Registering an MCP server is THIS group (`fduty safari mcp-server-create`) — **not** a tool search. A tool search only discovers callable tools on servers already connected to you; it can neither register nor configure one.
6+
7+
## Route here when
8+
9+
"安装 / 添加 / 配置 MCP / connector / 连接器 / install mcp / add mcp server / 上传 skill / 自定义 skill / skill upload / A2A agent / customize / AI-SRE 平台配置 / session 导出" → **safari**. Key IDs: **`server_id`** (`mcp_…`) from `mcp-server-list`; **`skill_id`** from `skill-list`; **`agent_id`** from `a2a-agent-list`; **`session_id`** (`sess_…`).
10+
11+
## Intent → verb
12+
13+
| want | verb |
14+
|---|---|
15+
| list MCP servers / connectors | `mcp-server-list` |
16+
| install / register an MCP server | `mcp-server-create` |
17+
| change an MCP server's config | `mcp-server-update` |
18+
| turn an MCP server on / off | `mcp-server-enable` / `mcp-server-disable` |
19+
| inspect one MCP server (+ live tool probe) | `mcp-server-get` |
20+
| remove an MCP server | `mcp-server-delete` |
21+
| list / upload / update a skill | `skill-list` / `skill-upload` / `skill-update` |
22+
| enable / disable / delete a skill | `skill-enable` / `skill-disable` / `skill-delete` |
23+
| list / create / update an A2A agent | `a2a-agent-list` / `a2a-agent-create` / `a2a-agent-update` |
24+
| enable / disable / delete an A2A agent | `a2a-agent-enable` / `a2a-agent-disable` / `a2a-agent-delete` |
25+
| list / get / export / delete a session | `session-list` / `session-get` / `session-export` / `session-delete` |
26+
27+
## Hot flow — install an MCP server
28+
29+
Pass the nested `env` / `headers` objects through `--data` (they have no scalar flags); `args` has a repeatable `--args` flag but is shown via `--data` below for one-line copy-paste.
30+
31+
```bash
32+
# stdio (local process): command + args + secrets via env
33+
fduty safari mcp-server-create --data '{"server_name":"GitHub Tools","transport":"stdio","description":"Read issues and pull requests from GitHub.","command":"npx","args":["-y","@modelcontextprotocol/server-github"],"env":{"GITHUB_TOKEN":"ghp_xxx"},"team_id":0,"status":"enabled"}'
34+
35+
# remote (streamable-http) with per-user OAuth — oauth_metadata stays empty (auto-discovered + DCR at runtime)
36+
fduty safari mcp-server-create --data '{"server_name":"Aliyun OpenAPI","transport":"streamable-http","description":"Alibaba Cloud OpenAPI MCP.","url":"https://openapi-mcp.example.com/mcp","auth_mode":"per_user_oauth","team_id":0,"status":"enabled"}'
37+
38+
# confirm it registered, then inspect its live tool catalogue
39+
fduty safari mcp-server-list --output-format toon
40+
fduty safari mcp-server-get --data '{"server_id":"mcp_xxx"}'
41+
```
42+
43+
<!-- GENERATED:safari START · 由 fduty __dump-commands 同步 · 勿手改 fence 内 -->
44+
45+
### a2a-agent-create
46+
Create A2A agent
47+
- `--agent-name` string (required) — Agent display name. (≤128 chars)
48+
- `--auth-mode` string — Authentication mode: shared (default), per_user_secret, or per_user_oauth.
49+
- `--auth-type` string — Authentication type for the remote agent.
50+
- `--card-url` string (required) — URL of the remote agent card.
51+
- `--description` string — Agent description.
52+
- `--oauth-metadata` string — JSON OAuth metadata; reserved for per_user_oauth.
53+
- `--secret-schema` string — JSON secret schema; required when auth_mode=per_user_secret.
54+
- `--streaming` bool — Whether the remote agent supports streaming.
55+
- `--team-id` int64 — Team scope: 0 = account-wide; >0 = team.
56+
- body-only (`--data`): auth_config (object)
57+
58+
### a2a-agent-delete <agent-id>
59+
Delete A2A agent
60+
- `<agent-id>` (positional, required) string — Target agent ID.
61+
62+
### a2a-agent-disable <agent-id>
63+
Disable A2A agent
64+
- `<agent-id>` (positional, required) string — Target agent ID.
65+
66+
### a2a-agent-enable <agent-id>
67+
Enable A2A agent
68+
- `<agent-id>` (positional, required) string — Target agent ID.
69+
70+
### a2a-agent-get <agent-id>
71+
Get A2A agent detail
72+
- `<agent-id>` (positional, required) string — Target agent ID.
73+
74+
### a2a-agent-list
75+
List A2A agents
76+
- `--include-account` bool — Include account-scoped (team_id=0) rows. Defaults to true.
77+
- `--limit` int64 — Page size.
78+
- `--offset` int64 — Row offset for pagination.
79+
- `--team-ids` intSlice — Filter to these team IDs; empty = the caller's visible set.
80+
81+
### a2a-agent-update <agent-id>
82+
Update A2A agent
83+
- `<agent-id>` (positional, required) string — Target agent ID.
84+
- `--agent-name` string — New display name. Omit to leave unchanged. (≤128 chars)
85+
- `--auth-mode` string — New auth mode: shared, per_user_secret, or per_user_oauth.
86+
- `--auth-type` string — New auth type. Omit to leave unchanged.
87+
- `--card-url` string — New card URL. Omit to leave unchanged.
88+
- `--description` string — New description. Omit to leave unchanged.
89+
- `--oauth-metadata` string — New JSON OAuth metadata.
90+
- `--secret-schema` string — New JSON secret schema.
91+
- `--streaming` bool — Toggle streaming support. Omit to leave unchanged.
92+
- `--team-id` int64 — Reassign team scope. Omit to leave unchanged.
93+
- body-only (`--data`): auth_config (object)
94+
95+
### mcp-server-create
96+
Create MCP server
97+
- `--args` stringSlice — Command arguments (stdio transport).
98+
- `--auth-mode` string — Authentication mode: shared (default), per_user_secret, or per_user_oauth.
99+
- `--call-timeout` int64 — Tool-call timeout in seconds. 0 = default (60s).
100+
- `--command` string — Executable command (stdio transport).
101+
- `--connect-timeout` int64 — Connection timeout in seconds. 0 = default (10s).
102+
- `--description` string (required) — Server description. (1-1024 chars)
103+
- `--oauth-metadata` string — JSON OAuth metadata; reserved for per_user_oauth.
104+
- `--secret-schema` string — JSON secret schema; required when auth_mode=per_user_secret.
105+
- `--server-name` string (required) — MCP server name, unique within the account. (1-255 chars)
106+
- `--source-template-name` string — Marketplace template name when created from a connector template.
107+
- `--status` string — Initial status. · enum: enabled | disabled
108+
- `--team-id` int64 — Team scope: 0 = account-wide; >0 = team.
109+
- `--transport` string (required) — Transport protocol. · enum: stdio | sse | streamable-http
110+
- `--url` string — Server URL (sse / streamable-http transport).
111+
- body-only (`--data`): env (object); headers (object)
112+
113+
### mcp-server-delete <server-id>
114+
Delete MCP server
115+
- `<server-id>` (positional, required) string — Target MCP server ID.
116+
117+
### mcp-server-disable <server-id>
118+
Disable MCP server
119+
- `<server-id>` (positional, required) string — Target MCP server ID.
120+
121+
### mcp-server-enable <server-id>
122+
Enable MCP server
123+
- `<server-id>` (positional, required) string — Target MCP server ID.
124+
125+
### mcp-server-get <server-id>
126+
Get MCP server detail
127+
- `<server-id>` (positional, required) string — Target MCP server ID.
128+
129+
### mcp-server-list
130+
List MCP servers
131+
- `--include-account` bool — Include account-scoped (team_id=0) rows. Defaults to true.
132+
- `--limit` int64 — Page size.
133+
- `--page` int64 — Page number, 1-based.
134+
- `--search-after-ctx` string
135+
- `--team-ids` intSlice — Filter to these team IDs; empty = the caller's visible set.
136+
137+
### mcp-server-update <server-id>
138+
Update MCP server
139+
- `--args` stringSlice — Command arguments (stdio transport).
140+
- `--auth-mode` string — Authentication mode: shared (default), per_user_secret, or per_user_oauth.
141+
- `--call-timeout` int64 — Tool-call timeout in seconds. 0 = default (60s).
142+
- `--command` string — Executable command (stdio transport).
143+
- `--connect-timeout` int64 — Connection timeout in seconds. 0 = default (10s).
144+
- `--description` string — New description. (1-1024 chars)
145+
- `--oauth-metadata` string — JSON OAuth metadata; reserved for per_user_oauth.
146+
- `--secret-schema` string — JSON secret schema; required when auth_mode=per_user_secret.
147+
- `<server-id>` (positional, required) string — Target MCP server ID.
148+
- `--server-name` string — New name. (1-255 chars)
149+
- `--team-id` int64 — Reassign team scope: 0 = account-wide; >0 = team. Omit to leave unchanged.
150+
- `--transport` string — Transport protocol. · enum: stdio | sse | streamable-http
151+
- `--url` string — Server URL (sse / streamable-http transport).
152+
- body-only (`--data`): env (object); headers (object)
153+
154+
### session-delete <session-id>
155+
Delete session
156+
- `<session-id>` (positional, required) string — Target session ID. (≥1 chars)
157+
158+
### session-export <session_id>
159+
Stream a session's full event transcript as NDJSON
160+
- `--include-subagents` bool
161+
162+
### session-get <session-id>
163+
Get session detail
164+
- `--limit` int64 — Page size for events; takes precedence over 'num_recent_events'. 0 uses the server default (100). (0-1000)
165+
- `--num-recent-events` int64 — Legacy page size: number of most-recent events to return. Superseded by 'limit' when both are set; 0 uses the server default (100). (0-1000)
166+
- `--search-after-ctx` string — Opaque keyset cursor from a previous response; pass it back to fetch the next older page. (≤4096 chars)
167+
- `<session-id>` (positional, required) string — Target session ID. (≥1 chars)
168+
169+
### session-list
170+
List sessions
171+
- `--app-name` string (required) — Agent app whose sessions to list. · enum: ask-ai | support | support-website | support-flashcat | ai-sre | template-assistant | swe
172+
- `--asc` bool — Ascending order when true; applies only when 'orderby' is set.
173+
- `--entry-kinds` stringSlice — Restrict to sessions produced by these surfaces; empty returns every kind. · enum: web | im | api | automation
174+
- `--include-subagent-sessions` bool — Include subagent-dispatched sessions in the list.
175+
- `--keyword` string — Filter by session-name keyword. (≤64 chars)
176+
- `--limit` int64 — Page size, 1–100. (1-100)
177+
- `--orderby` string — Sort field. · enum: created_at | updated_at
178+
- `--page` int64 — Page number, 1-based. (min 1)
179+
- `--scope` string — Visibility scope: all (own + member-of-team rows, default), personal, or team. · enum: all | personal | team
180+
- `--search-after-ctx` string
181+
- `--status` string — Archive bucket: active (default) returns un-archived, archived returns archived, all returns both. · enum: active | archived | all
182+
- `--team-ids` intSlice — Optional explicit team filter; intersects with 'scope'.
183+
184+
### skill-delete <skill-id>
185+
Delete skill
186+
- `<skill-id>` (positional, required) string — Target skill ID.
187+
188+
### skill-disable <skill-id>
189+
Disable skill
190+
- `<skill-id>` (positional, required) string — Target skill ID.
191+
192+
### skill-enable <skill-id>
193+
Enable skill
194+
- `<skill-id>` (positional, required) string — Target skill ID.
195+
196+
### skill-get <skill-id>
197+
Get skill detail
198+
- `<skill-id>` (positional, required) string — Target skill ID.
199+
200+
### skill-list
201+
List skills
202+
- `--include-account` bool — Include account-scoped (team_id=0) rows. Defaults to true.
203+
- `--limit` int64 — Page size.
204+
- `--page` int64 — Page number, 1-based.
205+
- `--search-after-ctx` string
206+
- `--team-ids` intSlice — Filter to these team IDs; empty = the caller's visible set.
207+
208+
### skill-update <skill-id>
209+
Update skill
210+
- `--description` string — New description. (≤1024 chars)
211+
- `<skill-id>` (positional, required) string — Target skill ID.
212+
- `--team-id` int64 — Reassign team scope: 0 = account-wide; >0 = team. Omit to leave unchanged.
213+
214+
### skill-upload
215+
Upload skill
216+
217+
<!-- GENERATED:safari END -->
218+
219+
## Key concepts
220+
221+
- **Transport ⇒ which fields matter.** `stdio` uses `command` + `args` + `env`; `sse` / `streamable-http` use `url` + `headers`. The nested `env` / `headers` objects have no scalar flags — pass them through `--data '{...}'`; typed scalar flags (`--server-name`, `--url`, `--args`, …) override matching `--data` keys.
222+
- **Scope (`team_id`).** `0` = account-wide (every team sees it); `>0` = that team only. Same field on every safari verb.
223+
- **Auth mode (`auth_mode`).** `shared` (default) = one credential for everyone, stored on the server. `per_user_secret` = each user supplies a secret matching `secret_schema` (which must carry a `header_name`). `per_user_oauth` = each user authorizes the server via OAuth.
224+
- **`per_user_oauth` needs no OAuth config up front.** Create it with an **empty `oauth_metadata`** — that is the normal, complete state, not a missing prerequisite. The runtime **auto-discovers the OAuth server and dynamically registers a client (DCR)** the first time a user authorizes; you do **not** collect `authorization_url` / `client_id` / `client_secret` / `scopes`. Only pass `oauth_metadata` as a rare fallback, when the endpoint advertises no discovery document.
225+
226+
## Gotchas
227+
228+
- **`mcp-server-create` requires `server_name`, `description`, `transport`.** A `stdio` server also needs `command`; a remote (`sse` / `streamable-http`) server needs `url`.
229+
- **`env` / `headers` go through `--data`** — there are no `--env` / `--header` scalar flags for them (`args` does have a repeatable `--args` flag).
230+
- **Don't reach for a tool search to install or configure a server** — that only finds tools on already-connected servers. Registration and configuration are `mcp-server-create` / `mcp-server-update`.
231+
- **`delete` is irreversible** — prefer `disable` to park a server / skill / agent without destroying it. `list` first to confirm the id.

0 commit comments

Comments
 (0)