kloudy-mcp 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/README.md +3 -3
- package/dist/kloudy-mcp/src/http-auth.d.ts +2 -0
- package/dist/kloudy-mcp/src/http-auth.js +26 -0
- package/dist/kloudy-mcp/src/http-auth.js.map +1 -1
- package/dist/kloudy-mcp/src/http-config.d.ts +1 -0
- package/dist/kloudy-mcp/src/http-config.js +4 -0
- package/dist/kloudy-mcp/src/http-config.js.map +1 -1
- package/dist/kloudy-mcp/src/http-server.d.ts +1 -0
- package/dist/kloudy-mcp/src/http-server.js +39 -11
- package/dist/kloudy-mcp/src/http-server.js.map +1 -1
- package/dist/kloudy-mcp/src/version.d.ts +1 -1
- package/dist/kloudy-mcp/src/version.js +1 -1
- package/dist/shared/src/api-a/client.js +3 -0
- package/dist/shared/src/api-a/client.js.map +1 -1
- package/dist/shared/src/config.d.ts +1 -0
- package/dist/shared/src/config.js +10 -0
- package/dist/shared/src/config.js.map +1 -1
- package/docs/http-mcp.md +10 -4
- package/docs/local-mcp.md +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ npx -y kloudy-mcp logout
|
|
|
36
36
|
codex mcp add kloudy -- npx -y kloudy-mcp serve
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
`serve`、`login` 和 `logout`
|
|
39
|
+
`serve`、`login` 和 `logout` 面向本地单用户客户端。Kloudy 自有 Agent 的生产主路径是常驻 `serve-http` 的内部 `/internal/mcp`:API-G 使用独立服务身份,并为每个协议请求携带已验证的 User、Device 和 Character 身份。`serve-request` 保留为每 Run 独立进程的诊断和显式回滚路径。三种入口调用同一个工具注册和 Schema,因此新增能力只需在 MCP 契约中实现一次,是否向模型开放仍由各 Agent 的工具政策决定。
|
|
40
40
|
|
|
41
41
|
远程服务使用:
|
|
42
42
|
|
|
@@ -44,8 +44,8 @@ codex mcp add kloudy -- npx -y kloudy-mcp serve
|
|
|
44
44
|
kloudy-mcp serve-http
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
`serve-http`
|
|
47
|
+
`serve-http` 提供公开 OAuth `/mcp`、受信服务身份 `/internal/mcp`、路径型 OAuth Protected Resource Metadata 和本机健康接口。它不读取本地登录文件;两个 MCP 入口都把 User、Device 和 Character 身份限制在当前请求内存中,且使用彼此独立的认证方式。完整环境变量、协议边界和部署前置条件见 [Streamable HTTP 说明](docs/http-mcp.md)。
|
|
48
48
|
|
|
49
49
|
默认连接 `https://shape.kloudy.cn/api-x` 和 `https://shape.kloudy.cn/api-a`。开发或测试时可通过 `KLOUDY_API_X_BASE_URL`、`KLOUDY_API_A_BASE_URL` 覆盖服务地址,通过 `KLOUDY_WEB_BASE_URL` 覆盖网页登录地址。
|
|
50
50
|
|
|
51
|
-
`knowledge_search` 需要登录,返回索引版本、Wiki 证据片段和来源 URL;最终知识回答由
|
|
51
|
+
`knowledge_search` 需要登录,返回索引版本、Wiki 证据片段和来源 URL;最终知识回答由 MCP 客户端根据证据生成,证据不足时应明确拒答。调用 API-A 时可通过 `KLOUDY_MCP_API_A_SERVICE_TOKEN` 附加独立服务身份;它不能代替逐请求用户、Device 和 Character 鉴权,也不会进入工具参数或结果。账号私有读取和写入工具也需要登录。Community 评论会立即公开发布,但只能删除当前 Agent Character 自己发布的评论;Blog 工具只能操作草稿;Archive 和 Wiki 投稿需要管理员审核后才会发布。
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders } from 'node:http';
|
|
1
2
|
import type { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
|
|
2
3
|
import type { OAuthTokenVerifier } from '@modelcontextprotocol/sdk/server/auth/provider.js';
|
|
3
4
|
import { RequestStateStore } from '../../shared/src/state-store.js';
|
|
@@ -9,3 +10,4 @@ export declare class HttpAuthContextVerifier implements OAuthTokenVerifier {
|
|
|
9
10
|
verifyAccessToken(token: string): Promise<AuthInfo>;
|
|
10
11
|
}
|
|
11
12
|
export declare function requestStateFromAuthInfo(authInfo: AuthInfo | undefined): RequestStateStore;
|
|
13
|
+
export declare function requestStateFromInternalHeaders(headers: IncomingHttpHeaders, expectedServiceToken: string | null): RequestStateStore;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InvalidTokenError, ServerError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
|
|
2
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { RequestStateStore } from '../../shared/src/state-store.js';
|
|
4
5
|
const bearerTokenSchema = z.string().min(1).max(8192).regex(/^[\x21-\x7e]+$/);
|
|
@@ -90,6 +91,31 @@ export function requestStateFromAuthInfo(authInfo) {
|
|
|
90
91
|
throw invalidToken();
|
|
91
92
|
}
|
|
92
93
|
}
|
|
94
|
+
export function requestStateFromInternalHeaders(headers, expectedServiceToken) {
|
|
95
|
+
const authorization = singleHeader(headers.authorization);
|
|
96
|
+
const prefix = 'Bearer ';
|
|
97
|
+
const presented = authorization?.startsWith(prefix) ? authorization.slice(prefix.length) : '';
|
|
98
|
+
if (!expectedServiceToken || !safeEqual(presented, expectedServiceToken))
|
|
99
|
+
throw invalidToken();
|
|
100
|
+
try {
|
|
101
|
+
return new RequestStateStore({
|
|
102
|
+
sessionToken: singleHeader(headers['k-session-token']) ?? '',
|
|
103
|
+
deviceId: singleHeader(headers['k-device-id']) ?? '',
|
|
104
|
+
characterId: singleHeader(headers['k-character-id']) ?? '',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
throw invalidToken();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function singleHeader(value) {
|
|
112
|
+
return typeof value === 'string' ? value : undefined;
|
|
113
|
+
}
|
|
114
|
+
function safeEqual(left, right) {
|
|
115
|
+
const leftBuffer = Buffer.from(left);
|
|
116
|
+
const rightBuffer = Buffer.from(right);
|
|
117
|
+
return leftBuffer.length === rightBuffer.length && timingSafeEqual(leftBuffer, rightBuffer);
|
|
118
|
+
}
|
|
93
119
|
function invalidToken() {
|
|
94
120
|
return new InvalidTokenError('Access token is invalid or expired');
|
|
95
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-auth.js","sourceRoot":"","sources":["../../../src/http-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"http-auth.js","sourceRoot":"","sources":["../../../src/http-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,9 @@ export function loadHttpServerConfig(env = process.env) {
|
|
|
25
25
|
throw new Error('KLOUDY_MCP_AUTH_CONTEXT_URL must not contain query or hash');
|
|
26
26
|
}
|
|
27
27
|
const authContextServiceToken = parseSecret(env.KLOUDY_MCP_AUTH_CONTEXT_SERVICE_TOKEN, 'KLOUDY_MCP_AUTH_CONTEXT_SERVICE_TOKEN');
|
|
28
|
+
const internalServiceToken = env.KLOUDY_MCP_INTERNAL_SERVICE_TOKEN
|
|
29
|
+
? parseSecret(env.KLOUDY_MCP_INTERNAL_SERVICE_TOKEN, 'KLOUDY_MCP_INTERNAL_SERVICE_TOKEN')
|
|
30
|
+
: null;
|
|
28
31
|
const authTimeoutMs = parseTimeout(env.KLOUDY_MCP_AUTH_TIMEOUT_MS);
|
|
29
32
|
const requiredScopes = parseScopes(env.KLOUDY_MCP_REQUIRED_SCOPES);
|
|
30
33
|
const allowedHosts = unique([
|
|
@@ -40,6 +43,7 @@ export function loadHttpServerConfig(env = process.env) {
|
|
|
40
43
|
authorizationServerUrl,
|
|
41
44
|
authContextUrl,
|
|
42
45
|
authContextServiceToken,
|
|
46
|
+
internalServiceToken,
|
|
43
47
|
authTimeoutMs,
|
|
44
48
|
requiredScopes,
|
|
45
49
|
allowedHosts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-config.js","sourceRoot":"","sources":["../../../src/http-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,iBAAiB,GAAG,WAAW,CAAC;AACtC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,kBAAkB,GAAG,UAAU,iBAAiB,IAAI,iBAAiB,MAAM,CAAC;AAClF,MAAM,cAAc,GAAG,CAAC,WAAW,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"http-config.js","sourceRoot":"","sources":["../../../src/http-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,6 @@ export interface HttpServerDependencies {
|
|
|
5
5
|
verifier?: OAuthTokenVerifier;
|
|
6
6
|
}
|
|
7
7
|
export declare function createHttpApp(config: HttpServerConfig, dependencies?: HttpServerDependencies): Express;
|
|
8
|
+
export declare function serializeAuthorizationServerIssuer(url: URL): string;
|
|
8
9
|
export declare function startHttpServer(config: HttpServerConfig): Promise<NodeHttpServer>;
|
|
9
10
|
export declare function installHttpServerShutdown(server: NodeHttpServer, timeoutMs?: number): void;
|
|
@@ -3,8 +3,9 @@ import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middlew
|
|
|
3
3
|
import { getOAuthProtectedResourceMetadataUrl } from '@modelcontextprotocol/sdk/server/auth/router.js';
|
|
4
4
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
5
|
import { createClients } from './clients.js';
|
|
6
|
-
import { HttpAuthContextVerifier, requestStateFromAuthInfo } from './http-auth.js';
|
|
6
|
+
import { HttpAuthContextVerifier, requestStateFromAuthInfo, requestStateFromInternalHeaders, } from './http-auth.js';
|
|
7
7
|
import { createMcpServer } from './mcp-server.js';
|
|
8
|
+
import { KLOUDY_MCP_VERSION } from './version.js';
|
|
8
9
|
export function createHttpApp(config, dependencies = {}) {
|
|
9
10
|
const app = createMcpExpressApp({ host: config.host, allowedHosts: config.allowedHosts });
|
|
10
11
|
const resourceMetadataUrl = getOAuthProtectedResourceMetadataUrl(config.publicUrl);
|
|
@@ -18,20 +19,24 @@ export function createHttpApp(config, dependencies = {}) {
|
|
|
18
19
|
response.json({ status: 'live' });
|
|
19
20
|
});
|
|
20
21
|
app.get('/health/ready', (_request, response) => {
|
|
21
|
-
response.json({
|
|
22
|
+
response.json({
|
|
23
|
+
status: 'ready',
|
|
24
|
+
resource: config.publicUrl.href,
|
|
25
|
+
version: KLOUDY_MCP_VERSION,
|
|
26
|
+
internalMcpEnabled: config.internalServiceToken !== null,
|
|
27
|
+
});
|
|
22
28
|
});
|
|
23
29
|
app.get(new URL(resourceMetadataUrl).pathname, (_request, response) => {
|
|
24
30
|
response.json({
|
|
25
31
|
resource: config.publicUrl.href,
|
|
26
|
-
authorization_servers: [config.authorizationServerUrl
|
|
32
|
+
authorization_servers: [serializeAuthorizationServerIssuer(config.authorizationServerUrl)],
|
|
27
33
|
scopes_supported: config.requiredScopes,
|
|
28
34
|
bearer_methods_supported: ['header'],
|
|
29
35
|
resource_name: 'Kloudy MCP',
|
|
30
36
|
});
|
|
31
37
|
});
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const { api, knowledge } = createClients(stateStore, 'remote-http-mcp');
|
|
38
|
+
const handleMcp = async (request, response, stateStore, clientKind) => {
|
|
39
|
+
const { api, knowledge } = createClients(stateStore, clientKind);
|
|
35
40
|
const server = createMcpServer(api, knowledge);
|
|
36
41
|
const transport = new StreamableHTTPServerTransport();
|
|
37
42
|
let closed = false;
|
|
@@ -62,18 +67,41 @@ export function createHttpApp(config, dependencies = {}) {
|
|
|
62
67
|
if (response.writableEnded || response.destroyed)
|
|
63
68
|
await close();
|
|
64
69
|
}
|
|
70
|
+
};
|
|
71
|
+
app.post('/mcp', requireAuth, async (request, response) => {
|
|
72
|
+
await handleMcp(request, response, requestStateFromAuthInfo(request.auth), 'remote-http-mcp');
|
|
65
73
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
app.post('/internal/mcp', async (request, response) => {
|
|
75
|
+
let stateStore;
|
|
76
|
+
try {
|
|
77
|
+
stateStore = requestStateFromInternalHeaders(request.headers, config.internalServiceToken);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
response.status(401).json({
|
|
69
81
|
jsonrpc: '2.0',
|
|
70
|
-
error: { code: -
|
|
82
|
+
error: { code: -32001, message: 'Unauthorized' },
|
|
71
83
|
id: null,
|
|
72
84
|
});
|
|
73
|
-
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
await handleMcp(request, response, stateStore, 'agent-internal-http-mcp');
|
|
88
|
+
});
|
|
89
|
+
for (const method of ['get', 'delete']) {
|
|
90
|
+
for (const path of ['/mcp', '/internal/mcp']) {
|
|
91
|
+
app[method](path, (_request, response) => {
|
|
92
|
+
response.status(405).json({
|
|
93
|
+
jsonrpc: '2.0',
|
|
94
|
+
error: { code: -32000, message: 'Method not allowed' },
|
|
95
|
+
id: null,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
74
99
|
}
|
|
75
100
|
return app;
|
|
76
101
|
}
|
|
102
|
+
export function serializeAuthorizationServerIssuer(url) {
|
|
103
|
+
return url.pathname === '/' && !url.search && !url.hash ? url.origin : url.href;
|
|
104
|
+
}
|
|
77
105
|
export async function startHttpServer(config) {
|
|
78
106
|
const app = createHttpApp(config);
|
|
79
107
|
return await new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../../src/http-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gEAAgE,CAAC;AACnG,OAAO,EAAE,oCAAoC,EAAE,MAAM,iDAAiD,CAAC;AAEvG,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../../src/http-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const KLOUDY_MCP_VERSION = "0.1.
|
|
1
|
+
export declare const KLOUDY_MCP_VERSION = "0.1.7";
|
|
2
2
|
export declare function getVersionCommandOutput(command: string, args: string[]): string | undefined;
|
|
@@ -55,6 +55,9 @@ export class ApiAClient {
|
|
|
55
55
|
});
|
|
56
56
|
if (state.characterId)
|
|
57
57
|
headers.set('K-Character-ID', state.characterId);
|
|
58
|
+
if (this.config.apiAServiceToken) {
|
|
59
|
+
headers.set('Authorization', `Bearer ${this.config.apiAServiceToken}`);
|
|
60
|
+
}
|
|
58
61
|
const body = {
|
|
59
62
|
query: input.query,
|
|
60
63
|
topK: input.topK ?? 4,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../../shared/src/api-a/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;QAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE;KAC3B,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAGvB;IACA;IAHX,YACE,OAAe,EACN,IAAY,EACZ,SAAkB;QAE3B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAS;QAG3B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,OAAO,UAAU;IAEF;IACA;IACA;IACA;IACA;IALnB,YACmB,MAAiB,EACjB,UAAsB,EACtB,YAA0B,KAAK,EAC/B,iBAAiB,oBAAoB,EACrC,aAAa,WAAW;QAJxB,WAAM,GAAN,MAAM,CAAW;QACjB,eAAU,GAAV,UAAU,CAAY;QACtB,cAAS,GAAT,SAAS,CAAsB;QAC/B,mBAAc,GAAd,cAAc,CAAuB;QACrC,eAAU,GAAV,UAAU,CAAc;IACxC,CAAC;IAEJ,KAAK,CAAC,eAAe,CAAC,KAA2B,EAAE,KAAa;QAC9D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,IAAI,SAAS,CAAC,+CAA+C,EAAE,yBAAyB,EAAE,KAAK,CAAC,CAAC;QACzG,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,mBAAmB,EACtD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAC/B,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;YAC1B,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,kBAAkB;YAClC,YAAY,EAAE,IAAI,CAAC,cAAc;YACjC,gBAAgB,EAAE,IAAI,CAAC,UAAU;YACjC,gBAAgB,EAAE,KAAK;YACvB,cAAc,EAAE,kBAAkB;YAClC,sBAAsB,EAAE,UAAU,EAAE;YACpC,aAAa,EAAE,KAAK,CAAC,QAAQ;YAC7B,MAAM,EAAE,cAAc,KAAK,CAAC,YAAY,EAAE;SAC3C,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../../shared/src/api-a/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
function parseOptionalServiceToken(raw) {
|
|
4
|
+
if (raw === undefined || raw === '')
|
|
5
|
+
return undefined;
|
|
6
|
+
if (raw.length < 32 || raw.length > 4096 || !/^[\x21-\x7e]+$/.test(raw)) {
|
|
7
|
+
throw new Error('KLOUDY_MCP_API_A_SERVICE_TOKEN must contain 32-4096 printable ASCII characters');
|
|
8
|
+
}
|
|
9
|
+
return raw;
|
|
10
|
+
}
|
|
3
11
|
export const DEFAULT_API_X_BASE_URL = 'https://shape.kloudy.cn/api-x';
|
|
4
12
|
export const DEFAULT_API_A_BASE_URL = 'https://shape.kloudy.cn/api-a';
|
|
5
13
|
export const DEFAULT_WEB_BASE_URL = 'https://shape.kloudy.cn';
|
|
@@ -35,9 +43,11 @@ function defaultStateDirectory(env) {
|
|
|
35
43
|
return join(homedir(), '.config', 'kloudy-agent-server');
|
|
36
44
|
}
|
|
37
45
|
export function loadConfig(env = process.env) {
|
|
46
|
+
const apiAServiceToken = parseOptionalServiceToken(env.KLOUDY_MCP_API_A_SERVICE_TOKEN);
|
|
38
47
|
return {
|
|
39
48
|
apiXBaseUrl: parseBaseUrl(env.KLOUDY_API_X_BASE_URL, DEFAULT_API_X_BASE_URL, 'KLOUDY_API_X_BASE_URL'),
|
|
40
49
|
apiABaseUrl: parseBaseUrl(env.KLOUDY_API_A_BASE_URL, DEFAULT_API_A_BASE_URL, 'KLOUDY_API_A_BASE_URL'),
|
|
50
|
+
...(apiAServiceToken ? { apiAServiceToken } : {}),
|
|
41
51
|
webBaseUrl: parseBaseUrl(env.KLOUDY_WEB_BASE_URL, DEFAULT_WEB_BASE_URL, 'KLOUDY_WEB_BASE_URL'),
|
|
42
52
|
requestTimeoutMs: parseTimeout(env.KLOUDY_API_X_TIMEOUT_MS, 'KLOUDY_API_X_TIMEOUT_MS'),
|
|
43
53
|
apiARequestTimeoutMs: parseTimeout(env.KLOUDY_API_A_TIMEOUT_MS, 'KLOUDY_API_A_TIMEOUT_MS'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../shared/src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../shared/src/config.ts"],"names":[],"mappings":"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"}
|
package/docs/http-mcp.md
CHANGED
|
@@ -8,15 +8,18 @@
|
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
10
|
POST /mcp
|
|
11
|
+
POST /internal/mcp
|
|
11
12
|
GET /.well-known/oauth-protected-resource/mcp
|
|
12
13
|
GET /health/live
|
|
13
14
|
GET /health/ready
|
|
14
15
|
```
|
|
15
16
|
|
|
16
|
-
`GET
|
|
17
|
+
`GET` 和 `DELETE` 两个 MCP 路径都返回 405。每个 POST 都创建新的 MCP Server、Transport、API-X/API-A 客户端和不可变 `RequestStateStore`;响应结束即关闭,不建立跨请求身份或协议 Session。公开 `/mcp` 使用 OAuth,内部 `/internal/mcp` 使用独立服务 Bearer 和逐请求身份 Header。
|
|
17
18
|
|
|
18
19
|
当前实现是 OAuth Resource Server,不签发 Access Token、不保存 Refresh Token,也不提供登录页。API-X 提供 Authorization Server 与内部授权上下文端点。源码完成和本地协议测试不代表 npm 已发布、真实 OAuth 已完成端到端验收或 `https://kloudy.cn/mcp` 已部署。
|
|
19
20
|
|
|
21
|
+
自有 API-G 不走交互式 OAuth。它只从本机访问 `/internal/mcp`,使用 `Authorization: Bearer <KLOUDY_MCP_INTERNAL_SERVICE_TOKEN>`,并分别通过 `K-Session-Token`、`K-Device-ID`、`K-Character-ID` 携带当前已验证身份。四项缺失、错误或格式无效均返回 401,不降级到公开 OAuth、Visitor 或 stdio。服务令牌不代替用户权限,下游 API 仍逐请求复验用户身份。
|
|
22
|
+
|
|
20
23
|
## 身份流程
|
|
21
24
|
|
|
22
25
|
```text
|
|
@@ -73,8 +76,10 @@ Content-Type: application/json
|
|
|
73
76
|
| `KLOUDY_MCP_AUTHORIZATION_SERVER_URL` | 无 | OAuth Authorization Server issuer,必填 |
|
|
74
77
|
| `KLOUDY_MCP_AUTH_CONTEXT_URL` | 无 | 受信内部授权上下文端点,必填 |
|
|
75
78
|
| `KLOUDY_MCP_AUTH_CONTEXT_SERVICE_TOKEN` | 无 | MCP 调用内部端点的服务令牌,必填且至少 32 字符 |
|
|
79
|
+
| `KLOUDY_MCP_INTERNAL_SERVICE_TOKEN` | 无 | 启用 `/internal/mcp` 的 API-G→MCP 服务 Bearer;至少 32 字符且不得复用其他令牌 |
|
|
76
80
|
| `KLOUDY_MCP_AUTH_TIMEOUT_MS` | `5000` | 内部授权请求超时,允许 1000 至 30000 毫秒 |
|
|
77
81
|
| `KLOUDY_MCP_REQUIRED_SCOPES` | `mcp:tools` | 每个远程协议请求必须具备的空格分隔 Scope |
|
|
82
|
+
| `KLOUDY_MCP_API_A_SERVICE_TOKEN` | 无 | 调用 API-A 知识检索时使用的独立服务 Bearer;不能代替请求级用户身份 |
|
|
78
83
|
|
|
79
84
|
生产示例只展示变量名,不应把真实服务令牌写入 Shell 历史、Git 或日志:
|
|
80
85
|
|
|
@@ -85,6 +90,7 @@ KLOUDY_MCP_PUBLIC_URL=https://kloudy.cn/mcp
|
|
|
85
90
|
KLOUDY_MCP_AUTHORIZATION_SERVER_URL=https://kloudy.cn
|
|
86
91
|
KLOUDY_MCP_AUTH_CONTEXT_URL=https://shape.kloudy.cn/api-x/internal/mcp/auth-context
|
|
87
92
|
KLOUDY_MCP_AUTH_CONTEXT_SERVICE_TOKEN=replace_with_private_service_token
|
|
93
|
+
KLOUDY_MCP_INTERNAL_SERVICE_TOKEN=replace_with_distinct_agent_service_token
|
|
88
94
|
KLOUDY_MCP_REQUIRED_SCOPES=mcp:tools
|
|
89
95
|
```
|
|
90
96
|
|
|
@@ -115,9 +121,9 @@ Shape 的最后一项实际写在 JSON 字段中;这里用赋值形式只是
|
|
|
115
121
|
node packages/kloudy-mcp/dist/kloudy-mcp/src/cli.js serve-http
|
|
116
122
|
```
|
|
117
123
|
|
|
118
|
-
|
|
124
|
+
启动前会完整校验公开 OAuth 配置;仅配置有效的 `KLOUDY_MCP_INTERNAL_SERVICE_TOKEN` 时才启用内部入口。进程收到 `SIGINT` 或 `SIGTERM` 后停止接收新连接,并给现有连接最多 60 秒结束。`live` 表示 Node HTTP 进程可以响应;`ready` 返回当前版本和 `internalMcpEnabled`,但不主动携带用户 Token 调用授权服务或业务 API,因此不能替代真实身份与 Tool 验收。
|
|
119
125
|
|
|
120
|
-
服务使用公开 Resource hostname、监听 hostname、`127.0.0.1` 和 `localhost` 作为 Host 白名单。生产应只监听本机,由 Nginx
|
|
126
|
+
服务使用公开 Resource hostname、监听 hostname、`127.0.0.1` 和 `localhost` 作为 Host 白名单。生产应只监听本机,由 Nginx 仅将精确 `/mcp` 和 `/.well-known/oauth-protected-resource/mcp` 转发到该端口;`/internal/mcp` 不得进入 Nginx、公网、CDN、SPA fallback 或 Cookie 身份处理。
|
|
121
127
|
|
|
122
128
|
## 本地验证
|
|
123
129
|
|
|
@@ -128,4 +134,4 @@ npm run smoke
|
|
|
128
134
|
npm run smoke:http
|
|
129
135
|
```
|
|
130
136
|
|
|
131
|
-
HTTP 测试使用本地临时监听和内存 Mock 授权上下文,验证 Protected Resource Metadata
|
|
137
|
+
HTTP 测试使用本地临时监听和内存 Mock 授权上下文,验证 Protected Resource Metadata、公开匿名 401、OAuth Bearer、内部服务 Bearer、请求身份隔离、无状态握手和两个入口均发现相同的 64 个工具,不访问线上 API-X/API-A。
|
package/docs/local-mcp.md
CHANGED
|
@@ -101,6 +101,7 @@ export KLOUDY_API_A_BASE_URL=http://localhost:12174/api-a
|
|
|
101
101
|
| `KLOUDY_WEB_BASE_URL` | `https://shape.kloudy.cn` | 开发、测试环境的网页授权地址覆盖 |
|
|
102
102
|
| `KLOUDY_API_X_TIMEOUT_MS` | `10000` | API-X 请求超时,允许 1000 至 60000 毫秒 |
|
|
103
103
|
| `KLOUDY_API_A_TIMEOUT_MS` | `10000` | API-A 检索请求超时,允许 1000 至 60000 毫秒 |
|
|
104
|
+
| `KLOUDY_MCP_API_A_SERVICE_TOKEN` | 无 | MCP 到 API-A 的独立 Bearer 服务身份;配置时必须为 32–4096 个无空白 ASCII 字符 |
|
|
104
105
|
| `KLOUDY_MCP_STATE_DIR` | `~/.config/kloudy-agent-server` | 本地设备和可选会话状态目录 |
|
|
105
106
|
|
|
106
107
|
默认地址必须直接指向 API-X 的最终主机名。`https://kloudy.cn/api-x` 会跨主机重定向到 `shape.kloudy.cn`,Node.js 会在该重定向中移除敏感 Cookie,导致公开查询可用但 User 级工具被识别为 Visitor。
|
|
@@ -206,13 +207,13 @@ node /absolute/path/to/kloudy-agent-tools/packages/kloudy-mcp/dist/kloudy-mcp/sr
|
|
|
206
207
|
|
|
207
208
|
API-X/API-A Base URL、HTTP Method、Route 和 Header 都由本地代码固定生成,模型不能通过 Tool 参数修改。工具注册按知识检索、账号、Character、分类字典、Links、Archive、Documents、Community、Wiki 和 Blog 领域拆分,统一声明 Character 类型、最低权限、风险、是否直接改变公开内容、幂等性、超时和最大响应大小。超过工具响应上限时返回 `result_too_large`,不会把过大的上游结果直接注入模型上下文。
|
|
208
209
|
|
|
209
|
-
`knowledge_search` 将本地状态中的 `k_token_id`、`K-Device-ID` 和可选 `K-Character-ID` 逐请求发送给 API-A
|
|
210
|
+
`knowledge_search` 将本地状态中的 `k_token_id`、`K-Device-ID` 和可选 `K-Character-ID` 逐请求发送给 API-A;配置服务身份时同时发送独立 Authorization Bearer,API-A 仍会通过 API-X 验证用户身份。服务身份只证明调用方是 MCP,不能扩展用户权限。输入只开放 `query`、`topK` 和可选 `entryId`,输出只保留索引版本、片段 ID、词条 ID、标题、树路径、来源 URL、片段类型、正文摘录和分数,不返回正文哈希。
|
|
210
211
|
|
|
211
212
|
API-A 连接或超时错误分别返回 `api_a_error` 下的 `knowledge_unavailable`、`knowledge_timeout`;API-A 的安全业务错误码(例如 `INDEX_CONFIG_CHANGED`、`AUTH_UNAVAILABLE`)会保留。错误包含独立 MCP `traceId`,不包含凭据、上游响应头、请求正文或堆栈;API-A 失败只影响当前知识检索调用,不关闭 MCP,也不阻断不依赖 API-A 的其他工具。
|
|
212
213
|
|
|
213
|
-
### 受信 Agent
|
|
214
|
+
### 受信 Agent stdio 回滚模式
|
|
214
215
|
|
|
215
|
-
`serve-
|
|
216
|
+
自有 Agent 的生产主路径已改为常驻 `serve-http` 的 `/internal/mcp`,详见 [Streamable HTTP MCP](http-mcp.md)。`serve-request` 保留为低并发诊断和显式回滚路径;受信父进程完成用户、设备和 Character 校验后,为一个 Run 启动一个独立 stdio MCP 子进程,并在子进程环境中提供:
|
|
216
217
|
|
|
217
218
|
| 环境变量 | 内容 |
|
|
218
219
|
| --- | --- |
|
|
@@ -231,7 +232,7 @@ CLI 在 MCP 握手前校验三项值并将其从 Node.js `process.env` 删除,
|
|
|
231
232
|
kloudy-mcp serve-request
|
|
232
233
|
```
|
|
233
234
|
|
|
234
|
-
一个 `serve-request` 进程只属于一个 Agent HTTP
|
|
235
|
+
一个 `serve-request` 进程只属于一个 Agent Run,不允许重绑身份、放入跨用户连接池或对公网直接暴露。自有 Agent 与外部 HTTP Agent 发现同一工具目录;MCP 提供身份隔离和统一契约,Agent 仍负责只读准入、预算、写入预览、用户确认、幂等与中断恢复。当前 Kloudy Agent 只动态开放符合完整只读元数据的工具,写工具保持关闭。
|
|
235
236
|
|
|
236
237
|
账号上下文只返回认证类型、权限级别、User ID 和当前 Character 的最小身份;自有角色列表也只返回 ID、类型、名称和头像,不返回 Token、Cookie、设备 ID、User SN、Character SN、邮箱或完整个人资料。Archive 和 Blog 结果会裁剪内部 SN、删除/发布管理状态和未列入白名单的字段。
|
|
237
238
|
|