@scorehub/mcp-server 0.2.6 → 0.2.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/README.md +3 -1
- package/dist/auth.js +4 -1
- package/dist/index.js +31 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,6 +116,8 @@ The `<endpoint>` is derived from the `SCOREHUB_REMOTE_MCP_URL` host and path (fo
|
|
|
116
116
|
|
|
117
117
|
To log out or switch accounts, delete the `~/.scorehub/` directory or just the host-specific subdirectory.
|
|
118
118
|
|
|
119
|
+
The `authorize` tool reuses cached credentials by default. If the cached access token is still valid, or the refresh token can renew it, `authorize` returns without opening the browser. To force a new browser login, call `authorize` with `force: true`.
|
|
120
|
+
|
|
119
121
|
## Available Tools
|
|
120
122
|
|
|
121
123
|
### Local tools
|
|
@@ -124,7 +126,7 @@ These tools run locally on your machine — they do not call the remote endpoint
|
|
|
124
126
|
|
|
125
127
|
| Tool | Description |
|
|
126
128
|
|---|---|
|
|
127
|
-
| `authorize` |
|
|
129
|
+
| `authorize` | Checks ScoreHub OAuth status. Reuses cached credentials by default; pass `force: true` to open the browser for a fresh login. |
|
|
128
130
|
| `status` | Returns connection status: remote URL, authorization state, and count of available tools. |
|
|
129
131
|
|
|
130
132
|
### Remote tools
|
package/dist/auth.js
CHANGED
|
@@ -51,6 +51,9 @@ function clearTokens(host) {
|
|
|
51
51
|
(0, node_fs_1.writeFileSync)(file, JSON.stringify({}), "utf-8");
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
function hasSignedTokenShape(token) {
|
|
55
|
+
return token.split(".").length === 3;
|
|
56
|
+
}
|
|
54
57
|
// ── Token Exchange ───────────────────────────────────────────
|
|
55
58
|
function tokenPostRequest(tokenEndpoint, body) {
|
|
56
59
|
const url = new URL(tokenEndpoint);
|
|
@@ -100,7 +103,7 @@ async function refreshAccessToken(tokenEndpoint, refreshToken, clientId) {
|
|
|
100
103
|
}
|
|
101
104
|
async function getValidAccessToken(host, tokenEndpoint, clientId) {
|
|
102
105
|
const cached = loadTokens(host);
|
|
103
|
-
if (cached && cached.access_token && cached.expires_at > Date.now() + 5 * 60 * 1000) {
|
|
106
|
+
if (cached && cached.access_token && hasSignedTokenShape(cached.access_token) && cached.expires_at > Date.now() + 5 * 60 * 1000) {
|
|
104
107
|
return { access_token: cached.access_token, source: "cache" };
|
|
105
108
|
}
|
|
106
109
|
if (cached?.refresh_token) {
|
package/dist/index.js
CHANGED
|
@@ -108,10 +108,15 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
|
108
108
|
const tools = [
|
|
109
109
|
{
|
|
110
110
|
name: "authorize",
|
|
111
|
-
description: "
|
|
111
|
+
description: "检查 ScoreHub OAuth 授权。已有有效授权时直接返回;仅在传入 force=true 时重新打开浏览器登录。",
|
|
112
112
|
inputSchema: {
|
|
113
113
|
type: "object",
|
|
114
|
-
properties: {
|
|
114
|
+
properties: {
|
|
115
|
+
force: {
|
|
116
|
+
type: "boolean",
|
|
117
|
+
description: "是否强制清除当前端点的本地 token 并重新登录",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
115
120
|
required: [],
|
|
116
121
|
},
|
|
117
122
|
},
|
|
@@ -136,8 +141,18 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
|
136
141
|
const { name, arguments: args = {} } = request.params;
|
|
137
142
|
switch (name) {
|
|
138
143
|
case "authorize": {
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
const force = args.force === true;
|
|
145
|
+
if (!force) {
|
|
146
|
+
const tokenResult = await (0, auth_js_1.getValidAccessToken)(TOKEN_STORE_KEY, TOKEN_ENDPOINT, CLIENT_ID);
|
|
147
|
+
if (tokenResult) {
|
|
148
|
+
return {
|
|
149
|
+
content: [{ type: "text", text: `✅ 已授权(${tokenResult.source === "cache" ? "使用本地缓存" : "已自动刷新"}),可以直接使用 ScoreHub 工具。` }],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
(0, auth_js_1.clearTokens)(TOKEN_STORE_KEY);
|
|
155
|
+
}
|
|
141
156
|
// Port 0 lets the OS assign a random available port,
|
|
142
157
|
// avoiding conflicts when multiple MCP clients run simultaneously
|
|
143
158
|
let actualPort = 0;
|
|
@@ -263,6 +278,18 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
|
263
278
|
}
|
|
264
279
|
try {
|
|
265
280
|
const result = await callRemoteTool(name, args, tokenResult.access_token);
|
|
281
|
+
if (result.includes("ScoreHub OAuth 授权已过期或无效")) {
|
|
282
|
+
(0, auth_js_1.clearTokens)(TOKEN_STORE_KEY);
|
|
283
|
+
const authUrl = generateAuthUrl();
|
|
284
|
+
return {
|
|
285
|
+
content: [
|
|
286
|
+
{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: `⚠️ 授权已失效,已清除本地缓存。请调用 "authorize" 工具重新登录 ScoreHub。\n授权地址: ${authUrl}`,
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
266
293
|
return { content: [{ type: "text", text: result }] };
|
|
267
294
|
}
|
|
268
295
|
catch (e) {
|