moltbook-mcp 0.1.2 → 0.1.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 +1 -1
- package/dist/index.js +12 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -177,7 +177,7 @@ The server enforces several safety mechanisms to protect the account:
|
|
|
177
177
|
|
|
178
178
|
- **Rate limiting** -- captures `retry-after` values from API responses (headers and body fields) and blocks write attempts until the cooldown expires. Cooldowns are tracked per-category (post, comment, general write).
|
|
179
179
|
- **Suspension detection** -- parses API responses for suspension or ban signals. When detected, all write operations are blocked until the suspension clears.
|
|
180
|
-
- **Verification challenges** -- when a challenge is detected and auto-solving fails, writes are blocked until the challenge is resolved via `moltbook_verify`.
|
|
180
|
+
- **Verification challenges** -- when a challenge is detected and auto-solving fails, writes are blocked until the challenge is resolved via `moltbook_verify`. Stale verifications with no expiry are automatically cleared after 30 minutes to prevent indefinite write blocks.
|
|
181
181
|
- **Safe mode** -- enabled by default, enforces a minimum 15-second interval between consecutive write operations to avoid triggering platform rate limits.
|
|
182
182
|
|
|
183
183
|
All guard state is persisted to `~/.config/moltbook/mcp_state.json` and survives server restarts.
|
package/dist/index.js
CHANGED
|
@@ -98,6 +98,7 @@ function extractVerification(response) {
|
|
|
98
98
|
if (!hasKeyword && !code) return null;
|
|
99
99
|
if (response.status < 400 && !code) return null;
|
|
100
100
|
const challengeText = challengeObj?.challenge ?? challengeObj?.prompt ?? challengeObj?.question ?? body.challenge_text ?? body.math_challenge ?? body.question ?? null;
|
|
101
|
+
if (!code && typeof challengeText !== "string") return null;
|
|
101
102
|
return {
|
|
102
103
|
verification_code: code ? String(code) : null,
|
|
103
104
|
challenge: typeof challengeText === "string" ? challengeText : null,
|
|
@@ -107,6 +108,7 @@ function extractVerification(response) {
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
// src/state.ts
|
|
111
|
+
var MAX_VERIFICATION_AGE_MS = 30 * 60 * 1e3;
|
|
110
112
|
var CREDENTIALS_PATH = join(homedir(), ".config", "moltbook", "credentials.json");
|
|
111
113
|
var STATE_PATH = join(homedir(), ".config", "moltbook", "mcp_state.json");
|
|
112
114
|
var DEFAULT_STATE = {
|
|
@@ -131,9 +133,14 @@ function saveState(state) {
|
|
|
131
133
|
writeJson(STATE_PATH, state);
|
|
132
134
|
}
|
|
133
135
|
function clearExpiredState(state) {
|
|
134
|
-
if (state.pending_verification
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
if (state.pending_verification) {
|
|
137
|
+
if (state.pending_verification.expires_at) {
|
|
138
|
+
const ts = Date.parse(state.pending_verification.expires_at);
|
|
139
|
+
if (Number.isFinite(ts) && ts < Date.now()) state.pending_verification = null;
|
|
140
|
+
} else if (state.pending_verification.detected_at) {
|
|
141
|
+
const age = Date.now() - Date.parse(state.pending_verification.detected_at);
|
|
142
|
+
if (Number.isFinite(age) && age > MAX_VERIFICATION_AGE_MS) state.pending_verification = null;
|
|
143
|
+
}
|
|
137
144
|
}
|
|
138
145
|
for (const key of ["post_until", "comment_until", "write_until"]) {
|
|
139
146
|
if (!isFutureIso(state.cooldowns[key])) state.cooldowns[key] = null;
|
|
@@ -476,7 +483,8 @@ async function handleVerify(args) {
|
|
|
476
483
|
if (suspension) {
|
|
477
484
|
state.suspension = { active: true, reason: suspension.reason, until: suspension.until ? String(suspension.until) : null, seen_at: nowIso() };
|
|
478
485
|
}
|
|
479
|
-
const
|
|
486
|
+
const rawVerification = extractVerification(response);
|
|
487
|
+
const verification = rawVerification?.verification_code ? rawVerification : null;
|
|
480
488
|
if (verification) {
|
|
481
489
|
const priorFailed = pending?.failed_answers ?? [];
|
|
482
490
|
state.pending_verification = {
|