prepublish-mcp 1.0.1 → 1.0.3
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 +65 -134
- package/package.json +3 -7
- package/server.json +1 -1
package/README.md
CHANGED
|
@@ -1,172 +1,103 @@
|
|
|
1
1
|
# prepublish-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Tooling around the hosted PrePublish MCP server. The server itself is **not** in this package. It lives in the web app and is served at `https://prepublish.ai/mcp`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Install
|
|
17
|
-
|
|
18
|
-
**Claude Code**, one command:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
claude mcp add --transport http prepublish https://mcp.prepublish.ai
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Cursor, VS Code, Windsurf, Claude Code project scope**, or anything that
|
|
25
|
-
reads an `mcpServers` object:
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"mcpServers": {
|
|
30
|
-
"prepublish": {
|
|
31
|
-
"type": "http",
|
|
32
|
-
"url": "https://mcp.prepublish.ai"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
```
|
|
5
|
+
| Path | What it is |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `prepublish-fe/app/mcp/route.ts` | The live endpoint. Streamable HTTP, stateless, anonymous-friendly |
|
|
8
|
+
| `prepublish-fe/lib/mcp/protocol.ts` | JSON-RPC / MCP core |
|
|
9
|
+
| `prepublish-fe/lib/mcp/tools.ts` | The six tools and their descriptions |
|
|
10
|
+
| `prepublish-fe/lib/mcp/limits.ts` | Daily spend cap and per-caller burst limits |
|
|
11
|
+
| `prepublish-fe/app/mcp-server/` | Public documentation page |
|
|
12
|
+
| `prepublish-mcp/src/bridge.ts` | stdio bridge for clients that cannot use a remote server |
|
|
13
|
+
| `prepublish-mcp/test/` | Conformance suite driven by the official MCP SDK client |
|
|
14
|
+
| `prepublish-mcp/server.json` | Registry entry for `ai.prepublish/script-audit` |
|
|
37
15
|
|
|
38
|
-
|
|
39
|
-
and paste `https://mcp.prepublish.ai`.
|
|
16
|
+
One source of truth for tools: the app. The bridge fetches its tool list from the hosted server at startup, so adding a tool needs no release here.
|
|
40
17
|
|
|
41
|
-
|
|
18
|
+
## Why the server is hand-rolled rather than SDK-hosted
|
|
42
19
|
|
|
43
|
-
|
|
44
|
-
[mcp_servers.prepublish]
|
|
45
|
-
url = "https://mcp.prepublish.ai"
|
|
46
|
-
```
|
|
20
|
+
`@modelcontextprotocol/sdk`'s `StreamableHTTPServerTransport` speaks Node's `IncomingMessage`/`ServerResponse`; a Next App Router route handler speaks Web `Request`/`Response`. Shimming one onto the other is more code, and more fragile code, than answering the five JSON-RPC methods a tools-only server needs. Conformance is not taken on trust: `test/conformance.test.ts` drives the endpoint with the official SDK **client** over Streamable HTTP, so the wire format is checked against the reference implementation.
|
|
47
21
|
|
|
48
|
-
|
|
49
|
-
repository. It needs Node 20 or newer and forwards to the same endpoint:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"mcpServers": {
|
|
54
|
-
"prepublish": {
|
|
55
|
-
"command": "npx",
|
|
56
|
-
"args": ["-y", "prepublish-mcp"]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Agents installing this on a user's behalf should read
|
|
63
|
-
[`llms-install.md`](./llms-install.md).
|
|
64
|
-
|
|
65
|
-
### Check it worked
|
|
66
|
-
|
|
67
|
-
Ask for a runtime estimate: *"Use prepublish to convert 1500 words into a
|
|
68
|
-
runtime range."* `script_runtime` is local arithmetic, never rate limited, and
|
|
69
|
-
returns three estimates. If that answers, the connection is good.
|
|
22
|
+
Supported protocol revisions: `2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`. A client asking for a supported revision gets it back; anything else negotiates down to the newest we implement.
|
|
70
23
|
|
|
71
24
|
## Tools
|
|
72
25
|
|
|
73
|
-
| Tool | Cost |
|
|
26
|
+
| Tool | Cost | Purpose |
|
|
74
27
|
| --- | --- | --- |
|
|
75
|
-
| `audit_script` | AI-backed | Full audit of a finished draft
|
|
76
|
-
| `get_audit` | free | Collect an
|
|
77
|
-
| `audit_hook` | AI-backed | Per-sentence attention pull
|
|
78
|
-
| `check_authenticity` | AI-backed | Reused
|
|
79
|
-
| `policy_preflight` | AI-backed |
|
|
80
|
-
| `script_runtime` | free, local | Words
|
|
28
|
+
| `audit_script` | AI-backed | Full audit of a finished draft. Scores, attention-risk map, per-passage rewrites. Polls to completion, then returns the analysis and its id |
|
|
29
|
+
| `get_audit` | free | Collect an audit by `analysis_id` |
|
|
30
|
+
| `audit_hook` | AI-backed | Per-sentence attention pull, curiosity gap, payoff distance, grade, rewrites |
|
|
31
|
+
| `check_authenticity` | AI-backed | Reused / templated / mass-produced content risk with quotes and remediation |
|
|
32
|
+
| `policy_preflight` | AI-backed | YouTube advertiser and monetisation policy exposure, each category citing YouTube's own page. Quoted passages are the paid half |
|
|
33
|
+
| `script_runtime` | free, local | Words ↔ runtime from measured speaking rates (160 / 181 / 201 wpm across 349 videos) |
|
|
81
34
|
|
|
82
|
-
`
|
|
83
|
-
email. The other five do not.
|
|
35
|
+
Every AI-backed response carries the same `notice`: the check is text-only, it maps relative attention risk inside an unrecorded script, and it does not measure or predict published YouTube retention. That sentence is repeated to the user by the model, so it is in the tool descriptions as well as the payloads.
|
|
84
36
|
|
|
85
|
-
|
|
37
|
+
Failures return the next action rather than a stack trace: `402` asks the user for an email, `401`/`403` points at the plan, `429` says the allowance is spent and not to retry, `503` says try later.
|
|
86
38
|
|
|
87
|
-
|
|
88
|
-
too. These checks are text-only. They map relative attention risk inside an
|
|
89
|
-
unrecorded script. They do not measure or predict the retention a published
|
|
90
|
-
video will get, and no output here is a forecast of views, watch time or
|
|
91
|
-
revenue.
|
|
39
|
+
## ChatGPT app (MCP Apps UI)
|
|
92
40
|
|
|
93
|
-
|
|
94
|
-
pass it.
|
|
41
|
+
Listed in the ChatGPT plugin directory since 2026-10-17 at `https://chatgpt.com/plugins/plugin_asdk_app_6aba148dbb6c81918fbc261b405c0c1c`; the package source is `ops/chatgpt-app/plugin-src/`. OpenAI rescans this endpoint daily, and a changed tool descriptor is held until it passes automated checks, so edits to `tools.ts` descriptions are reviewed, not instant.
|
|
95
42
|
|
|
96
|
-
|
|
43
|
+
Two tools render their result as an inline report rather than text: `audit_script` and `get_audit`. The widget is one HTML document, served as `ui://prepublish/audit-v2.html` and under each retired URI in `AUDIT_WIDGET_LEGACY_URIS` (ChatGPT caches the view by URI, and a held descriptor update still names the old one), exported as `AUDIT_WIDGET_URI` from `prepublish-fe/lib/mcp/ui/audit-widget.ts` and served by `resources/read` as `text/html;profile=mcp-app`. The tool descriptor links it with `_meta.ui.resourceUri` and the ChatGPT compatibility alias `_meta["openai/outputTemplate"]`, and marks it widget accessible. A client that does not implement MCP Apps ignores those keys and keeps the text and structured payload it already received.
|
|
97
44
|
|
|
98
|
-
The
|
|
99
|
-
returns a machine-readable server card with the current day's usage.
|
|
45
|
+
The resource declares no CSP domains, so the host applies its restrictive defaults, plus a redirect allowance for `https://prepublish.ai` (the same report in the browser), display modes `inline` and `fullscreen`, and clipboard write for the copy button. `structuredContent` is a projection of the backend audit, not the backend body: the scores, the relative attention-risk map, the improvements, the locked count and the policy pre-flight summary, with internal ids, timestamps and processing metadata dropped. The six tools, their inputs and their text output are unchanged for every other client.
|
|
100
46
|
|
|
101
|
-
|
|
102
|
-
| --- | --- |
|
|
103
|
-
| AI-backed calls per UTC day, across the whole endpoint | 100 |
|
|
104
|
-
| AI-backed calls per caller per 10 minutes | 6 |
|
|
47
|
+
A ChatGPT call carries `_meta["openai/subject"]`, an anonymized per-user id. The endpoint hashes it and uses `mcp:oai:` plus the first 32 hex characters of the digest as the caller key, so the existing per-caller window applies per ChatGPT user and no new environment variable is introduced. A presented bearer token still wins over the subject, and a call without one falls back to the forwarded caller address, then the session id, then a random per-call key. Reports returned to a ChatGPT caller link to `?source=chatgpt-app`, which keeps those arrivals separable from other MCP callers in Umami.
|
|
105
48
|
|
|
106
|
-
|
|
49
|
+
## Limits
|
|
107
50
|
|
|
108
|
-
|
|
109
|
-
tool list.
|
|
51
|
+
Set on the web app, visible at `GET https://prepublish.ai/mcp`:
|
|
110
52
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
53
|
+
| Variable | Default | Meaning |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `MCP_DAILY_CALL_CAP` | `100` | AI-backed calls per UTC day across the whole endpoint. Anonymous callers only |
|
|
56
|
+
| `MCP_CALLER_CALL_LIMIT` | `6` | AI-backed anonymous calls per caller per 10 minutes |
|
|
57
|
+
| `MCP_AUTHED_CALLER_LIMIT` | `30` | AI-backed calls per authenticated caller per 10 minutes |
|
|
114
58
|
|
|
115
|
-
|
|
59
|
+
The counters are in-process. One web container, small numbers, and a restart resets a counter rather than wrongly blocking someone. Move them to Valkey if the app ever runs replicas.
|
|
116
60
|
|
|
117
|
-
|
|
118
|
-
`2025-03-26`, `2024-11-05`. A client asking for a supported revision gets it
|
|
119
|
-
back; anything else negotiates to the newest one implemented, and the
|
|
120
|
-
negotiated revision is reported identically in the response header and in the
|
|
121
|
-
`initialize` result.
|
|
61
|
+
The backend's own limiter keys on client IP, and every MCP call reaches it from the web container's single IP, which is exactly why the per-caller limit exists here. A call carrying an API key is attributable to one account, and the backend already enforces that account's plan quota, so it is exempt from the shared daily cap and bounded by the wider window instead. `used_today` on the server card counts anonymous calls only.
|
|
122
62
|
|
|
123
|
-
|
|
124
|
-
every non-browser client, are always served. A browser origin that is not
|
|
125
|
-
`prepublish.ai` is refused with 403, as the transport specification requires.
|
|
126
|
-
An unsupported `MCP-Protocol-Version` header is a 400.
|
|
63
|
+
## Local development
|
|
127
64
|
|
|
128
|
-
|
|
129
|
-
the
|
|
65
|
+
```bash
|
|
66
|
+
# 1. run the app (serves /mcp)
|
|
67
|
+
cd ../prepublish-fe && npm run build && npm run start -- --port 4910
|
|
130
68
|
|
|
131
|
-
|
|
69
|
+
# 2. conformance suite against it
|
|
70
|
+
cd ../prepublish-mcp && npm install && npm run build && npm test
|
|
71
|
+
```
|
|
132
72
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
73
|
+
`npm test` covers the handshake, tool discovery, schema shape, both directions of `script_runtime`, unknown-tool errors, the server card, batching rejection, notification handling, protocol negotiation in both directions, and the stdio bridge round trip. One AI-backed test is skipped unless `MCP_TEST_BILLABLE=1`, because a real call costs money and writes a row.
|
|
74
|
+
|
|
75
|
+
Verify a deployment:
|
|
136
76
|
|
|
137
77
|
```bash
|
|
138
|
-
npm
|
|
139
|
-
npm run build
|
|
140
|
-
MCP_URL=https://mcp.prepublish.ai npm test
|
|
78
|
+
MCP_URL=https://prepublish.ai/mcp npm run test:conformance
|
|
141
79
|
```
|
|
142
80
|
|
|
143
|
-
The
|
|
144
|
-
Streamable HTTP, so the wire format is checked against the reference
|
|
145
|
-
implementation rather than against our own assumptions. It covers the
|
|
146
|
-
handshake, tool discovery, schema shape, both directions of `script_runtime`,
|
|
147
|
-
unknown-tool errors, the server card, batching rejection, notification
|
|
148
|
-
handling, protocol negotiation in both directions, Origin validation, protocol
|
|
149
|
-
version validation, and the stdio bridge round trip.
|
|
150
|
-
|
|
151
|
-
One AI-backed test is skipped unless `MCP_TEST_BILLABLE=1`, because a real call
|
|
152
|
-
costs money and writes a row.
|
|
81
|
+
## The bridge
|
|
153
82
|
|
|
154
|
-
|
|
155
|
-
adds and hides nothing: a test asserts its tool list equals the hosted one, so
|
|
156
|
-
adding a tool on the server needs no release here.
|
|
83
|
+
For clients that require a local stdio command:
|
|
157
84
|
|
|
158
|
-
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"prepublish": { "command": "npx", "args": ["-y", "prepublish-mcp"] }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
159
92
|
|
|
160
|
-
|
|
161
|
-
remote-only entry under the DNS-verified `ai.prepublish` namespace. See
|
|
162
|
-
[`server.json`](./server.json).
|
|
93
|
+
`PREPUBLISH_MCP_URL` overrides the upstream endpoint; `PREPUBLISH_TOKEN` forwards a bearer token, and a `pp_live_...` API key works there. The bridge adds and hides nothing: a test asserts its tool list equals the hosted one.
|
|
163
94
|
|
|
164
|
-
##
|
|
95
|
+
## Registry
|
|
165
96
|
|
|
166
|
-
-
|
|
167
|
-
- Privacy: <https://prepublish.ai/privacy>
|
|
168
|
-
- Contact: <https://prepublish.ai/contact>
|
|
97
|
+
`server.json` claims the DNS-verified namespace `ai.prepublish/script-audit` with a remote-only entry. Two ways to prove the domain, both documented in `ops/mcp/launch-2026-09-10.md`: a DNS TXT record, or the `MCP_REGISTRY_PUBLIC_KEY` environment variable, which makes `https://prepublish.ai/.well-known/mcp-registry-auth` serve the same value. The route 404s until that variable is set, so an unconfigured deployment cannot advertise a half-finished claim.
|
|
169
98
|
|
|
170
|
-
##
|
|
99
|
+
## Known gaps
|
|
171
100
|
|
|
172
|
-
|
|
101
|
+
- **Protocol revision lag.** The revision in force is `2026-07-28`; this server implements up to `2025-11-25`, which the SDK also treats as latest. Newer clients are required to handle older dialects. Revisit when the SDK ships `2026-07-28`.
|
|
102
|
+
- **API keys shipped; OAuth 2.1 has not.** Create a `pp_live_...` key at `https://prepublish.ai/dashboard` and send it as `Authorization: Bearer`; the call resolves to that account, skips the shared anonymous cap and counts against the account's plan quota. An existing magic-link JWT still works. OAuth remains the missing piece, and verified-directory status is what it costs.
|
|
103
|
+
- **Path, not subdomain.** `mcp.prepublish.ai` needs a DNS record and a Dokploy service; when it exists, only the URL in `server.json`, the docs page and the card change.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prepublish-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "stdio bridge to the hosted PrePublish MCP server: audit a YouTube script before recording from any MCP client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"homepage": "https://prepublish.ai/mcp-server",
|
|
16
16
|
"bugs": {
|
|
17
|
-
"url": "https://
|
|
17
|
+
"url": "https://prepublish.ai/contact"
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"author": "PrePublish (https://prepublish.ai)",
|
|
@@ -41,15 +41,11 @@
|
|
|
41
41
|
"prepublishOnly": "npm run build"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@modelcontextprotocol/sdk": "1.
|
|
44
|
+
"@modelcontextprotocol/sdk": "1.32.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^24.0.0",
|
|
48
48
|
"tsx": "^4.0.0",
|
|
49
49
|
"typescript": "^5.0.0"
|
|
50
|
-
},
|
|
51
|
-
"repository": {
|
|
52
|
-
"type": "git",
|
|
53
|
-
"url": "https://github.com/prepublish/prepublish-mcp"
|
|
54
50
|
}
|
|
55
51
|
}
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "ai.prepublish/script-audit",
|
|
4
4
|
"title": "PrePublish - YouTube script QA",
|
|
5
5
|
"description": "Audit a YouTube script before recording: hook, pacing, drop-off risk, copy-paste rewrites.",
|
|
6
|
-
"version": "1.0
|
|
6
|
+
"version": "1.1.0",
|
|
7
7
|
"websiteUrl": "https://prepublish.ai/mcp-server",
|
|
8
8
|
"remotes": [
|
|
9
9
|
{
|