@sync.so/mcp-server 0.1.3 → 0.2.0
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/README.md +261 -86
- package/deploy/generation-status/app.html.gz +0 -0
- package/deploy/generation-status/release.json +6 -0
- package/dist/abort-signals.d.ts +6 -0
- package/dist/abort-signals.d.ts.map +1 -0
- package/dist/abort-signals.js +23 -0
- package/dist/account-features.d.ts +7 -0
- package/dist/account-features.d.ts.map +1 -0
- package/dist/account-features.js +48 -0
- package/dist/app-upload-relay.d.ts +13 -0
- package/dist/app-upload-relay.d.ts.map +1 -0
- package/dist/app-upload-relay.js +136 -0
- package/dist/asset-thumbnail.d.ts +3 -0
- package/dist/asset-thumbnail.d.ts.map +1 -0
- package/dist/asset-thumbnail.js +2 -0
- package/dist/auth/async-context.d.ts +5 -0
- package/dist/auth/async-context.d.ts.map +1 -0
- package/dist/auth/async-context.js +14 -0
- package/dist/auth/bearer-auth.d.ts +16 -0
- package/dist/auth/bearer-auth.d.ts.map +1 -0
- package/dist/auth/bearer-auth.js +55 -0
- package/dist/auth/client-credentials.d.ts +13 -0
- package/dist/auth/client-credentials.d.ts.map +1 -0
- package/dist/auth/client-credentials.js +67 -0
- package/dist/auth/device-auth.d.ts.map +1 -1
- package/dist/auth/device-auth.js +3 -2
- package/dist/auth/fixture-cleanup.d.ts +4 -0
- package/dist/auth/fixture-cleanup.d.ts.map +1 -0
- package/dist/auth/fixture-cleanup.js +9 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -0
- package/dist/auth/oauth-diagnostics.d.ts +11 -0
- package/dist/auth/oauth-diagnostics.d.ts.map +1 -0
- package/dist/auth/oauth-diagnostics.js +78 -0
- package/dist/auth/oauth-provider.d.ts +16 -0
- package/dist/auth/oauth-provider.d.ts.map +1 -0
- package/dist/auth/oauth-provider.js +107 -0
- package/dist/auth/resource-metadata.d.ts +2 -0
- package/dist/auth/resource-metadata.d.ts.map +1 -0
- package/dist/auth/resource-metadata.js +3 -0
- package/dist/auth/token-verification.d.ts +11 -0
- package/dist/auth/token-verification.d.ts.map +1 -0
- package/dist/auth/token-verification.js +99 -0
- package/dist/auth/verification-cache.d.ts +8 -0
- package/dist/auth/verification-cache.d.ts.map +1 -0
- package/dist/auth/verification-cache.js +111 -0
- package/dist/chatgpt-analytics.d.ts +22 -0
- package/dist/chatgpt-analytics.d.ts.map +1 -0
- package/dist/chatgpt-analytics.js +172 -0
- package/dist/chatgpt-app.d.ts +15 -0
- package/dist/chatgpt-app.d.ts.map +1 -0
- package/dist/chatgpt-app.js +133 -0
- package/dist/chatgpt-release.d.ts +12 -0
- package/dist/chatgpt-release.d.ts.map +1 -0
- package/dist/chatgpt-release.js +30 -0
- package/dist/cli.js +30 -16
- package/dist/client-profile.d.ts +10 -0
- package/dist/client-profile.d.ts.map +1 -0
- package/dist/client-profile.js +45 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +52 -0
- package/dist/generation-status-html.d.ts +2 -0
- package/dist/generation-status-html.d.ts.map +1 -0
- package/dist/generation-status-html.js +26 -0
- package/dist/generation-status.d.ts +6 -0
- package/dist/generation-status.d.ts.map +1 -0
- package/dist/generation-status.js +37 -0
- package/dist/http-client.d.ts +45 -1
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +171 -34
- package/dist/http-server.d.ts +53 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +753 -0
- package/dist/http-session.d.ts +18 -0
- package/dist/http-session.d.ts.map +1 -0
- package/dist/http-session.js +189 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/oauth-response.d.ts +3 -0
- package/dist/oauth-response.d.ts.map +1 -0
- package/dist/oauth-response.js +30 -0
- package/dist/openapi/index.d.ts +2 -2
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/parser.d.ts +2 -0
- package/dist/openapi/parser.d.ts.map +1 -1
- package/dist/openapi/parser.js +41 -1
- package/dist/openapi/types.d.ts +3 -0
- package/dist/openapi/types.d.ts.map +1 -1
- package/dist/organization-selection.d.ts +61 -0
- package/dist/organization-selection.d.ts.map +1 -0
- package/dist/organization-selection.js +142 -0
- package/dist/rate-limits.d.ts +13 -0
- package/dist/rate-limits.d.ts.map +1 -0
- package/dist/rate-limits.js +67 -0
- package/dist/revision.d.ts +6 -0
- package/dist/revision.d.ts.map +1 -0
- package/dist/revision.js +17 -0
- package/dist/runtime-diagnostics.d.ts +32 -0
- package/dist/runtime-diagnostics.d.ts.map +1 -0
- package/dist/runtime-diagnostics.js +58 -0
- package/dist/server.d.ts +23 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +893 -32
- package/dist/session-registry.d.ts +54 -0
- package/dist/session-registry.d.ts.map +1 -0
- package/dist/session-registry.js +202 -0
- package/dist/session-telemetry.d.ts +13 -0
- package/dist/session-telemetry.d.ts.map +1 -0
- package/dist/session-telemetry.js +87 -0
- package/dist/spend-confirmation.d.ts +21 -0
- package/dist/spend-confirmation.d.ts.map +1 -0
- package/dist/spend-confirmation.js +105 -0
- package/dist/tool-analytics-context.d.ts +11 -0
- package/dist/tool-analytics-context.d.ts.map +1 -0
- package/dist/tool-analytics-context.js +8 -0
- package/dist/tool-names.d.ts +35 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +133 -0
- package/dist/tools/account-context.d.ts +5 -0
- package/dist/tools/account-context.d.ts.map +1 -0
- package/dist/tools/account-context.js +131 -0
- package/dist/tools/account-management.d.ts +4 -0
- package/dist/tools/account-management.d.ts.map +1 -0
- package/dist/tools/account-management.js +111 -0
- package/dist/tools/app-tools.d.ts +31 -0
- package/dist/tools/app-tools.d.ts.map +1 -0
- package/dist/tools/app-tools.js +350 -0
- package/dist/tools/asset-analysis.d.ts +4 -0
- package/dist/tools/asset-analysis.d.ts.map +1 -0
- package/dist/tools/asset-analysis.js +172 -0
- package/dist/tools/asset-creators.d.ts +4 -0
- package/dist/tools/asset-creators.d.ts.map +1 -0
- package/dist/tools/asset-creators.js +38 -0
- package/dist/tools/audio-trim.d.ts +6 -0
- package/dist/tools/audio-trim.d.ts.map +1 -0
- package/dist/tools/audio-trim.js +79 -0
- package/dist/tools/batch-results.d.ts +16 -0
- package/dist/tools/batch-results.d.ts.map +1 -0
- package/dist/tools/batch-results.js +103 -0
- package/dist/tools/batches.d.ts +28 -0
- package/dist/tools/batches.d.ts.map +1 -0
- package/dist/tools/batches.js +293 -0
- package/dist/tools/dialogue.d.ts +6 -0
- package/dist/tools/dialogue.d.ts.map +1 -0
- package/dist/tools/dialogue.js +309 -0
- package/dist/tools/estimate-duration.d.ts +35 -0
- package/dist/tools/estimate-duration.d.ts.map +1 -0
- package/dist/tools/estimate-duration.js +66 -0
- package/dist/tools/feedback.d.ts +14 -0
- package/dist/tools/feedback.d.ts.map +1 -0
- package/dist/tools/feedback.js +72 -0
- package/dist/tools/generated-adapters.d.ts +25 -0
- package/dist/tools/generated-adapters.d.ts.map +1 -0
- package/dist/tools/generated-adapters.js +143 -0
- package/dist/tools/generation-context.d.ts +14 -0
- package/dist/tools/generation-context.d.ts.map +1 -0
- package/dist/tools/generation-context.js +39 -0
- package/dist/tools/generation-continuation.d.ts +4 -0
- package/dist/tools/generation-continuation.d.ts.map +1 -0
- package/dist/tools/generation-continuation.js +124 -0
- package/dist/tools/generation-costs.d.ts +6 -0
- package/dist/tools/generation-costs.d.ts.map +1 -0
- package/dist/tools/generation-costs.js +67 -0
- package/dist/tools/generation-output.d.ts +3 -0
- package/dist/tools/generation-output.d.ts.map +1 -0
- package/dist/tools/generation-output.js +39 -0
- package/dist/tools/generator.d.ts +35 -2
- package/dist/tools/generator.d.ts.map +1 -1
- package/dist/tools/generator.js +127 -9
- package/dist/tools/job-status.d.ts +35 -0
- package/dist/tools/job-status.d.ts.map +1 -0
- package/dist/tools/job-status.js +92 -0
- package/dist/tools/job-wait.d.ts +41 -0
- package/dist/tools/job-wait.d.ts.map +1 -0
- package/dist/tools/job-wait.js +84 -0
- package/dist/tools/jobs.d.ts +3 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +210 -0
- package/dist/tools/media-upload.d.ts +27 -0
- package/dist/tools/media-upload.d.ts.map +1 -0
- package/dist/tools/media-upload.js +247 -0
- package/dist/tools/model-options.d.ts +36 -0
- package/dist/tools/model-options.d.ts.map +1 -0
- package/dist/tools/model-options.js +48 -0
- package/dist/tools/organization-choice.d.ts +9 -0
- package/dist/tools/organization-choice.d.ts.map +1 -0
- package/dist/tools/organization-choice.js +136 -0
- package/dist/tools/organizations.d.ts +56 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +235 -0
- package/dist/tools/output-schemas.d.ts +54 -0
- package/dist/tools/output-schemas.d.ts.map +1 -0
- package/dist/tools/output-schemas.js +58 -0
- package/dist/tools/overrides.d.ts +3 -0
- package/dist/tools/overrides.d.ts.map +1 -1
- package/dist/tools/overrides.js +113 -15
- package/dist/tools/playback-metadata.d.ts +4 -0
- package/dist/tools/playback-metadata.d.ts.map +1 -0
- package/dist/tools/playback-metadata.js +51 -0
- package/dist/tools/project-destination.d.ts +13 -0
- package/dist/tools/project-destination.d.ts.map +1 -0
- package/dist/tools/project-destination.js +45 -0
- package/dist/tools/project-history.d.ts +6 -0
- package/dist/tools/project-history.d.ts.map +1 -0
- package/dist/tools/project-history.js +45 -0
- package/dist/tools/project-intent.d.ts +8 -0
- package/dist/tools/project-intent.d.ts.map +1 -0
- package/dist/tools/project-intent.js +87 -0
- package/dist/tools/running-submissions.d.ts +7 -0
- package/dist/tools/running-submissions.d.ts.map +1 -0
- package/dist/tools/running-submissions.js +91 -0
- package/dist/tools/speech.d.ts +6 -0
- package/dist/tools/speech.d.ts.map +1 -0
- package/dist/tools/speech.js +116 -0
- package/dist/tools/studio-draft.d.ts +7 -0
- package/dist/tools/studio-draft.d.ts.map +1 -0
- package/dist/tools/studio-draft.js +195 -0
- package/dist/tools/studio-view-contract.d.ts +184 -0
- package/dist/tools/studio-view-contract.d.ts.map +1 -0
- package/dist/tools/studio-view-contract.js +67 -0
- package/dist/tools/studio-view.d.ts +6 -0
- package/dist/tools/studio-view.d.ts.map +1 -0
- package/dist/tools/studio-view.js +126 -0
- package/dist/tools/timeline-lipsync.d.ts +316 -0
- package/dist/tools/timeline-lipsync.d.ts.map +1 -0
- package/dist/tools/timeline-lipsync.js +304 -0
- package/dist/tools/translation-preview.d.ts +8 -0
- package/dist/tools/translation-preview.d.ts.map +1 -0
- package/dist/tools/translation-preview.js +146 -0
- package/dist/tools/translation.d.ts +6 -0
- package/dist/tools/translation.d.ts.map +1 -0
- package/dist/tools/translation.js +131 -0
- package/dist/tools/upload-widget.d.ts +13 -0
- package/dist/tools/upload-widget.d.ts.map +1 -0
- package/dist/tools/upload-widget.js +788 -0
- package/dist/toolsets.d.ts +18 -0
- package/dist/toolsets.d.ts.map +1 -0
- package/dist/toolsets.js +157 -0
- package/dist/update-check.d.ts +38 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +150 -0
- package/dist/upload-runtime.d.ts +45 -0
- package/dist/upload-runtime.d.ts.map +1 -0
- package/dist/upload-runtime.js +156 -0
- package/dist/upload-source.d.ts +4 -0
- package/dist/upload-source.d.ts.map +1 -0
- package/dist/upload-source.js +46 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/package.json +79 -33
- package/dist/openapi/parser.test.d.ts +0 -2
- package/dist/openapi/parser.test.d.ts.map +0 -1
- package/dist/openapi/parser.test.js +0 -188
- package/dist/tools/generator.test.d.ts +0 -2
- package/dist/tools/generator.test.d.ts.map +0 -1
- package/dist/tools/generator.test.js +0 -178
package/README.md
CHANGED
|
@@ -1,118 +1,222 @@
|
|
|
1
|
-
#
|
|
1
|
+
# sync. MCP server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Connect your AI agent to [sync.](https://sync.so) to lip-sync videos, translate
|
|
4
|
+
and dub them into other languages, clone voices, and manage assets and projects
|
|
5
|
+
from a chat or a coding session.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
sync. hosts this server at **`https://mcp.sync.so/mcp`**. You sign in with your
|
|
8
|
+
sync. account, so there is nothing to install and no API key to copy. Every merge
|
|
9
|
+
to this repository's `main` deploys there.
|
|
6
10
|
|
|
7
|
-
##
|
|
11
|
+
## Connect your agent
|
|
12
|
+
|
|
13
|
+
### ChatGPT
|
|
14
|
+
|
|
15
|
+
Open [sync. in ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6a398355fbc08191a232e7eeeacb73d5)
|
|
16
|
+
and connect your account. In ChatGPT, sync. Studio also opens inside the chat.
|
|
17
|
+
|
|
18
|
+
### Claude (claude.ai and Claude Desktop)
|
|
19
|
+
|
|
20
|
+
1. Open **Settings → Connectors** and choose **Add custom connector**.
|
|
21
|
+
2. Name it `sync.` and set the URL to `https://mcp.sync.so/mcp`.
|
|
22
|
+
3. Click **Connect** and sign in to sync.
|
|
8
23
|
|
|
9
24
|
### Claude Code
|
|
10
25
|
|
|
11
26
|
```bash
|
|
12
|
-
claude mcp add
|
|
27
|
+
claude mcp add --transport http sync https://mcp.sync.so/mcp
|
|
13
28
|
```
|
|
14
29
|
|
|
15
|
-
|
|
30
|
+
Then run `/mcp` in Claude Code, select `sync` and sign in. Add `--scope user` to
|
|
31
|
+
use it in every project.
|
|
16
32
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"args": ["-y", "@sync.so/mcp-server"],
|
|
23
|
-
"env": {
|
|
24
|
-
"SYNC_API_KEY": "your-api-key"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
33
|
+
### Codex
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
codex mcp add sync --url https://mcp.sync.so/mcp
|
|
37
|
+
codex mcp login sync
|
|
29
38
|
```
|
|
30
39
|
|
|
31
|
-
###
|
|
40
|
+
### Cursor
|
|
32
41
|
|
|
33
|
-
Add to `
|
|
42
|
+
Add to `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` for all projects:
|
|
34
43
|
|
|
35
44
|
```json
|
|
36
45
|
{
|
|
37
46
|
"mcpServers": {
|
|
38
|
-
"sync": {
|
|
39
|
-
"command": "npx",
|
|
40
|
-
"args": ["-y", "@sync.so/mcp-server"],
|
|
41
|
-
"env": {
|
|
42
|
-
"SYNC_API_KEY": "your-api-key"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
47
|
+
"sync": { "url": "https://mcp.sync.so/mcp" }
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
```
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
Cursor asks you to sign in to sync. the first time it connects.
|
|
53
|
+
|
|
54
|
+
### VS Code
|
|
50
55
|
|
|
51
|
-
Add to `.
|
|
56
|
+
Add to `.vscode/mcp.json`:
|
|
52
57
|
|
|
53
58
|
```json
|
|
54
59
|
{
|
|
55
|
-
"
|
|
56
|
-
"sync": {
|
|
57
|
-
"command": "npx",
|
|
58
|
-
"args": ["-y", "@sync.so/mcp-server"],
|
|
59
|
-
"env": {
|
|
60
|
-
"SYNC_API_KEY": "your-api-key"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
60
|
+
"servers": {
|
|
61
|
+
"sync": { "type": "http", "url": "https://mcp.sync.so/mcp" }
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
```
|
|
66
65
|
|
|
67
|
-
###
|
|
66
|
+
### Other clients
|
|
67
|
+
|
|
68
|
+
Any client that supports remote MCP servers over Streamable HTTP with OAuth can
|
|
69
|
+
use `https://mcp.sync.so/mcp`. The client registers itself, and you sign in to
|
|
70
|
+
sync. in the browser.
|
|
71
|
+
|
|
72
|
+
The server is listed in the [official MCP Registry](https://registry.modelcontextprotocol.io)
|
|
73
|
+
as `io.github.synchronicity-labs/mcp-server`, so clients and directories that read
|
|
74
|
+
the registry can find and add it. `server.json` is that listing.
|
|
68
75
|
|
|
69
|
-
|
|
76
|
+
### Local server with an API key
|
|
77
|
+
|
|
78
|
+
For clients without remote MCP support, and for scripts and CI, run the server
|
|
79
|
+
locally over stdio with a sync. [API key](https://sync.so/docs/api-reference/guides/authentication):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
claude mcp add sync -e SYNC_API_KEY=your-api-key -- npx -y @sync.so/mcp-server@latest
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or in a client's JSON config:
|
|
70
86
|
|
|
71
87
|
```json
|
|
72
88
|
{
|
|
73
89
|
"mcpServers": {
|
|
74
90
|
"sync": {
|
|
75
91
|
"command": "npx",
|
|
76
|
-
"args": ["-y", "@sync.so/mcp-server"]
|
|
92
|
+
"args": ["-y", "@sync.so/mcp-server@latest"],
|
|
93
|
+
"env": { "SYNC_API_KEY": "your-api-key" }
|
|
77
94
|
}
|
|
78
95
|
}
|
|
79
96
|
}
|
|
80
97
|
```
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
Without `SYNC_API_KEY`, the server starts a device login on first run: visit the
|
|
100
|
+
URL it prints and enter the code. The token is cached at
|
|
101
|
+
`~/.config/sync/mcp-credentials.json`.
|
|
102
|
+
|
|
103
|
+
npm releases are published separately from the hosted deploy and can lag behind
|
|
104
|
+
it, so prefer the hosted server when your client supports it. `@latest` makes npx
|
|
105
|
+
fetch the newest release when the client restarts the server; without it, npx can
|
|
106
|
+
keep running an old cached copy.
|
|
107
|
+
|
|
108
|
+
#### Update notice
|
|
109
|
+
|
|
110
|
+
At startup a local server asks the npm registry for the latest version, at most once
|
|
111
|
+
a day (the answer is cached in `~/.config/sync/mcp-update-check.json`). The check runs
|
|
112
|
+
in the background with a two-second limit and never delays startup or a tool call; if
|
|
113
|
+
it fails, nothing is shown. When a newer version exists, the server's instructions and
|
|
114
|
+
the first tool result of the session tell the agent to ask you to restart with
|
|
115
|
+
`npx -y @sync.so/mcp-server@latest` or switch to the hosted server.
|
|
116
|
+
|
|
117
|
+
To turn it off, set `SYNC_MCP_UPDATE_CHECK=off` or pass `--no-update-check`. It is
|
|
118
|
+
also skipped when `CI` is set, and the hosted server never checks.
|
|
119
|
+
|
|
120
|
+
## What to ask
|
|
121
|
+
|
|
122
|
+
Paste prompts like these into your agent. Asset IDs come from your sync. library.
|
|
123
|
+
Links can be public media URLs or YouTube, TikTok, Instagram and Facebook videos.
|
|
124
|
+
|
|
125
|
+
| Ask | What the agent does |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| "Lipsync video asset `<video-asset-id>` with audio asset `<audio-asset-id>`." | `lipsync_create` with the saved assets, then waits for the result |
|
|
128
|
+
| "Lipsync https://example.com/talk.mp4 to https://example.com/voiceover.wav." | `lipsync_create` with public URLs |
|
|
129
|
+
| "Translate https://www.youtube.com/watch?v=… to Spanish." | Imports the link with `assets_create`, quotes the cost, and after you confirm runs `dubbing_create` |
|
|
130
|
+
| "Make video asset `<video-asset-id>` say “thanks for watching” in a calm narrator voice." | Picks a voice with `voices_list`, quotes the script, then `lipsync_create` with `script` |
|
|
131
|
+
| "How many credits do I have left?" | `account_get-usage` |
|
|
132
|
+
| "What did my last generation cost?" | Finds it in history and reads `generations_get-costs` |
|
|
133
|
+
|
|
134
|
+
Translation, dubbing, speech previews and voice clones are quoted and confirmed
|
|
135
|
+
with you before they start.
|
|
136
|
+
|
|
137
|
+
### Agent skills
|
|
138
|
+
|
|
139
|
+
Step-by-step workflows for these tools (lipsync, talking photos, dubbing, Edit Dialogue,
|
|
140
|
+
campaigns, batches, troubleshooting and the API) are agent skills in
|
|
141
|
+
[synchronicity-labs/skills](https://github.com/synchronicity-labs/skills). Install them
|
|
142
|
+
in any agent with `npx skills add synchronicity-labs/skills`. The ChatGPT and Codex
|
|
143
|
+
plugin ships them from a pinned commit of that repository; see
|
|
144
|
+
[docs/chatgpt-plugin.md](docs/chatgpt-plugin.md).
|
|
145
|
+
|
|
146
|
+
## Tools
|
|
147
|
+
|
|
148
|
+
The hosted server exposes a curated set of tools to every client:
|
|
149
|
+
|
|
150
|
+
| Area | Tools |
|
|
151
|
+
| --- | --- |
|
|
152
|
+
| Lip sync | `lipsync_create`, `lipsync_create-timeline`¹, `generations_estimate-cost`, `generations_get`, `generations_list`, `generations_get-continuation`, `generations_get-costs`, `models_list` |
|
|
153
|
+
| Translation and dubbing | `dubbing_create`, `dubbing_get-options`, `translation-previews_estimate`, `translation-previews_create`, `translation-previews_get` |
|
|
154
|
+
| Speech and voices | `speech-previews_create`, `speech-previews_get-options`, `speech-previews_get`, `voices_list`, `voices_clone` |
|
|
155
|
+
| Edit Dialogue | `dialogue_get-options`, `dialogue_upload-source`, `dialogue-transcriptions_create`, `dialogue-transcriptions_get`, `dialogue-previews_create`, `dialogue-previews_get`, `dialogue-videos_estimate`, `dialogue-videos_create` |
|
|
156
|
+
| Assets | `assets_create`, `assets_create-upload-url`, `assets_get`, `assets_list`, `assets_count`, `assets_get-download-url`, `assets_update`, `assets_delete`, `assets_get-playback-metadata`, `audio-trims_get`, `audio-trims_create` |
|
|
157
|
+
| Projects | `projects_create`, `projects_get`, `projects_list`, `projects_list-generations`, `projects_rename` |
|
|
158
|
+
| Batches | `batches_create`², `batches_get`², `batches_list`² |
|
|
159
|
+
| Account | `account_get-context`, `account_get-usage`, `organizations_list`, `organizations_select` |
|
|
160
|
+
|
|
161
|
+
¹ Not offered to the ChatGPT app, whose embedded Studio has no timeline.
|
|
162
|
+
|
|
163
|
+
² Not in the ChatGPT app listing yet. A batch runs 20 or more independent generations
|
|
164
|
+
(500 per batch by default), such as one campaign video localized into many languages.
|
|
165
|
+
Where the account's plan doesn't include batch, the API answers 402 with `requiredPlan`
|
|
166
|
+
and `billingUrl`, which the tools pass on.
|
|
167
|
+
|
|
168
|
+
Organizations with the matching feature also get `scenes_detect` (camera cuts in a
|
|
169
|
+
video) and `stems_separate` (vocals and background audio), outside the ChatGPT
|
|
170
|
+
app. They are in the `lipsync` and `assets` toolsets locally.
|
|
171
|
+
|
|
172
|
+
Clients with app support also get the tools behind the embedded Studio app:
|
|
173
|
+
Studio views and drafts, the upload widget and app helpers. Those are clients
|
|
174
|
+
whose MCP handshake name selects the ChatGPT or Codex app profile (`openai-mcp`,
|
|
175
|
+
`openai-mcp (Codex)`; see `src/client-profile.ts`). Other clients don't see these
|
|
176
|
+
tools, and their calls to them are refused.
|
|
177
|
+
|
|
178
|
+
### Local toolsets
|
|
179
|
+
|
|
180
|
+
The local stdio server can also offer a tool for every other public API operation in
|
|
181
|
+
the [OpenAPI spec](https://api.sync.so/api-json), 65+ in all. By default it lists the
|
|
182
|
+
hosted set above, without its admin tools (`assets_delete` and `voices_clone`),
|
|
183
|
+
plus `jobs_get` and `jobs_wait` and the `transcriptions_*` tools, whose speaker face
|
|
184
|
+
tracks feed `lipsync_create-timeline` clips.
|
|
185
|
+
|
|
186
|
+
To list more, set `SYNC_MCP_TOOLSETS` or pass `--toolsets` with a comma-separated list:
|
|
187
|
+
|
|
188
|
+
| Toolset | Adds |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| `default` | The default above, so `default,admin` adds the admin tools to it |
|
|
191
|
+
| `lipsync` | Lip sync, timeline, Edit Dialogue, audio trim and batch tools, plus raw `generate_*`, `generations_*` and `dialogue-edits_*` |
|
|
192
|
+
| `dubbing` | Translation and dubbing tools, and the batch tools |
|
|
193
|
+
| `assets` | `assets_*` (except deletes) and the upload tools |
|
|
194
|
+
| `projects` | `projects_*` (except deletes) and `projects_rename` |
|
|
195
|
+
| `transcription` | `transcriptions_*` |
|
|
196
|
+
| `voices` | `voices_*` (except cloning and deletes), speech previews and `tts_*` |
|
|
197
|
+
| `admin` | Every delete (`assets_delete`, `projects_delete`, `generations_delete`, `voices_delete`) and `voices_clone` |
|
|
198
|
+
| `all` | Every tool, as before this option existed |
|
|
199
|
+
|
|
200
|
+
Job, account and generation reads (`jobs_get`, `jobs_wait`, `generations_get`,
|
|
201
|
+
`account_get-context`, `organizations_list`, `organizations_select` and similar) come with
|
|
202
|
+
every selection. Naming toolsets replaces
|
|
203
|
+
the default rather than adding to it. To get every tool back:
|
|
91
204
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| Tool | Description |
|
|
97
|
-
|------|-------------|
|
|
98
|
-
| `generate_create-generation` | Create a lipsync video from video + audio inputs |
|
|
99
|
-
| `generate_get-generation` | Get generation status — poll until COMPLETED |
|
|
100
|
-
| `models_get-public` | List available lipsync models |
|
|
101
|
-
| `assets_get-all` | List all assets in your organization |
|
|
102
|
-
| `assets_get` | Get a specific asset by ID |
|
|
103
|
-
| `generations_estimate` | Estimate generation cost before creating |
|
|
104
|
-
|
|
105
|
-
Plus every other public endpoint in the [Sync API](https://sync.so/docs/api-reference).
|
|
205
|
+
```bash
|
|
206
|
+
claude mcp add sync -e SYNC_API_KEY=your-api-key -e SYNC_MCP_TOOLSETS=all -- npx -y @sync.so/mcp-server@latest
|
|
207
|
+
```
|
|
106
208
|
|
|
107
|
-
|
|
209
|
+
Unless it lists everything, the server's instructions tell the agent which toolsets are
|
|
210
|
+
listed and how to get the rest, so it can ask you to restart the server with a wider
|
|
211
|
+
set. The hosted server ignores this setting.
|
|
108
212
|
|
|
109
|
-
|
|
213
|
+
[Tool workflows](docs/tool-workflows.md) describes how the multi-step and paid
|
|
214
|
+
tools behave.
|
|
110
215
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
- *"How much would it cost to generate a 30-second video?"*
|
|
216
|
+
Tool names follow one `<noun>_<verb>` scheme (`lipsync_create`, `generations_get`).
|
|
217
|
+
The names used before it (`create-lipsync`, `generate_get-generation`) still work for a
|
|
218
|
+
deprecation period: calls through them run the same tool and add a one-line notice
|
|
219
|
+
naming the new one. [Tool names](docs/tool-names.md) has the full old → new table.
|
|
116
220
|
|
|
117
221
|
## CLI Options
|
|
118
222
|
|
|
@@ -124,25 +228,51 @@ Options:
|
|
|
124
228
|
--base-url <url> API base URL (default: https://api.sync.so)
|
|
125
229
|
--transport <type> stdio (default) or http
|
|
126
230
|
--port <port> HTTP port (default: 3002, only with --transport http)
|
|
231
|
+
--no-spend-confirmation
|
|
232
|
+
Unattended automation: drop the cost-quote and confirm-before-paying
|
|
233
|
+
instructions (or set SYNC_MCP_SPEND_CONFIRMATION=off)
|
|
234
|
+
--no-update-check Skip the daily npm check for a newer version (or set
|
|
235
|
+
SYNC_MCP_UPDATE_CHECK=off; skipped when CI is set)
|
|
236
|
+
--toolsets <list> stdio only: comma-separated tools to list (or set SYNC_MCP_TOOLSETS):
|
|
237
|
+
default, lipsync, dubbing, assets, projects, transcription,
|
|
238
|
+
voices, admin or all (default: the hosted set without admin)
|
|
127
239
|
-h, --help Show this help message
|
|
128
240
|
```
|
|
129
241
|
|
|
130
|
-
###
|
|
242
|
+
### Unattended automation
|
|
243
|
+
|
|
244
|
+
By default the tools tell the agent to quote a paid action and wait for the user's
|
|
245
|
+
approval. When the server runs a pipeline or a scheduled agent whose operator has already
|
|
246
|
+
approved spending, start it with `--no-spend-confirmation` (or
|
|
247
|
+
`SYNC_MCP_SPEND_CONFIRMATION=off`). The agent then creates jobs without quoting or asking,
|
|
248
|
+
and estimate tools stay available. Agents cannot change this setting.
|
|
131
249
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
250
|
+
Job tools take `wait: true` to wait on the server (up to about 50 seconds per call, with
|
|
251
|
+
progress notifications when the client sends a `progressToken`): `generations_get`,
|
|
252
|
+
`translation-previews_get`, `transcriptions_get` and social imports
|
|
253
|
+
through `assets_create`. On the local server, `jobs_wait` and `jobs_get` do the same for
|
|
254
|
+
every kind of job (generation, transcription, speaker analysis, translation preview,
|
|
255
|
+
import) with one input, `{kind, id, projectId?}`, and one result shape and status set;
|
|
256
|
+
see [Jobs](docs/jobs.md).
|
|
257
|
+
|
|
258
|
+
When the API offers it, `feedback_send` lets agents report confusing errors, wrong results
|
|
259
|
+
and missing capabilities to the Sync team.
|
|
260
|
+
|
|
261
|
+
Environment variables and the HTTP server's session, memory, upload and
|
|
262
|
+
diagnostics limits are in [HTTP server configuration](docs/http-server.md).
|
|
136
263
|
|
|
137
264
|
## How It Works
|
|
138
265
|
|
|
139
|
-
1.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
266
|
+
1. At startup, the server fetches the public OpenAPI spec from `{baseUrl}/api-json`
|
|
267
|
+
and turns each operation into an MCP tool with a Zod input schema.
|
|
268
|
+
2. Hand-written tools add multi-step workflows on the same API, such as translate
|
|
269
|
+
and dub, Edit Dialogue, speech previews and cost lookups.
|
|
270
|
+
3. Each tool call is an authenticated request to the sync. API, with your OAuth
|
|
271
|
+
token (hosted) or API key (local).
|
|
144
272
|
|
|
145
|
-
|
|
273
|
+
Over stdio, a new public API operation becomes a tool on the next restart. The
|
|
274
|
+
hosted server only exposes tools on its allowlist, so a new hosted tool ships with
|
|
275
|
+
a release of this repository.
|
|
146
276
|
|
|
147
277
|
## Programmatic Usage
|
|
148
278
|
|
|
@@ -157,25 +287,70 @@ const server = await createSyncMcpServer(config);
|
|
|
157
287
|
|
|
158
288
|
## Development
|
|
159
289
|
|
|
290
|
+
HTTPS source tests use the local `openssl` command to create a one-day, self-signed
|
|
291
|
+
test identity. Temporary certificate and key files are removed before the tests run.
|
|
292
|
+
|
|
160
293
|
```bash
|
|
161
294
|
# Install dependencies
|
|
162
|
-
|
|
295
|
+
pnpm install
|
|
163
296
|
|
|
164
297
|
# Build
|
|
165
|
-
|
|
298
|
+
pnpm run build
|
|
166
299
|
|
|
167
300
|
# Run tests
|
|
168
|
-
|
|
301
|
+
pnpm test
|
|
169
302
|
|
|
170
303
|
# Lint
|
|
171
|
-
|
|
304
|
+
pnpm run lint
|
|
172
305
|
|
|
173
306
|
# Type check
|
|
174
|
-
|
|
307
|
+
pnpm run typecheck
|
|
308
|
+
|
|
309
|
+
# Script tests (monitor, smoke check, pre-commit size check)
|
|
310
|
+
pnpm run test:scripts
|
|
175
311
|
```
|
|
176
312
|
|
|
313
|
+
Development needs Node 26 or newer (`.nvmrc`); `devEngines` in `package.json`
|
|
314
|
+
enforces it on install. `pnpm install` installs a pre-commit hook. It runs Oxlint and Oxfmt on staged
|
|
315
|
+
files, and blocks a staged source file that grows past 5,000 tokens (20,000
|
|
316
|
+
bytes). Files already over that size are exempt until someone splits them.
|
|
317
|
+
|
|
318
|
+
### Local HTTP Transport Testing
|
|
319
|
+
|
|
320
|
+
To test the HTTP transport (OAuth flow) locally:
|
|
321
|
+
|
|
322
|
+
1. Copy `.env.example` to `.env` and fill in the values
|
|
323
|
+
2. Start a tunnel to expose localhost:
|
|
324
|
+
```bash
|
|
325
|
+
ngrok http 3002
|
|
326
|
+
```
|
|
327
|
+
3. Update `MCP_ISSUER_URL` in `.env` with the ngrok URL
|
|
328
|
+
4. Start the server:
|
|
329
|
+
```bash
|
|
330
|
+
source .env
|
|
331
|
+
node dist/cli.js --transport http --base-url $SYNC_BASE_URL --port 3002
|
|
332
|
+
```
|
|
333
|
+
5. Verify it works:
|
|
334
|
+
```bash
|
|
335
|
+
curl https://<ngrok-url>/health
|
|
336
|
+
curl https://<ngrok-url>/.well-known/oauth-authorization-server
|
|
337
|
+
```
|
|
338
|
+
When an isolated Studio login requires the same-origin web proxy, set
|
|
339
|
+
`SYNC_OAUTH_AUTHORIZATION_URL` to its `/api-proxy/v2/oauth/authorize` URL, while
|
|
340
|
+
keeping `SYNC_BASE_URL` on the direct isolated API listener. Only browser
|
|
341
|
+
navigation uses the web proxy. Registration, code exchange, refresh, revocation,
|
|
342
|
+
userinfo and tool calls use the direct API and retain existing deadlines,
|
|
343
|
+
PKCE and confidential-client checks. The optional URL must use HTTP(S), with no
|
|
344
|
+
credentials, query or fragment. Existing deployments need no new setting.
|
|
345
|
+
|
|
346
|
+
6. Add `https://<ngrok-url>/mcp` as a custom connector in [Claude Web](https://claude.ai)
|
|
347
|
+
|
|
177
348
|
## Learn More
|
|
178
349
|
|
|
350
|
+
- [Tool workflows](docs/tool-workflows.md) — How multi-step and paid tools behave
|
|
351
|
+
- [HTTP server configuration](docs/http-server.md) — Environment variables and runtime limits
|
|
352
|
+
- [Maintainer notes](docs/maintainers.md) — Hosted compatibility, cancellation, OAuth proxy, uploads and monitoring
|
|
353
|
+
- [Claude directory readiness](docs/claude-directory-readiness.md) — Review checklist and remaining submission work
|
|
179
354
|
- [Sync Documentation](https://sync.so/docs) — Full API reference and guides
|
|
180
355
|
- [Sync API Reference](https://sync.so/docs/api-reference) — Endpoint documentation
|
|
181
356
|
- [MCP Protocol](https://modelcontextprotocol.io) — Learn about the Model Context Protocol
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort-signals.d.ts","sourceRoot":"","sources":["../src/abort-signals.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG;IACtD,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAoBA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Compose cancellation on every supported Node runtime; dispose listeners after work. */
|
|
2
|
+
export function combineSignals(signals) {
|
|
3
|
+
const controller = new AbortController();
|
|
4
|
+
const listeners = new Map();
|
|
5
|
+
const dispose = () => {
|
|
6
|
+
for (const [signal, listener] of listeners)
|
|
7
|
+
signal.removeEventListener('abort', listener);
|
|
8
|
+
listeners.clear();
|
|
9
|
+
};
|
|
10
|
+
for (const signal of signals) {
|
|
11
|
+
const abort = () => {
|
|
12
|
+
controller.abort(signal.reason);
|
|
13
|
+
dispose();
|
|
14
|
+
};
|
|
15
|
+
if (signal.aborted) {
|
|
16
|
+
abort();
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
listeners.set(signal, abort);
|
|
20
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
21
|
+
}
|
|
22
|
+
return { signal: controller.signal, dispose };
|
|
23
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Tool } from '@modelcontextprotocol/server';
|
|
2
|
+
import type { HttpClient } from './http-client.js';
|
|
3
|
+
import { type OrganizationSession } from './organization-selection.js';
|
|
4
|
+
export declare function isFeatureGatedTool(name: string): boolean;
|
|
5
|
+
/** The descriptors this organization may see; reads features only when a gated tool is listed. */
|
|
6
|
+
export declare function listedForAccount(descriptors: Tool[], session: OrganizationSession, http: HttpClient): Promise<Tool[]>;
|
|
7
|
+
//# sourceMappingURL=account-features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-features.d.ts","sourceRoot":"","sources":["../src/account-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,6BAA6B,CAAC;AAcjG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAmCD,kGAAkG;AAClG,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,IAAI,EAAE,EACnB,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,EAAE,CAAC,CAMjB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { runInOrganizationSession } from './organization-selection.js';
|
|
2
|
+
import { parseAccountOverview } from './tools/organizations.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tools listed only when the active organization's GET /v2/account `features` names the
|
|
5
|
+
* feature: their API routes are behind server-side flags, so other accounts would only get a
|
|
6
|
+
* 404. A tool call is not refused here; the API stays the authority, and the tool reports
|
|
7
|
+
* its 404.
|
|
8
|
+
*/
|
|
9
|
+
const TOOL_FEATURES = {
|
|
10
|
+
scenes_detect: 'scene_detection',
|
|
11
|
+
stems_separate: 'stem_separation',
|
|
12
|
+
};
|
|
13
|
+
export function isFeatureGatedTool(name) {
|
|
14
|
+
return Object.hasOwn(TOOL_FEATURES, name);
|
|
15
|
+
}
|
|
16
|
+
// tools/list waits on this read, so it must not take the API's full request budget.
|
|
17
|
+
const FEATURES_TIMEOUT_MS = 5_000;
|
|
18
|
+
/**
|
|
19
|
+
* The active organization's features, kept on the MCP session's OrganizationSession: the
|
|
20
|
+
* stdio process, or one hosted session. organizations_select and account_get-context write
|
|
21
|
+
* the same field when they read the account, so an organization switch changes what is
|
|
22
|
+
* listed. An API without the field means none. A failed read lists no gated tools and keeps
|
|
23
|
+
* nothing, so a later list reads again.
|
|
24
|
+
*/
|
|
25
|
+
async function sessionFeatures(session, http) {
|
|
26
|
+
const kept = session.activeFeatures();
|
|
27
|
+
if (kept)
|
|
28
|
+
return new Set(kept);
|
|
29
|
+
const stamp = session.featureStamp();
|
|
30
|
+
try {
|
|
31
|
+
// In the session, so the read names its selected organization like any other call.
|
|
32
|
+
const overview = parseAccountOverview(await runInOrganizationSession(session, () => http.request('get', '/v2/account', { signal: AbortSignal.timeout(FEATURES_TIMEOUT_MS) })));
|
|
33
|
+
const features = overview.features ?? [];
|
|
34
|
+
// Not kept if the session switched meanwhile or the answer is for another organization.
|
|
35
|
+
session.recordFeatures(features, stamp, overview.organization?.id);
|
|
36
|
+
return new Set(features);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return new Set();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** The descriptors this organization may see; reads features only when a gated tool is listed. */
|
|
43
|
+
export async function listedForAccount(descriptors, session, http) {
|
|
44
|
+
if (!descriptors.some((tool) => isFeatureGatedTool(tool.name)))
|
|
45
|
+
return descriptors;
|
|
46
|
+
const enabled = await sessionFeatures(session, http);
|
|
47
|
+
return descriptors.filter((tool) => !isFeatureGatedTool(tool.name) || enabled.has(TOOL_FEATURES[tool.name]));
|
|
48
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import cors from 'cors';
|
|
2
|
+
import type { RequestHandler } from 'express';
|
|
3
|
+
import type { McpToolDefinition } from './tools/generator.js';
|
|
4
|
+
/** Browser origins are configured separately from storage destinations. Tickets remain required. */
|
|
5
|
+
export declare function createAppUploadCors(origins: string[]): (req: cors.CorsRequest, res: {
|
|
6
|
+
statusCode?: number | undefined;
|
|
7
|
+
setHeader(key: string, value: string): any;
|
|
8
|
+
end(): any;
|
|
9
|
+
}, next: (err?: any) => any) => void;
|
|
10
|
+
/** A ticket grants one bounded PUT to one server-issued storage URL, never arbitrary proxying. */
|
|
11
|
+
export declare function relayUploadTool(tool: McpToolDefinition, origin: string, storageOrigin: string): McpToolDefinition;
|
|
12
|
+
export declare const appUploadHandler: RequestHandler;
|
|
13
|
+
//# sourceMappingURL=app-upload-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-upload-relay.d.ts","sourceRoot":"","sources":["../src/app-upload-relay.ts"],"names":[],"mappings":"AAIA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE;;;;qCAOpD;AAcD,kGAAkG;AAClG,wBAAgB,eAAe,CAC7B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,iBAAiB,CAoCnB;AAED,eAAO,MAAM,gBAAgB,EAAE,cA8E9B,CAAC"}
|