@qvac/skills 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled.js +10 -10
- package/hash.js +1 -1
- package/package.json +1 -1
- package/skills/apple-notes/SKILL.md +19 -19
- package/skills/asana/SKILL.md +63 -0
- package/skills/gmail/SKILL.md +66 -30
- package/skills/gmail/operations.json +23 -0
- package/skills/google-calendar/SKILL.md +51 -0
- package/skills/google-docs/SKILL.md +52 -0
- package/skills/google-drive/SKILL.md +51 -0
- package/skills/google-sheets/SKILL.md +52 -0
- package/skills/notion/SKILL.md +29 -0
- package/skills/spotify/SKILL.md +53 -6
package/hash.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Autogenerated by scripts/build.mjs from skills/. Do not edit.
|
|
2
|
-
export const SKILLS_HASH = '
|
|
2
|
+
export const SKILLS_HASH = '8ce2fae4970bf369'
|
package/package.json
CHANGED
|
@@ -5,28 +5,28 @@ tools: [exec(osascript)]
|
|
|
5
5
|
platform: [darwin]
|
|
6
6
|
metadata:
|
|
7
7
|
{
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
"openclaw": {
|
|
9
|
+
"requires": {
|
|
10
|
+
"bins": [
|
|
11
|
+
"osascript"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"setup": {
|
|
15
|
+
"summary": "Apple Notes works through macOS automation (osascript), which ships with macOS — nothing to install. The first command triggers a one-time permission prompt to let this app control Notes.",
|
|
16
|
+
"routes": [
|
|
12
17
|
{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
[
|
|
22
|
-
'Use the skill once — macOS shows a permission prompt to allow control of Notes.',
|
|
23
|
-
'Click Allow.',
|
|
24
|
-
'If it was denied, enable it under System Settings → Privacy & Security → Automation.'
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
]
|
|
18
|
+
"kind": "instructions",
|
|
19
|
+
"label": "Allow Notes automation",
|
|
20
|
+
"description": "macOS asks once for permission to control Notes. Commands fail until it's granted.",
|
|
21
|
+
"steps": [
|
|
22
|
+
"Use the skill once — macOS shows a permission prompt to allow control of Notes.",
|
|
23
|
+
"Click Allow.",
|
|
24
|
+
"If it was denied, enable it under System Settings → Privacy & Security → Automation."
|
|
25
|
+
]
|
|
28
26
|
}
|
|
27
|
+
]
|
|
29
28
|
}
|
|
29
|
+
}
|
|
30
30
|
}
|
|
31
31
|
---
|
|
32
32
|
|
package/skills/asana/SKILL.md
CHANGED
|
@@ -6,6 +6,69 @@ platform: [darwin, linux, win32]
|
|
|
6
6
|
credentials: [asana_mcp_access_token]
|
|
7
7
|
allow_list: [https://mcp.asana.com/v2/mcp]
|
|
8
8
|
mcp_reads: [get_task, get_tasks, get_my_tasks, get_projects, search_tasks, search_objects]
|
|
9
|
+
metadata:
|
|
10
|
+
{
|
|
11
|
+
"openclaw": {
|
|
12
|
+
"setup": {
|
|
13
|
+
"routes": [
|
|
14
|
+
{
|
|
15
|
+
"kind": "oauth",
|
|
16
|
+
"label": "Asana",
|
|
17
|
+
"provider": "asana",
|
|
18
|
+
"credentialKey": "asana_mcp_access_token",
|
|
19
|
+
"description": "Tasks, projects, and comments",
|
|
20
|
+
"helpUrl": "https://app.asana.com/0/my-apps",
|
|
21
|
+
"steps": [
|
|
22
|
+
"Click Connect and approve access in the browser. Approving grants access to the Asana workspace you allow."
|
|
23
|
+
],
|
|
24
|
+
"configSteps": [
|
|
25
|
+
"[Open the Asana developer console](https://app.asana.com/0/my-apps) and create an MCP app",
|
|
26
|
+
"In OAuth settings, add the exact redirect URI shown below",
|
|
27
|
+
"In \"Manage distribution\", allow the workspace you want this connection to access"
|
|
28
|
+
],
|
|
29
|
+
"fields": [
|
|
30
|
+
{
|
|
31
|
+
"key": "clientId",
|
|
32
|
+
"label": "Client ID",
|
|
33
|
+
"placeholder": "OAuth client ID from your app"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"key": "clientSecret",
|
|
37
|
+
"label": "Client Secret",
|
|
38
|
+
"secret": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"oauth": {
|
|
42
|
+
"stateKey": "asana_oauth",
|
|
43
|
+
"authUrl": "https://app.asana.com/-/oauth_authorize",
|
|
44
|
+
"tokenUrl": "https://app.asana.com/-/oauth_token",
|
|
45
|
+
"tokenAuth": "secret-in-body",
|
|
46
|
+
"port": 18981,
|
|
47
|
+
"scopes": [],
|
|
48
|
+
"extraAuthParams": {
|
|
49
|
+
"resource": "https://mcp.asana.com/v2"
|
|
50
|
+
},
|
|
51
|
+
"verify": {
|
|
52
|
+
"url": "https://mcp.asana.com/v2/mcp",
|
|
53
|
+
"method": "POST",
|
|
54
|
+
"body": {
|
|
55
|
+
"jsonrpc": "2.0",
|
|
56
|
+
"id": 1,
|
|
57
|
+
"method": "initialize",
|
|
58
|
+
"params": {
|
|
59
|
+
"protocolVersion": "2025-03-26",
|
|
60
|
+
"capabilities": {},
|
|
61
|
+
"clientInfo": { "name": "qvac", "version": "1.0.0" }
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"reject": [{ "status": [401, 403], "error": "asana_not_mcp_app" }]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
9
72
|
---
|
|
10
73
|
|
|
11
74
|
# Asana
|
package/skills/gmail/SKILL.md
CHANGED
|
@@ -2,15 +2,66 @@
|
|
|
2
2
|
name: gmail
|
|
3
3
|
description: Read, search, send, and manage Gmail messages and labels via the Gmail REST API.
|
|
4
4
|
aliases: [inbox, email+send, email+draft, email+reply, email+forward]
|
|
5
|
-
tools: [http_request, gmail_send, gmail_draft]
|
|
5
|
+
tools: [http_request, gmail_get, gmail_send, gmail_draft]
|
|
6
6
|
platform: [darwin, linux, win32]
|
|
7
7
|
credentials: [gmail_access_token]
|
|
8
8
|
allow_list: [https://gmail.googleapis.com/gmail/v1/users/me/]
|
|
9
|
+
metadata:
|
|
10
|
+
{
|
|
11
|
+
"openclaw": {
|
|
12
|
+
"setup": {
|
|
13
|
+
"routes": [
|
|
14
|
+
{
|
|
15
|
+
"kind": "oauth",
|
|
16
|
+
"label": "Gmail",
|
|
17
|
+
"provider": "google",
|
|
18
|
+
"credentialKey": "gmail_access_token",
|
|
19
|
+
"description": "Read, search, send, and manage Gmail messages and labels",
|
|
20
|
+
"steps": [
|
|
21
|
+
"Click Connect and approve access in the browser. Approving grants access to your Gmail only.",
|
|
22
|
+
"Each Google skill is connected separately, with its own app and its own approval."
|
|
23
|
+
],
|
|
24
|
+
"configSteps": [
|
|
25
|
+
"[Open Google Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=gmail.googleapis.com) to enable the Gmail API",
|
|
26
|
+
"[Open OAuth clients](https://console.cloud.google.com/auth/clients) to create an OAuth client — choose \"Web application\" as the type",
|
|
27
|
+
"[Open OAuth audience](https://console.cloud.google.com/auth/audience) and add your Google account as a test user"
|
|
28
|
+
],
|
|
29
|
+
"fields": [
|
|
30
|
+
{
|
|
31
|
+
"key": "clientId",
|
|
32
|
+
"label": "Client ID",
|
|
33
|
+
"placeholder": "OAuth client ID from your app"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"key": "clientSecret",
|
|
37
|
+
"label": "Client Secret",
|
|
38
|
+
"secret": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"oauth": {
|
|
42
|
+
"stateKey": "gmail_oauth",
|
|
43
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
|
|
44
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
|
45
|
+
"tokenAuth": "secret-in-body",
|
|
46
|
+
"port": 18978,
|
|
47
|
+
"scopes": [
|
|
48
|
+
"https://www.googleapis.com/auth/gmail.modify"
|
|
49
|
+
],
|
|
50
|
+
"extraAuthParams": {
|
|
51
|
+
"access_type": "offline",
|
|
52
|
+
"prompt": "consent"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
9
60
|
---
|
|
10
61
|
|
|
11
62
|
# Gmail
|
|
12
63
|
|
|
13
|
-
|
|
64
|
+
Read with `gmail_get`, send with `gmail_send`, draft with `gmail_draft`. `http_request` is only for list/search, labels and trash. The Gmail credential is attached automatically to every `gmail.googleapis.com` request — **never include an `auth` block**. Never run code.
|
|
14
65
|
|
|
15
66
|
## Prerequisites
|
|
16
67
|
|
|
@@ -25,11 +76,13 @@ set the `gmail_access_token` credential.
|
|
|
25
76
|
|
|
26
77
|
The host is `gmail.googleapis.com` — not `www.googleapis.com`. Send is at `/messages/send`, never `/send`.
|
|
27
78
|
|
|
28
|
-
##
|
|
79
|
+
## Read messages
|
|
29
80
|
|
|
30
|
-
|
|
81
|
+
1. List with `http_request`. Use `q` for Gmail search (`from:`, `subject:`, `is:unread`, `newer_than:7d`, `has:attachment`, `label:work`). Keep `maxResults` ≤ 10. The result is ids only.
|
|
82
|
+
2. Call `gmail_get` with each `id`. It returns `headers` (From, To, Subject, Date), `snippet` and, with `format: "full"`, `text`.
|
|
83
|
+
3. Answer from those fields. Never run code.
|
|
31
84
|
|
|
32
|
-
`
|
|
85
|
+
`http_request` to list:
|
|
33
86
|
|
|
34
87
|
```json
|
|
35
88
|
{
|
|
@@ -39,32 +92,15 @@ The host is `gmail.googleapis.com` — not `www.googleapis.com`. Send is at `/me
|
|
|
39
92
|
}
|
|
40
93
|
```
|
|
41
94
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
For lists and summaries always use `format=metadata` — it skips the body and is far cheaper than `full`.
|
|
95
|
+
`gmail_get` for each id:
|
|
45
96
|
|
|
46
97
|
```json
|
|
47
|
-
{
|
|
48
|
-
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{id}",
|
|
49
|
-
"method": "GET",
|
|
50
|
-
"query": {
|
|
51
|
-
"format": "metadata",
|
|
52
|
-
"metadataHeaders": "Subject,From,To,Date,Message-ID,References"
|
|
53
|
-
}
|
|
54
|
-
}
|
|
98
|
+
{ "id": "1a0c420faf8b68fe" }
|
|
55
99
|
```
|
|
56
100
|
|
|
57
|
-
|
|
101
|
+
Use `format: "full"` only when the user asks what a message says.
|
|
58
102
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{id}",
|
|
64
|
-
"method": "GET",
|
|
65
|
-
"query": { "format": "full" }
|
|
66
|
-
}
|
|
67
|
-
```
|
|
103
|
+
## Common Operations
|
|
68
104
|
|
|
69
105
|
### Send a message
|
|
70
106
|
|
|
@@ -90,7 +126,7 @@ Use `gmail_draft` with the same envelope as `gmail_send`.
|
|
|
90
126
|
|
|
91
127
|
A reply is `gmail_send` with the original's `threadId`, `inReplyTo`, and `references`. Without these Gmail starts a new thread.
|
|
92
128
|
|
|
93
|
-
1.
|
|
129
|
+
1. `gmail_get` the original; capture its `threadId` and its `Message-ID` and `References` headers.
|
|
94
130
|
2. Send with `to` <- original From (or Reply-To), `subject` <- `Re: ` + original (don't double-prefix), `inReplyTo` <- original Message-ID, `references` <- original References then that Message-ID. Keep angle brackets.
|
|
95
131
|
|
|
96
132
|
```json
|
|
@@ -127,15 +163,15 @@ System labels: `INBOX`, `UNREAD`, `STARRED`, `IMPORTANT`, `SPAM`, `TRASH`. Mark
|
|
|
127
163
|
|
|
128
164
|
## Output Policy
|
|
129
165
|
|
|
130
|
-
- Lists: up to 5 entries with subject, sender, and a human-readable date. Fetch
|
|
131
|
-
- Decode base64 message bodies before presenting; never include raw base64 blobs.
|
|
166
|
+
- Lists: up to 5 entries with subject, sender, and a human-readable date. Fetch `text` only when asked.
|
|
132
167
|
- Modify/trash: state the user-facing effect ("marked 3 messages as read"), not the label diff.
|
|
133
168
|
- Confirm destructive or outgoing actions (send, reply, trash) with the user first.
|
|
134
169
|
|
|
135
170
|
## Common Mistakes
|
|
136
171
|
|
|
137
172
|
- Using `www.googleapis.com` for Gmail, or building send/draft/reply through `http_request` instead of `gmail_send`/`gmail_draft`.
|
|
138
|
-
- Treating `messages.list` results as if they had subjects —
|
|
173
|
+
- Treating `messages.list` results as if they had subjects — call `gmail_get` for each id.
|
|
174
|
+
- Reading a message through `http_request` or code instead of `gmail_get`.
|
|
139
175
|
- Replying without `threadId` + `inReplyTo`/`references` — Gmail starts a new thread.
|
|
140
176
|
- Sending a placeholder (`<RECIPIENT_EMAIL>`, `recipient@example.com`) — the runtime refuses these.
|
|
141
177
|
- Inventing an address. The runtime refuses any recipient absent from the conversation and from earlier tool results; search Gmail or ask the user.
|
|
@@ -66,6 +66,29 @@
|
|
|
66
66
|
"url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts",
|
|
67
67
|
"builder": "gmail-draft"
|
|
68
68
|
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"tool": "gmail_get",
|
|
72
|
+
"description": "Read one Gmail message by id: sender, recipients, subject, date, snippet and, with format \"full\", the message text. Call it for each id that messages.list returned. Never read a message with http_request or code.",
|
|
73
|
+
"parameters": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"properties": {
|
|
76
|
+
"id": { "type": "string", "description": "Message id from messages.list" },
|
|
77
|
+
"format": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"enum": ["metadata", "full"],
|
|
80
|
+
"description": "metadata (default) for lists and summaries; full only when the user needs the message text"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"required": ["id"]
|
|
84
|
+
},
|
|
85
|
+
"request": {
|
|
86
|
+
"method": "GET",
|
|
87
|
+
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{id}",
|
|
88
|
+
"query": { "metadataHeaders": "Subject,From,To,Date,Message-ID,References" },
|
|
89
|
+
"builder": "gmail-get"
|
|
90
|
+
},
|
|
91
|
+
"response": { "decode": "gmail-message" }
|
|
69
92
|
}
|
|
70
93
|
]
|
|
71
94
|
}
|
|
@@ -6,6 +6,57 @@ tools: [http_request, calendar_create_meet_event, calendar_add_meet]
|
|
|
6
6
|
platform: [darwin, linux, win32]
|
|
7
7
|
credentials: [google_calendar_access_token]
|
|
8
8
|
allow_list: [https://www.googleapis.com/calendar/v3/]
|
|
9
|
+
metadata:
|
|
10
|
+
{
|
|
11
|
+
"openclaw": {
|
|
12
|
+
"setup": {
|
|
13
|
+
"routes": [
|
|
14
|
+
{
|
|
15
|
+
"kind": "oauth",
|
|
16
|
+
"label": "Google Calendar",
|
|
17
|
+
"provider": "google",
|
|
18
|
+
"credentialKey": "google_calendar_access_token",
|
|
19
|
+
"description": "List, create, update, and delete Google Calendar events",
|
|
20
|
+
"steps": [
|
|
21
|
+
"Click Connect and approve access in the browser. Approving grants access to your calendars only.",
|
|
22
|
+
"Each Google skill is connected separately, with its own app and its own approval."
|
|
23
|
+
],
|
|
24
|
+
"configSteps": [
|
|
25
|
+
"[Open Google Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=calendar-json.googleapis.com) to enable the Google Calendar API",
|
|
26
|
+
"[Open OAuth clients](https://console.cloud.google.com/auth/clients) to create an OAuth client — choose \"Web application\" as the type",
|
|
27
|
+
"[Open OAuth audience](https://console.cloud.google.com/auth/audience) and add your Google account as a test user"
|
|
28
|
+
],
|
|
29
|
+
"fields": [
|
|
30
|
+
{
|
|
31
|
+
"key": "clientId",
|
|
32
|
+
"label": "Client ID",
|
|
33
|
+
"placeholder": "OAuth client ID from your app"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"key": "clientSecret",
|
|
37
|
+
"label": "Client Secret",
|
|
38
|
+
"secret": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"oauth": {
|
|
42
|
+
"stateKey": "google_calendar_oauth",
|
|
43
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
|
|
44
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
|
45
|
+
"tokenAuth": "secret-in-body",
|
|
46
|
+
"port": 18978,
|
|
47
|
+
"scopes": [
|
|
48
|
+
"https://www.googleapis.com/auth/calendar"
|
|
49
|
+
],
|
|
50
|
+
"extraAuthParams": {
|
|
51
|
+
"access_type": "offline",
|
|
52
|
+
"prompt": "consent"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
9
60
|
---
|
|
10
61
|
|
|
11
62
|
# Google Calendar
|
|
@@ -5,6 +5,58 @@ tools: [http_request, docs_create, docs_append_text]
|
|
|
5
5
|
platform: [darwin, linux, win32]
|
|
6
6
|
credentials: [google_docs_access_token]
|
|
7
7
|
allow_list: [https://docs.googleapis.com/v1/documents, https://www.googleapis.com/drive/v3/files]
|
|
8
|
+
metadata:
|
|
9
|
+
{
|
|
10
|
+
"openclaw": {
|
|
11
|
+
"setup": {
|
|
12
|
+
"routes": [
|
|
13
|
+
{
|
|
14
|
+
"kind": "oauth",
|
|
15
|
+
"label": "Google Docs",
|
|
16
|
+
"provider": "google",
|
|
17
|
+
"credentialKey": "google_docs_access_token",
|
|
18
|
+
"description": "Create, read, and edit Google Docs documents",
|
|
19
|
+
"steps": [
|
|
20
|
+
"Click Connect and approve access in the browser. Approving grants access to your documents and Drive files only.",
|
|
21
|
+
"Each Google skill is connected separately, with its own app and its own approval."
|
|
22
|
+
],
|
|
23
|
+
"configSteps": [
|
|
24
|
+
"[Open Google Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=docs.googleapis.com,drive.googleapis.com) to enable the Google Docs API",
|
|
25
|
+
"[Open OAuth clients](https://console.cloud.google.com/auth/clients) to create an OAuth client — choose \"Web application\" as the type",
|
|
26
|
+
"[Open OAuth audience](https://console.cloud.google.com/auth/audience) and add your Google account as a test user"
|
|
27
|
+
],
|
|
28
|
+
"fields": [
|
|
29
|
+
{
|
|
30
|
+
"key": "clientId",
|
|
31
|
+
"label": "Client ID",
|
|
32
|
+
"placeholder": "OAuth client ID from your app"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"key": "clientSecret",
|
|
36
|
+
"label": "Client Secret",
|
|
37
|
+
"secret": true
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"oauth": {
|
|
41
|
+
"stateKey": "google_docs_oauth",
|
|
42
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
|
|
43
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
|
44
|
+
"tokenAuth": "secret-in-body",
|
|
45
|
+
"port": 18978,
|
|
46
|
+
"scopes": [
|
|
47
|
+
"https://www.googleapis.com/auth/documents",
|
|
48
|
+
"https://www.googleapis.com/auth/drive"
|
|
49
|
+
],
|
|
50
|
+
"extraAuthParams": {
|
|
51
|
+
"access_type": "offline",
|
|
52
|
+
"prompt": "consent"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
8
60
|
---
|
|
9
61
|
|
|
10
62
|
# Google Docs
|
|
@@ -5,6 +5,57 @@ tools: [http_request, drive_create_folder, drive_trash]
|
|
|
5
5
|
platform: [darwin, linux, win32]
|
|
6
6
|
credentials: [google_drive_access_token]
|
|
7
7
|
allow_list: [https://www.googleapis.com/drive/v3/]
|
|
8
|
+
metadata:
|
|
9
|
+
{
|
|
10
|
+
"openclaw": {
|
|
11
|
+
"setup": {
|
|
12
|
+
"routes": [
|
|
13
|
+
{
|
|
14
|
+
"kind": "oauth",
|
|
15
|
+
"label": "Google Drive",
|
|
16
|
+
"provider": "google",
|
|
17
|
+
"credentialKey": "google_drive_access_token",
|
|
18
|
+
"description": "Search, list, and manage Google Drive files and folders",
|
|
19
|
+
"steps": [
|
|
20
|
+
"Click Connect and approve access in the browser. Approving grants access to your Drive files only.",
|
|
21
|
+
"Each Google skill is connected separately, with its own app and its own approval."
|
|
22
|
+
],
|
|
23
|
+
"configSteps": [
|
|
24
|
+
"[Open Google Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=drive.googleapis.com) to enable the Google Drive API",
|
|
25
|
+
"[Open OAuth clients](https://console.cloud.google.com/auth/clients) to create an OAuth client — choose \"Web application\" as the type",
|
|
26
|
+
"[Open OAuth audience](https://console.cloud.google.com/auth/audience) and add your Google account as a test user"
|
|
27
|
+
],
|
|
28
|
+
"fields": [
|
|
29
|
+
{
|
|
30
|
+
"key": "clientId",
|
|
31
|
+
"label": "Client ID",
|
|
32
|
+
"placeholder": "OAuth client ID from your app"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"key": "clientSecret",
|
|
36
|
+
"label": "Client Secret",
|
|
37
|
+
"secret": true
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"oauth": {
|
|
41
|
+
"stateKey": "google_drive_oauth",
|
|
42
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
|
|
43
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
|
44
|
+
"tokenAuth": "secret-in-body",
|
|
45
|
+
"port": 18978,
|
|
46
|
+
"scopes": [
|
|
47
|
+
"https://www.googleapis.com/auth/drive"
|
|
48
|
+
],
|
|
49
|
+
"extraAuthParams": {
|
|
50
|
+
"access_type": "offline",
|
|
51
|
+
"prompt": "consent"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
8
59
|
---
|
|
9
60
|
|
|
10
61
|
# Google Drive
|
|
@@ -6,6 +6,58 @@ platform: [darwin, linux, win32]
|
|
|
6
6
|
credentials: [google_sheets_access_token]
|
|
7
7
|
allow_list:
|
|
8
8
|
[https://sheets.googleapis.com/v4/spreadsheets, https://www.googleapis.com/drive/v3/files]
|
|
9
|
+
metadata:
|
|
10
|
+
{
|
|
11
|
+
"openclaw": {
|
|
12
|
+
"setup": {
|
|
13
|
+
"routes": [
|
|
14
|
+
{
|
|
15
|
+
"kind": "oauth",
|
|
16
|
+
"label": "Google Sheets",
|
|
17
|
+
"provider": "google",
|
|
18
|
+
"credentialKey": "google_sheets_access_token",
|
|
19
|
+
"description": "Create, read, and update Google Sheets spreadsheets",
|
|
20
|
+
"steps": [
|
|
21
|
+
"Click Connect and approve access in the browser. Approving grants access to your spreadsheets and Drive files only.",
|
|
22
|
+
"Each Google skill is connected separately, with its own app and its own approval."
|
|
23
|
+
],
|
|
24
|
+
"configSteps": [
|
|
25
|
+
"[Open Google Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=sheets.googleapis.com,drive.googleapis.com) to enable the Google Sheets API",
|
|
26
|
+
"[Open OAuth clients](https://console.cloud.google.com/auth/clients) to create an OAuth client — choose \"Web application\" as the type",
|
|
27
|
+
"[Open OAuth audience](https://console.cloud.google.com/auth/audience) and add your Google account as a test user"
|
|
28
|
+
],
|
|
29
|
+
"fields": [
|
|
30
|
+
{
|
|
31
|
+
"key": "clientId",
|
|
32
|
+
"label": "Client ID",
|
|
33
|
+
"placeholder": "OAuth client ID from your app"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"key": "clientSecret",
|
|
37
|
+
"label": "Client Secret",
|
|
38
|
+
"secret": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"oauth": {
|
|
42
|
+
"stateKey": "google_sheets_oauth",
|
|
43
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
|
|
44
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
|
45
|
+
"tokenAuth": "secret-in-body",
|
|
46
|
+
"port": 18978,
|
|
47
|
+
"scopes": [
|
|
48
|
+
"https://www.googleapis.com/auth/spreadsheets",
|
|
49
|
+
"https://www.googleapis.com/auth/drive"
|
|
50
|
+
],
|
|
51
|
+
"extraAuthParams": {
|
|
52
|
+
"access_type": "offline",
|
|
53
|
+
"prompt": "consent"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
9
61
|
---
|
|
10
62
|
|
|
11
63
|
# Google Sheets
|
package/skills/notion/SKILL.md
CHANGED
|
@@ -15,6 +15,35 @@ mcp_reads:
|
|
|
15
15
|
notion-get-async-task,
|
|
16
16
|
notion-query-data-sources
|
|
17
17
|
]
|
|
18
|
+
metadata:
|
|
19
|
+
{
|
|
20
|
+
"openclaw": {
|
|
21
|
+
"setup": {
|
|
22
|
+
"routes": [
|
|
23
|
+
{
|
|
24
|
+
"kind": "oauth",
|
|
25
|
+
"label": "Notion",
|
|
26
|
+
"provider": "notion",
|
|
27
|
+
"credentialKey": "notion_mcp_access_token",
|
|
28
|
+
"description": "Pages, databases, and blocks",
|
|
29
|
+
"steps": [
|
|
30
|
+
"Click Connect and approve access in the browser — Workbench uses Notion's hosted MCP OAuth, so no app credentials are needed."
|
|
31
|
+
],
|
|
32
|
+
"oauth": {
|
|
33
|
+
"stateKey": "notion_oauth",
|
|
34
|
+
"authUrl": "https://mcp.notion.com/authorize",
|
|
35
|
+
"tokenUrl": "https://mcp.notion.com/token",
|
|
36
|
+
"tokenAuth": "pkce-only",
|
|
37
|
+
"port": 18982,
|
|
38
|
+
"registrationEndpoint": "https://mcp.notion.com/register",
|
|
39
|
+
"sharedIosSession": true,
|
|
40
|
+
"scopes": []
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
18
47
|
---
|
|
19
48
|
|
|
20
49
|
# Notion
|
package/skills/spotify/SKILL.md
CHANGED
|
@@ -8,15 +8,62 @@ credentials: [spotify_access_token]
|
|
|
8
8
|
allow_list: [https://api.spotify.com/v1/]
|
|
9
9
|
metadata:
|
|
10
10
|
{
|
|
11
|
-
"openclaw":
|
|
12
|
-
{
|
|
13
|
-
"
|
|
11
|
+
"openclaw": {
|
|
12
|
+
"requires": {
|
|
13
|
+
"credentials": [
|
|
14
|
+
"spotify_access_token"
|
|
15
|
+
],
|
|
16
|
+
"credentialChecks": {
|
|
17
|
+
"spotify_access_token": {
|
|
18
|
+
"url": "https://api.spotify.com/v1/me"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"setup": {
|
|
23
|
+
"routes": [
|
|
14
24
|
{
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
25
|
+
"kind": "oauth",
|
|
26
|
+
"label": "Spotify",
|
|
27
|
+
"provider": "spotify",
|
|
28
|
+
"credentialKey": "spotify_access_token",
|
|
29
|
+
"description": "Search, library, and playback control — playback requires Spotify Premium",
|
|
30
|
+
"helpUrl": "https://developer.spotify.com/dashboard",
|
|
31
|
+
"steps": [
|
|
32
|
+
"Search and library browsing work with any Spotify account; controlling playback (play, pause, skip) requires Spotify Premium and an open Spotify app on a device.",
|
|
33
|
+
"Create your own app at https://developer.spotify.com/dashboard (Spotify requires the app owner to hold a Premium subscription).",
|
|
34
|
+
"In the app settings, add these exact Redirect URIs: http://127.0.0.1:18974/callback (desktop) and, for mobile, the Redirect URI shown in this connect form (the scheme varies per build, e.g. qvac://oauth-callback or qvac-dev://oauth-callback).",
|
|
35
|
+
"Paste the Client ID above and click Connect, then approve access in the browser. No Client Secret is needed — Workbench uses PKCE."
|
|
36
|
+
],
|
|
37
|
+
"fields": [
|
|
38
|
+
{
|
|
39
|
+
"key": "clientId",
|
|
40
|
+
"label": "Client ID",
|
|
41
|
+
"placeholder": "From your app at developer.spotify.com"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"oauth": {
|
|
45
|
+
"stateKey": "spotify_oauth",
|
|
46
|
+
"authUrl": "https://accounts.spotify.com/authorize",
|
|
47
|
+
"tokenUrl": "https://accounts.spotify.com/api/token",
|
|
48
|
+
"tokenAuth": "pkce-only",
|
|
49
|
+
"port": 18974,
|
|
50
|
+
"sharedIosSession": true,
|
|
51
|
+
"scopes": [
|
|
52
|
+
"user-read-private",
|
|
53
|
+
"user-read-playback-state",
|
|
54
|
+
"user-modify-playback-state",
|
|
55
|
+
"user-read-currently-playing",
|
|
56
|
+
"playlist-read-private",
|
|
57
|
+
"playlist-read-collaborative",
|
|
58
|
+
"user-library-read",
|
|
59
|
+
"user-top-read",
|
|
60
|
+
"user-read-recently-played"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
18
63
|
}
|
|
64
|
+
]
|
|
19
65
|
}
|
|
66
|
+
}
|
|
20
67
|
}
|
|
21
68
|
---
|
|
22
69
|
|