@qwen-code/qwen-code 0.19.5-nightly.20260703.b16baf1ff → 0.19.5
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/chunks/{MaxSizedBox-42KZ5OFE.js → MaxSizedBox-5JV77KRA.js} +6 -6
- package/chunks/{StandaloneSessionPicker-G4VTICMM.js → StandaloneSessionPicker-MGUGB6PH.js} +17 -17
- package/chunks/{acpAgent-6O25PA3M.js → acpAgent-4F36XM3X.js} +53 -55
- package/chunks/{agent-SNVTRNV7.js → agent-IWBUZI6A.js} +3 -3
- package/chunks/{agent-headless-LNKVTSBX.js → agent-headless-JUTICAYO.js} +3 -3
- package/chunks/{bridge-AZZAYKI2.js → bridge-DHZHQ4UV.js} +6 -6
- package/chunks/{chunk-ZRHHQFV4.js → chunk-2CAII5HD.js} +1 -1
- package/chunks/{chunk-RBLDOR7U.js → chunk-2YH27UNF.js} +1 -1
- package/chunks/{chunk-XR7W5VRL.js → chunk-4MCC4XHH.js} +26 -26
- package/chunks/{chunk-3GCPLNVF.js → chunk-6KPZJJ6U.js} +9 -9
- package/chunks/{chunk-WWOVV2PW.js → chunk-6QTCOQX7.js} +109 -298
- package/chunks/{chunk-4JWM2UGC.js → chunk-6QVQZAW6.js} +1 -1
- package/chunks/{chunk-XAVV2JAM.js → chunk-BC4R5C5R.js} +5 -5
- package/chunks/{chunk-WMLQKZ64.js → chunk-CBJE2PLG.js} +2 -2
- package/chunks/{chunk-UEGNXWAX.js → chunk-CHY5C5T4.js} +3 -3
- package/chunks/{chunk-FEPEMQR4.js → chunk-CSPSJU5R.js} +13 -13
- package/chunks/{chunk-L4CYPEA7.js → chunk-DM4E337C.js} +1 -1
- package/chunks/{chunk-XS7IHJ63.js → chunk-DRS2HTNT.js} +5 -5
- package/chunks/chunk-EJ7BN3EN.js +11396 -0
- package/chunks/{chunk-FVRLDQ7T.js → chunk-EROWZQN7.js} +1 -1
- package/chunks/{chunk-C47IJLUT.js → chunk-G4M7FPNY.js} +1 -1
- package/chunks/{chunk-DLJKEPXB.js → chunk-HISPEX42.js} +6 -6
- package/chunks/{chunk-P5GH4DTN.js → chunk-IMAMNLY6.js} +3 -3
- package/chunks/{chunk-YLQSGKAN.js → chunk-J3ERRYYI.js} +2 -2
- package/chunks/{chunk-Z75MFQFL.js → chunk-JJ6B3ZD3.js} +2 -2
- package/chunks/{chunk-26UO4PLG.js → chunk-JKGCBO3O.js} +3 -3
- package/chunks/{chunk-KFO6YNQT.js → chunk-K4I4STSL.js} +2 -2
- package/chunks/{chunk-DNV4FSN5.js → chunk-KKQWC6WS.js} +1 -1
- package/chunks/{chunk-STP6AYKH.js → chunk-LHMZCIKL.js} +1 -1
- package/chunks/{chunk-6NHUWPNL.js → chunk-M5ITDKSM.js} +1 -1
- package/chunks/{chunk-QURP4S5U.js → chunk-MDBNFHIO.js} +3 -3
- package/chunks/{chunk-AYUVPH6L.js → chunk-MNOXKSM2.js} +1 -1
- package/chunks/{chunk-VDIZBM46.js → chunk-NDY7OENU.js} +2 -2
- package/chunks/{chunk-HCLTQ3PV.js → chunk-NNEJEBCF.js} +19 -19
- package/chunks/{chunk-4UEWG5AS.js → chunk-NSSVORTQ.js} +4 -4
- package/chunks/{chunk-O2EZ4VRP.js → chunk-OQHLUA2Y.js} +3 -3
- package/chunks/{chunk-4RQIB5UZ.js → chunk-PPFWEV7G.js} +62 -62
- package/chunks/{chunk-FB6LGUF4.js → chunk-QHYITL6P.js} +1 -1
- package/chunks/{chunk-VJSWLYUL.js → chunk-R3UWLLRQ.js} +1 -1
- package/chunks/{chunk-UTWYG2WA.js → chunk-RNGAT2Y2.js} +1 -1
- package/chunks/{chunk-7XS7CMSU.js → chunk-RSBQS6M4.js} +1 -1
- package/chunks/{chunk-4PGQKUIV.js → chunk-SBMHB6N5.js} +11 -11
- package/chunks/{chunk-DNJ2KHWN.js → chunk-SJVPSHXU.js} +4 -4
- package/chunks/{chunk-LOEYAC6N.js → chunk-TN6RT6EJ.js} +2 -2
- package/chunks/{chunk-F26BNXI2.js → chunk-UJT42DB6.js} +5 -5
- package/chunks/{chunk-46IAL3RB.js → chunk-WALEWZ44.js} +1 -1
- package/chunks/{chunk-APTOAKV5.js → chunk-WZ724G6K.js} +3 -3
- package/chunks/{chunk-FKHE7ZNF.js → chunk-XKZXGIRM.js} +2 -2
- package/chunks/{chunk-7K4G2H2H.js → chunk-Y4UQT3PM.js} +1 -1
- package/chunks/{chunk-ODPWORQZ.js → chunk-Z7XNVNPM.js} +1 -1
- package/chunks/{chunk-WSAAEPPQ.js → chunk-ZISMVA6U.js} +4 -4
- package/chunks/{computer-use-UHZAYYGO.js → computer-use-ON3JQUHW.js} +3 -3
- package/chunks/{contextCommand-X4WOJ2L4.js → contextCommand-OGCG7W6N.js} +5 -5
- package/chunks/{daemon-status-provider-YXWNGOAF.js → daemon-status-provider-P72STMLB.js} +9 -9
- package/chunks/{earlyInputCapture-3HUGMAFL.js → earlyInputCapture-DAFHSGVW.js} +3 -3
- package/chunks/{edit-QDKRNFZK.js → edit-3QFNCSZH.js} +3 -3
- package/chunks/{enter-worktree-ODWIPMOP.js → enter-worktree-62EQQMLD.js} +3 -3
- package/chunks/{enterPlanMode-XROL6G5C.js → enterPlanMode-VUQSE4EG.js} +3 -3
- package/chunks/{errors-RCPBWFTG.js → errors-PW75PZXE.js} +5 -5
- package/chunks/{exit-worktree-BIU7P4TR.js → exit-worktree-VVNH7OVY.js} +3 -3
- package/chunks/{exitPlanMode-LWZHZ7CF.js → exitPlanMode-RUYRCYZW.js} +3 -3
- package/chunks/{fast-path-7S4NR2WI.js → fast-path-TFRJRTTR.js} +3 -3
- package/chunks/{fast-path-settings-RCRXH2JG.js → fast-path-settings-UQLRFDQP.js} +2 -2
- package/chunks/{gemini-W7CZCFFV.js → gemini-XW7ZDUVR.js} +53 -58
- package/chunks/{geminiContentGenerator-MWZWJAWR.js → geminiContentGenerator-MZDVHVZH.js} +1 -1
- package/chunks/{glob-GZ4LUOQT.js → glob-WAY2PUWA.js} +3 -3
- package/chunks/{grep-BZ34WAQJ.js → grep-W6CBKSYC.js} +3 -3
- package/chunks/{initializer-W4EUD3H7.js → initializer-HK2XE6P2.js} +8 -8
- package/chunks/{list-S325XJ2Y.js → list-RVLIIKKL.js} +10 -10
- package/chunks/{loadedSettingsAdapter-QP3XBMQI.js → loadedSettingsAdapter-C63OUYZC.js} +8 -8
- package/chunks/{monitor-7C33CWA5.js → monitor-FOG36ABM.js} +3 -3
- package/chunks/{nonInteractiveCli-FPZS7ROR.js → nonInteractiveCli-6BYQSJTB.js} +34 -36
- package/chunks/{notebook-edit-ZXQ25NWU.js → notebook-edit-GC6NXRCX.js} +3 -3
- package/chunks/{openaiContentGenerator-FUQ7GNK6.js → openaiContentGenerator-EXR3ZL3Z.js} +2 -2
- package/chunks/{pidfile-NPZV5ZIA.js → pidfile-FNZM2DDH.js} +3 -3
- package/chunks/{qwenContentGenerator-LNEWYA52.js → qwenContentGenerator-A7B6J4U7.js} +4 -4
- package/chunks/{read-file-G6GBNSM3.js → read-file-6JL4ULMY.js} +1 -1
- package/chunks/{ripGrep-IGOC7PVL.js → ripGrep-DIUGLJE5.js} +3 -3
- package/chunks/{run-qwen-serve-AAA53KS4.js → run-qwen-serve-CME3AKM4.js} +23 -23
- package/chunks/{scheduler-SPGJ7ILO.js → scheduler-L7F6GDDT.js} +3 -3
- package/chunks/{serve-37UIHUYP.js → serve-SRCBOJGP.js} +9 -9
- package/chunks/{server-MFMOYMEB.js → server-QSQ45QFR.js} +46 -46
- package/chunks/{session-XRY2CG4Z.js → session-5DG6NXHZ.js} +35 -37
- package/chunks/{settings-X5GXXGKH.js → settings-3EEQI4MN.js} +7 -7
- package/chunks/{shell-E5HOWJMT.js → shell-B7FNYF5S.js} +3 -3
- package/chunks/{skill-FELDZMWO.js → skill-AAOGHD5O.js} +1 -1
- package/chunks/{spawnChannel-XLTVHAT6.js → spawnChannel-3CBN3ZLK.js} +5 -5
- package/chunks/{src-ZWPLTWTV.js → src-T5A7P7FS.js} +3 -3
- package/chunks/{startInteractiveUI-GO6J3SJ7.js → startInteractiveUI-2FGEQ6AS.js} +108 -111
- package/chunks/{team-create-WWMKZ3UO.js → team-create-KDF6W6PV.js} +3 -3
- package/chunks/{team-plan-approval-CUNEZJOV.js → team-plan-approval-PSFKQX7M.js} +3 -3
- package/chunks/{theme-manager-LRBEA5ID.js → theme-manager-5XOA2AO7.js} +3 -3
- package/chunks/{tool-search-L57ZRBJF.js → tool-search-LFRILZXC.js} +1 -1
- package/chunks/{trustedFolders-DYAOFXN2.js → trustedFolders-7HQY6T6X.js} +4 -4
- package/chunks/{validateNonInterActiveAuth-AB4C2FLG.js → validateNonInterActiveAuth-UC27B7BA.js} +31 -33
- package/chunks/{workflow-H7YLGTBI.js → workflow-KUTESS6L.js} +4 -4
- package/chunks/{workspace-providers-status-UUIBOTKI.js → workspace-providers-status-LJT5AQDS.js} +10 -10
- package/chunks/{workspace-service-FATHYK5C.js → workspace-service-YOBYVDXH.js} +15 -15
- package/chunks/{workspace-skills-status-KIC3KYPR.js → workspace-skills-status-ONEPXJV6.js} +5 -5
- package/chunks/{write-file-ETGUMYAK.js → write-file-FJYBZUHP.js} +3 -3
- package/cli-entry.js +8 -81
- package/cli.js +55 -348
- package/node_modules/@qwen-code/audio-capture/package.json +1 -1
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-QjIJgYzv.js → arc-D_rAuMDd.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-DJkZ9KoB.js → architectureDiagram-3BPJPVTR-DUCzbHVo.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-BlNeekUB.js → blockDiagram-GPEHLZMM-BEEBt1LL.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-B6FDrE3D.js → c4Diagram-AAUBKEIU-5ZJ_DeFL.js} +1 -1
- package/web-shell/assets/channel-B5ynH0q8.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-CZO5-3og.js → chunk-2J33WTMH-Cfw7EiLn.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-CZ2VJPFe.js → chunk-4BX2VUAB-FGuZNCZY.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-3zVP6pGF.js → chunk-55IACEB6-CaBwYPBF.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-omuP8Zhh.js → chunk-727SXJPM-BlR04OFz.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BK6Ivmyv.js → chunk-AQP2D5EJ-D3_mYJH5.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-NLjjxV0s.js → chunk-FMBD7UC4-7D4q4SbB.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-Dc0JTV8t.js → chunk-ND2GUHAM-BjX_Iwmr.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-ZYp-8jN-.js → chunk-QZHKN3VN-C3Hz_ZQh.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CK3ibywp.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CK3ibywp.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-BNu1jqy7.js → cose-bilkent-S5V4N54A-Ax4UycaT.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-0AHvPm2v.js → dagre-BM42HDAG-C6hmPtGt.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-BJsDQdp0.js → diagram-2AECGRRQ-tXZnxjmw.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-C1gNnoxj.js → diagram-5GNKFQAL-99dwIzQG.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-FmgehSoq.js → diagram-KO2AKTUF-Bqhn0-2s.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-i7_13R2F.js → diagram-LMA3HP47-DzThVSvo.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DkUUR1x-.js → diagram-OG6HWLK6-DPE8vjln.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-BcwJzw0n.js → erDiagram-TEJ5UH35-KzUKgQCV.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-CCPgwkQS.js → flowDiagram-I6XJVG4X-DBN-DXw5.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-C3g0sliF.js → ganttDiagram-6RSMTGT7-DuBsP9u8.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-DLt4J_oG.js → gitGraphDiagram-PVQCEYII-BjWHMyKR.js} +1 -1
- package/web-shell/assets/{index-DasTT8n6.js → index-CWzDaQT5.js} +105 -105
- package/web-shell/assets/{infoDiagram-5YYISTIA-DMO0nW8F.js → infoDiagram-5YYISTIA-BVux0vP6.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-qSN9LjC5.js → ishikawaDiagram-YF4QCWOH-2qzw7f--.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CQZH-jC2.js → journeyDiagram-JHISSGLW-Dnl65sxL.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-Cu6qk5En.js → kanban-definition-UN3LZRKU-BElSQYtY.js} +1 -1
- package/web-shell/assets/{linear-Dpp4BWJF.js → linear-BjoycSSY.js} +1 -1
- package/web-shell/assets/{mermaid.core-DDAcmZsz.js → mermaid.core-xe6bvMRz.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-G3JXxnUU.js → mindmap-definition-RKZ34NQL-D8DQgI4U.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-ABQwHraX.js → pieDiagram-4H26LBE5-Dwh7Gp7c.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BUWZV-ho.js → quadrantDiagram-W4KKPZXB-BXKNBln2.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-XHg5n00A.js → requirementDiagram-4Y6WPE33-BzaC3cIA.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-Bwzw0RtM.js → sankeyDiagram-5OEKKPKP-DP2t7eZk.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CGYLtnFV.js → sequenceDiagram-3UESZ5HK-XlFiWEYv.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-BG1UhKch.js → stateDiagram-AJRCARHV-CupgUMJO.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-By3E4QwN.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-B_tY-Dyz.js → timeline-definition-PNZ67QCA-DstuGywa.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-Crp_Rw_L.js → vennDiagram-CIIHVFJN-CnbNp6zu.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-DR27pFXX.js → wardley-L42UT6IY-DnvoHq6R.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BM_CRFgm.js → wardleyDiagram-YWT4CUSO-Cz0xHEWB.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-DO2Z2lWl.js → xychartDiagram-2RQKCTM6-p36gfo88.js} +1 -1
- package/web-shell/index.html +1 -1
- package/chunks/chunk-3RW4AZJV.js +0 -5063
- package/chunks/chunk-DOYHOG47.js +0 -949
- package/chunks/chunk-E2K45AJ7.js +0 -5448
- package/chunks/mcp-LRKXM6OS.js +0 -66
- package/chunks/version-2A66AIB2.js +0 -10
- package/chunks/yargs-B64EYTCF.js +0 -10
- package/web-shell/assets/channel-M6R-XOoS.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-B7rcL2Jc.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B7rcL2Jc.js +0 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CSG8MpoN.js +0 -1
- package/chunks/{channel-worker-supervisor-C2J3TIOV.js → channel-worker-supervisor-EVPAYNZ5.js} +3 -3
package/chunks/chunk-DOYHOG47.js
DELETED
|
@@ -1,949 +0,0 @@
|
|
|
1
|
-
// Force strict mode and setup for ESM
|
|
2
|
-
"use strict";
|
|
3
|
-
import {
|
|
4
|
-
loadSettings
|
|
5
|
-
} from "./chunk-XAVV2JAM.js";
|
|
6
|
-
import {
|
|
7
|
-
getCurrentLanguage
|
|
8
|
-
} from "./chunk-L4CYPEA7.js";
|
|
9
|
-
import {
|
|
10
|
-
isWorkspaceTrusted
|
|
11
|
-
} from "./chunk-ODPWORQZ.js";
|
|
12
|
-
import {
|
|
13
|
-
writeStderrLine,
|
|
14
|
-
writeStdoutLine
|
|
15
|
-
} from "./chunk-Y6Z2O3WR.js";
|
|
16
|
-
import {
|
|
17
|
-
require_strip_json_comments
|
|
18
|
-
} from "./chunk-QYUE6W3T.js";
|
|
19
|
-
import {
|
|
20
|
-
Client,
|
|
21
|
-
Config,
|
|
22
|
-
ExtensionManager,
|
|
23
|
-
FileDiscoveryService,
|
|
24
|
-
MCPOAuthTokenStorage,
|
|
25
|
-
createTransport,
|
|
26
|
-
hashMcpServerConfig,
|
|
27
|
-
isGatedMcpScope,
|
|
28
|
-
normalizeClaudeMcpServer
|
|
29
|
-
} from "./chunk-WWOVV2PW.js";
|
|
30
|
-
import {
|
|
31
|
-
atomicWriteFile
|
|
32
|
-
} from "./chunk-T42ACHFI.js";
|
|
33
|
-
import {
|
|
34
|
-
Storage,
|
|
35
|
-
getErrorMessage
|
|
36
|
-
} from "./chunk-AVQDCKNF.js";
|
|
37
|
-
import {
|
|
38
|
-
init_esbuild_shims
|
|
39
|
-
} from "./chunk-A4BMJM77.js";
|
|
40
|
-
import {
|
|
41
|
-
__name,
|
|
42
|
-
__toESM
|
|
43
|
-
} from "./chunk-J2S4EL5Y.js";
|
|
44
|
-
|
|
45
|
-
// packages/cli/src/commands/mcp.ts
|
|
46
|
-
init_esbuild_shims();
|
|
47
|
-
|
|
48
|
-
// packages/cli/src/commands/mcp/add.ts
|
|
49
|
-
init_esbuild_shims();
|
|
50
|
-
async function addMcpServer(name, commandOrUrl, args, options) {
|
|
51
|
-
const {
|
|
52
|
-
scope,
|
|
53
|
-
transport,
|
|
54
|
-
env,
|
|
55
|
-
header,
|
|
56
|
-
timeout,
|
|
57
|
-
trust,
|
|
58
|
-
description,
|
|
59
|
-
includeTools,
|
|
60
|
-
excludeTools,
|
|
61
|
-
oauthClientId,
|
|
62
|
-
oauthClientSecret,
|
|
63
|
-
oauthRedirectUri,
|
|
64
|
-
oauthAuthorizationUrl,
|
|
65
|
-
oauthTokenUrl,
|
|
66
|
-
oauthScopes
|
|
67
|
-
} = options;
|
|
68
|
-
const settings = loadSettings(process.cwd());
|
|
69
|
-
const inHome = settings.workspace.path === settings.user.path;
|
|
70
|
-
if (scope === "project" && inHome) {
|
|
71
|
-
writeStderrLine(
|
|
72
|
-
"Error: Please use --scope user to edit settings in the home directory."
|
|
73
|
-
);
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
const settingsScope = scope === "user" ? "User" /* User */ : "Workspace" /* Workspace */;
|
|
77
|
-
let newServer = {};
|
|
78
|
-
const scopes = oauthScopes?.flatMap((s) => s.split(",")).map((s) => s.trim()).filter(Boolean);
|
|
79
|
-
const hasOAuth = Boolean(
|
|
80
|
-
oauthClientId || oauthClientSecret || oauthRedirectUri || oauthAuthorizationUrl || oauthTokenUrl || scopes && scopes.length > 0
|
|
81
|
-
);
|
|
82
|
-
if (hasOAuth && transport === "stdio") {
|
|
83
|
-
writeStderrLine(
|
|
84
|
-
"Error: OAuth options (--oauth-*) are only supported with --transport sse or --transport http."
|
|
85
|
-
);
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
const oauthConfig = hasOAuth ? {
|
|
89
|
-
enabled: true,
|
|
90
|
-
...oauthClientId && { clientId: oauthClientId },
|
|
91
|
-
...oauthClientSecret && { clientSecret: oauthClientSecret },
|
|
92
|
-
...oauthRedirectUri && { redirectUri: oauthRedirectUri },
|
|
93
|
-
...oauthAuthorizationUrl && {
|
|
94
|
-
authorizationUrl: oauthAuthorizationUrl
|
|
95
|
-
},
|
|
96
|
-
...oauthTokenUrl && { tokenUrl: oauthTokenUrl },
|
|
97
|
-
...scopes && scopes.length > 0 && { scopes }
|
|
98
|
-
} : void 0;
|
|
99
|
-
const headers = header?.reduce(
|
|
100
|
-
(acc, curr) => {
|
|
101
|
-
const [key, ...valueParts] = curr.split(":");
|
|
102
|
-
const value = valueParts.join(":").trim();
|
|
103
|
-
if (key.trim() && value) {
|
|
104
|
-
acc[key.trim()] = value;
|
|
105
|
-
}
|
|
106
|
-
return acc;
|
|
107
|
-
},
|
|
108
|
-
{}
|
|
109
|
-
);
|
|
110
|
-
switch (transport) {
|
|
111
|
-
case "sse":
|
|
112
|
-
newServer = {
|
|
113
|
-
url: commandOrUrl,
|
|
114
|
-
headers,
|
|
115
|
-
timeout,
|
|
116
|
-
trust,
|
|
117
|
-
description,
|
|
118
|
-
includeTools,
|
|
119
|
-
excludeTools,
|
|
120
|
-
oauth: oauthConfig
|
|
121
|
-
};
|
|
122
|
-
break;
|
|
123
|
-
case "http":
|
|
124
|
-
newServer = {
|
|
125
|
-
httpUrl: commandOrUrl,
|
|
126
|
-
headers,
|
|
127
|
-
timeout,
|
|
128
|
-
trust,
|
|
129
|
-
description,
|
|
130
|
-
includeTools,
|
|
131
|
-
excludeTools,
|
|
132
|
-
oauth: oauthConfig
|
|
133
|
-
};
|
|
134
|
-
break;
|
|
135
|
-
case "stdio":
|
|
136
|
-
default:
|
|
137
|
-
newServer = {
|
|
138
|
-
command: commandOrUrl,
|
|
139
|
-
args: args?.map(String),
|
|
140
|
-
env: env?.reduce(
|
|
141
|
-
(acc, curr) => {
|
|
142
|
-
const separator = curr.indexOf("=");
|
|
143
|
-
if (separator === -1) {
|
|
144
|
-
return acc;
|
|
145
|
-
}
|
|
146
|
-
const key = curr.slice(0, separator);
|
|
147
|
-
const value = curr.slice(separator + 1);
|
|
148
|
-
if (key && value) {
|
|
149
|
-
acc[key] = value;
|
|
150
|
-
}
|
|
151
|
-
return acc;
|
|
152
|
-
},
|
|
153
|
-
{}
|
|
154
|
-
),
|
|
155
|
-
timeout,
|
|
156
|
-
trust,
|
|
157
|
-
description,
|
|
158
|
-
includeTools,
|
|
159
|
-
excludeTools
|
|
160
|
-
};
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
const existingSettings = settings.forScope(settingsScope).settings;
|
|
164
|
-
const mcpServers = existingSettings.mcpServers || {};
|
|
165
|
-
const isExistingServer = !!mcpServers[name];
|
|
166
|
-
if (isExistingServer) {
|
|
167
|
-
writeStdoutLine(
|
|
168
|
-
`MCP server "${name}" is already configured within ${scope} settings.`
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
mcpServers[name] = newServer;
|
|
172
|
-
settings.setValue(settingsScope, "mcpServers", mcpServers);
|
|
173
|
-
if (isExistingServer) {
|
|
174
|
-
writeStdoutLine(`MCP server "${name}" updated in ${scope} settings.`);
|
|
175
|
-
} else {
|
|
176
|
-
writeStdoutLine(
|
|
177
|
-
`MCP server "${name}" added to ${scope} settings. (${transport})`
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
__name(addMcpServer, "addMcpServer");
|
|
182
|
-
var addCommand = {
|
|
183
|
-
command: "add <name> <commandOrUrl> [args...]",
|
|
184
|
-
describe: "Add a server",
|
|
185
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.usage("Usage: qwen mcp add [options] <name> <commandOrUrl> [args...]").parserConfiguration({
|
|
186
|
-
"unknown-options-as-args": true,
|
|
187
|
-
// Pass unknown options as server args
|
|
188
|
-
"populate--": true
|
|
189
|
-
// Populate server args after -- separator
|
|
190
|
-
}).positional("name", {
|
|
191
|
-
describe: "Name of the server",
|
|
192
|
-
type: "string",
|
|
193
|
-
demandOption: true
|
|
194
|
-
}).positional("commandOrUrl", {
|
|
195
|
-
describe: "Command (stdio) or URL (sse, http)",
|
|
196
|
-
type: "string",
|
|
197
|
-
demandOption: true
|
|
198
|
-
}).option("scope", {
|
|
199
|
-
alias: "s",
|
|
200
|
-
describe: "Configuration scope (user or project)",
|
|
201
|
-
type: "string",
|
|
202
|
-
default: "user",
|
|
203
|
-
choices: ["user", "project"]
|
|
204
|
-
}).option("transport", {
|
|
205
|
-
alias: "t",
|
|
206
|
-
describe: "Transport type (stdio, sse, http). Auto-detected from URL if not specified.",
|
|
207
|
-
type: "string",
|
|
208
|
-
choices: ["stdio", "sse", "http"]
|
|
209
|
-
}).option("env", {
|
|
210
|
-
alias: "e",
|
|
211
|
-
describe: "Set environment variables (e.g. -e KEY=value)",
|
|
212
|
-
type: "array",
|
|
213
|
-
string: true,
|
|
214
|
-
nargs: 1
|
|
215
|
-
}).option("header", {
|
|
216
|
-
alias: "H",
|
|
217
|
-
describe: 'Set HTTP headers for SSE and HTTP transports (e.g. -H "X-Api-Key: abc123" -H "Authorization: Bearer abc123")',
|
|
218
|
-
type: "array",
|
|
219
|
-
string: true,
|
|
220
|
-
nargs: 1
|
|
221
|
-
}).option("timeout", {
|
|
222
|
-
describe: "Set connection timeout in milliseconds",
|
|
223
|
-
type: "number"
|
|
224
|
-
}).option("trust", {
|
|
225
|
-
describe: "Trust the server (bypass all tool call confirmation prompts)",
|
|
226
|
-
type: "boolean"
|
|
227
|
-
}).option("description", {
|
|
228
|
-
describe: "Set the description for the server",
|
|
229
|
-
type: "string"
|
|
230
|
-
}).option("include-tools", {
|
|
231
|
-
describe: "A comma-separated list of tools to include",
|
|
232
|
-
type: "array",
|
|
233
|
-
string: true
|
|
234
|
-
}).option("exclude-tools", {
|
|
235
|
-
describe: "A comma-separated list of tools to exclude",
|
|
236
|
-
type: "array",
|
|
237
|
-
string: true
|
|
238
|
-
}).option("oauth-client-id", {
|
|
239
|
-
describe: "OAuth client ID for MCP server authentication",
|
|
240
|
-
type: "string"
|
|
241
|
-
}).option("oauth-client-secret", {
|
|
242
|
-
describe: "OAuth client secret for MCP server authentication",
|
|
243
|
-
type: "string"
|
|
244
|
-
}).option("oauth-redirect-uri", {
|
|
245
|
-
describe: "OAuth redirect URI (e.g., https://your-server.com/oauth/callback). Defaults to localhost for local setups.",
|
|
246
|
-
type: "string"
|
|
247
|
-
}).option("oauth-authorization-url", {
|
|
248
|
-
describe: "OAuth authorization URL",
|
|
249
|
-
type: "string"
|
|
250
|
-
}).option("oauth-token-url", {
|
|
251
|
-
describe: "OAuth token URL",
|
|
252
|
-
type: "string"
|
|
253
|
-
}).option("oauth-scopes", {
|
|
254
|
-
describe: "OAuth scopes (comma-separated)",
|
|
255
|
-
type: "array",
|
|
256
|
-
string: true
|
|
257
|
-
}).middleware((argv) => {
|
|
258
|
-
if (argv["--"]) {
|
|
259
|
-
const existingArgs = argv["args"] || [];
|
|
260
|
-
argv["args"] = [...existingArgs, ...argv["--"]];
|
|
261
|
-
}
|
|
262
|
-
if (!argv["transport"]) {
|
|
263
|
-
const commandOrUrl = argv["commandOrUrl"];
|
|
264
|
-
if (commandOrUrl && /^https?:\/\//i.test(commandOrUrl)) {
|
|
265
|
-
argv["transport"] = "http";
|
|
266
|
-
} else {
|
|
267
|
-
argv["transport"] = "stdio";
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}), "builder"),
|
|
271
|
-
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
272
|
-
await addMcpServer(
|
|
273
|
-
argv["name"],
|
|
274
|
-
argv["commandOrUrl"],
|
|
275
|
-
argv["args"],
|
|
276
|
-
{
|
|
277
|
-
scope: argv["scope"],
|
|
278
|
-
transport: argv["transport"],
|
|
279
|
-
env: argv["env"],
|
|
280
|
-
header: argv["header"],
|
|
281
|
-
timeout: argv["timeout"],
|
|
282
|
-
trust: argv["trust"],
|
|
283
|
-
description: argv["description"],
|
|
284
|
-
includeTools: argv["includeTools"],
|
|
285
|
-
excludeTools: argv["excludeTools"],
|
|
286
|
-
oauthClientId: argv["oauthClientId"],
|
|
287
|
-
oauthClientSecret: argv["oauthClientSecret"],
|
|
288
|
-
oauthRedirectUri: argv["oauthRedirectUri"],
|
|
289
|
-
oauthAuthorizationUrl: argv["oauthAuthorizationUrl"],
|
|
290
|
-
oauthTokenUrl: argv["oauthTokenUrl"],
|
|
291
|
-
oauthScopes: argv["oauthScopes"]
|
|
292
|
-
}
|
|
293
|
-
);
|
|
294
|
-
}, "handler")
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// packages/cli/src/commands/mcp/remove.ts
|
|
298
|
-
init_esbuild_shims();
|
|
299
|
-
async function removeMcpServer(name, options) {
|
|
300
|
-
const { scope } = options;
|
|
301
|
-
const settingsScope = scope === "user" ? "User" /* User */ : "Workspace" /* Workspace */;
|
|
302
|
-
const settings = loadSettings();
|
|
303
|
-
const existingSettings = settings.forScope(settingsScope).settings;
|
|
304
|
-
const mcpServers = existingSettings.mcpServers || {};
|
|
305
|
-
if (!mcpServers[name]) {
|
|
306
|
-
writeStdoutLine(`Server "${name}" not found in ${scope} settings.`);
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
delete mcpServers[name];
|
|
310
|
-
settings.setValue(settingsScope, "mcpServers", mcpServers);
|
|
311
|
-
try {
|
|
312
|
-
const tokenStorage = new MCPOAuthTokenStorage();
|
|
313
|
-
await tokenStorage.deleteCredentials(name);
|
|
314
|
-
} catch {
|
|
315
|
-
}
|
|
316
|
-
writeStdoutLine(`Server "${name}" removed from ${scope} settings.`);
|
|
317
|
-
}
|
|
318
|
-
__name(removeMcpServer, "removeMcpServer");
|
|
319
|
-
var removeCommand = {
|
|
320
|
-
command: "remove <name>",
|
|
321
|
-
describe: "Remove a server",
|
|
322
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.usage("Usage: qwen mcp remove [options] <name>").positional("name", {
|
|
323
|
-
describe: "Name of the server",
|
|
324
|
-
type: "string",
|
|
325
|
-
demandOption: true
|
|
326
|
-
}).option("scope", {
|
|
327
|
-
alias: "s",
|
|
328
|
-
describe: "Configuration scope (user or project)",
|
|
329
|
-
type: "string",
|
|
330
|
-
default: "user",
|
|
331
|
-
choices: ["user", "project"]
|
|
332
|
-
}), "builder"),
|
|
333
|
-
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
334
|
-
await removeMcpServer(argv["name"], {
|
|
335
|
-
scope: argv["scope"]
|
|
336
|
-
});
|
|
337
|
-
}, "handler")
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
// packages/cli/src/commands/mcp/list.ts
|
|
341
|
-
init_esbuild_shims();
|
|
342
|
-
|
|
343
|
-
// packages/cli/src/config/mcpServers.ts
|
|
344
|
-
init_esbuild_shims();
|
|
345
|
-
|
|
346
|
-
// packages/cli/src/config/mcpJson.ts
|
|
347
|
-
init_esbuild_shims();
|
|
348
|
-
import * as fs from "node:fs";
|
|
349
|
-
import * as path from "node:path";
|
|
350
|
-
var import_strip_json_comments = __toESM(require_strip_json_comments(), 1);
|
|
351
|
-
var PROJECT_MCP_FILENAME = ".mcp.json";
|
|
352
|
-
function loadProjectMcpServers(projectRoot) {
|
|
353
|
-
const filePath = path.join(projectRoot, PROJECT_MCP_FILENAME);
|
|
354
|
-
let raw;
|
|
355
|
-
try {
|
|
356
|
-
raw = fs.readFileSync(filePath, "utf-8");
|
|
357
|
-
} catch {
|
|
358
|
-
return { servers: {}, path: void 0, errors: [] };
|
|
359
|
-
}
|
|
360
|
-
let parsed;
|
|
361
|
-
try {
|
|
362
|
-
parsed = JSON.parse((0, import_strip_json_comments.default)(raw));
|
|
363
|
-
} catch (e) {
|
|
364
|
-
return {
|
|
365
|
-
servers: {},
|
|
366
|
-
path: filePath,
|
|
367
|
-
errors: [`Failed to parse ${filePath}: ${e.message}`]
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
const mcpServers = parsed?.mcpServers;
|
|
371
|
-
if (!mcpServers || typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
|
|
372
|
-
return {
|
|
373
|
-
servers: {},
|
|
374
|
-
path: filePath,
|
|
375
|
-
errors: [`${filePath} has no "mcpServers" object`]
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
const servers = /* @__PURE__ */ Object.create(null);
|
|
379
|
-
const errors = [];
|
|
380
|
-
for (const [name, value] of Object.entries(
|
|
381
|
-
mcpServers
|
|
382
|
-
)) {
|
|
383
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
384
|
-
errors.push(`${filePath}: server "${name}" is not an object \u2014 skipped`);
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
servers[name] = {
|
|
388
|
-
...normalizeClaudeMcpServer(value),
|
|
389
|
-
scope: "project"
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
return { servers, path: filePath, errors };
|
|
393
|
-
}
|
|
394
|
-
__name(loadProjectMcpServers, "loadProjectMcpServers");
|
|
395
|
-
|
|
396
|
-
// packages/cli/src/config/mcpServers.ts
|
|
397
|
-
function assembleMcpServers(mergedSettingsServers, cwd, cliMcpServers) {
|
|
398
|
-
const belowProject = {};
|
|
399
|
-
const aboveProject = {};
|
|
400
|
-
for (const [name, config] of Object.entries(mergedSettingsServers ?? {})) {
|
|
401
|
-
if (config.scope === "workspace" || config.scope === "system") {
|
|
402
|
-
aboveProject[name] = config;
|
|
403
|
-
} else {
|
|
404
|
-
belowProject[name] = config;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
const projectResult = loadProjectMcpServers(cwd);
|
|
408
|
-
for (const error of projectResult.errors) {
|
|
409
|
-
writeStderrLine(`Warning: ${error}`);
|
|
410
|
-
}
|
|
411
|
-
return {
|
|
412
|
-
...belowProject,
|
|
413
|
-
...projectResult.servers,
|
|
414
|
-
...aboveProject,
|
|
415
|
-
...cliMcpServers ?? {}
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
__name(assembleMcpServers, "assembleMcpServers");
|
|
419
|
-
|
|
420
|
-
// packages/cli/src/config/mcpApprovals.ts
|
|
421
|
-
init_esbuild_shims();
|
|
422
|
-
import * as fs2 from "node:fs";
|
|
423
|
-
import * as path2 from "node:path";
|
|
424
|
-
var import_strip_json_comments2 = __toESM(require_strip_json_comments(), 1);
|
|
425
|
-
var MCP_APPROVALS_FILENAME = "mcpApprovals.json";
|
|
426
|
-
function getMcpApprovalsPath() {
|
|
427
|
-
if (process.env["QWEN_CODE_MCP_APPROVALS_PATH"]) {
|
|
428
|
-
return process.env["QWEN_CODE_MCP_APPROVALS_PATH"];
|
|
429
|
-
}
|
|
430
|
-
return path2.join(Storage.getGlobalQwenDir(), MCP_APPROVALS_FILENAME);
|
|
431
|
-
}
|
|
432
|
-
__name(getMcpApprovalsPath, "getMcpApprovalsPath");
|
|
433
|
-
function normalizeProjectRoot(projectRoot) {
|
|
434
|
-
return path2.resolve(projectRoot);
|
|
435
|
-
}
|
|
436
|
-
__name(normalizeProjectRoot, "normalizeProjectRoot");
|
|
437
|
-
var LoadedMcpApprovals = class {
|
|
438
|
-
constructor(file, errors) {
|
|
439
|
-
this.file = file;
|
|
440
|
-
this.errors = errors;
|
|
441
|
-
}
|
|
442
|
-
static {
|
|
443
|
-
__name(this, "LoadedMcpApprovals");
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Live approval state for a project server. Returns `pending` when there is no
|
|
447
|
-
* stored decision OR when the stored decision was bound to a different config
|
|
448
|
-
* hash (i.e. `.mcp.json` changed since approval). This is the hash-binding
|
|
449
|
-
* that makes a config edit require re-approval.
|
|
450
|
-
*/
|
|
451
|
-
getState(projectRoot, serverName, config) {
|
|
452
|
-
const record = this.file.config[normalizeProjectRoot(projectRoot)]?.[serverName];
|
|
453
|
-
if (!record) {
|
|
454
|
-
return "pending";
|
|
455
|
-
}
|
|
456
|
-
if (record.hash !== hashMcpServerConfig(config)) {
|
|
457
|
-
return "pending";
|
|
458
|
-
}
|
|
459
|
-
return record.status;
|
|
460
|
-
}
|
|
461
|
-
/** Persist an approve/reject decision bound to the current config hash. */
|
|
462
|
-
async setState(projectRoot, serverName, config, status) {
|
|
463
|
-
const root = normalizeProjectRoot(projectRoot);
|
|
464
|
-
const existing = this.file.config[root];
|
|
465
|
-
const project = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : /* @__PURE__ */ Object.create(null);
|
|
466
|
-
Object.defineProperty(project, serverName, {
|
|
467
|
-
value: { hash: hashMcpServerConfig(config), status },
|
|
468
|
-
enumerable: true,
|
|
469
|
-
configurable: true,
|
|
470
|
-
writable: true
|
|
471
|
-
});
|
|
472
|
-
this.file.config[root] = project;
|
|
473
|
-
await saveMcpApprovals(this.file);
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
var loadedMcpApprovals;
|
|
477
|
-
function loadMcpApprovals() {
|
|
478
|
-
if (loadedMcpApprovals) {
|
|
479
|
-
return loadedMcpApprovals;
|
|
480
|
-
}
|
|
481
|
-
const errors = [];
|
|
482
|
-
let config = {};
|
|
483
|
-
const filePath = getMcpApprovalsPath();
|
|
484
|
-
try {
|
|
485
|
-
if (fs2.existsSync(filePath)) {
|
|
486
|
-
const content = fs2.readFileSync(filePath, "utf-8");
|
|
487
|
-
const parsed = JSON.parse((0, import_strip_json_comments2.default)(content));
|
|
488
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
489
|
-
errors.push({
|
|
490
|
-
message: "MCP approvals file is not a valid JSON object.",
|
|
491
|
-
path: filePath
|
|
492
|
-
});
|
|
493
|
-
} else {
|
|
494
|
-
config = parsed;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
} catch (error) {
|
|
498
|
-
errors.push({ message: getErrorMessage(error), path: filePath });
|
|
499
|
-
}
|
|
500
|
-
loadedMcpApprovals = new LoadedMcpApprovals(
|
|
501
|
-
{ path: filePath, config },
|
|
502
|
-
errors
|
|
503
|
-
);
|
|
504
|
-
for (const error of errors) {
|
|
505
|
-
writeStderrLine(`Warning: MCP approvals file error: ${error.message}`);
|
|
506
|
-
}
|
|
507
|
-
return loadedMcpApprovals;
|
|
508
|
-
}
|
|
509
|
-
__name(loadMcpApprovals, "loadMcpApprovals");
|
|
510
|
-
function getPendingGatedMcpServers(mcpServers, projectRoot) {
|
|
511
|
-
const approvals = loadMcpApprovals();
|
|
512
|
-
const pending = [];
|
|
513
|
-
for (const [name, config] of Object.entries(mcpServers)) {
|
|
514
|
-
if (!isGatedMcpScope(config.scope)) {
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
if (approvals.getState(projectRoot, name, config) !== "approved") {
|
|
518
|
-
pending.push(name);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
return pending;
|
|
522
|
-
}
|
|
523
|
-
__name(getPendingGatedMcpServers, "getPendingGatedMcpServers");
|
|
524
|
-
function getPromptableMcpServers(mcpServers, projectRoot) {
|
|
525
|
-
const approvals = loadMcpApprovals();
|
|
526
|
-
const promptable = [];
|
|
527
|
-
for (const [name, config] of Object.entries(mcpServers)) {
|
|
528
|
-
if (!isGatedMcpScope(config.scope)) {
|
|
529
|
-
continue;
|
|
530
|
-
}
|
|
531
|
-
if (approvals.getState(projectRoot, name, config) === "pending") {
|
|
532
|
-
promptable.push(name);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return promptable;
|
|
536
|
-
}
|
|
537
|
-
__name(getPromptableMcpServers, "getPromptableMcpServers");
|
|
538
|
-
async function saveMcpApprovals(file) {
|
|
539
|
-
try {
|
|
540
|
-
const dirPath = path2.dirname(file.path);
|
|
541
|
-
if (!fs2.existsSync(dirPath)) {
|
|
542
|
-
fs2.mkdirSync(dirPath, { recursive: true });
|
|
543
|
-
}
|
|
544
|
-
await atomicWriteFile(file.path, JSON.stringify(file.config, null, 2), {
|
|
545
|
-
mode: 384
|
|
546
|
-
});
|
|
547
|
-
} catch (error) {
|
|
548
|
-
writeStderrLine("Error saving MCP approvals file.");
|
|
549
|
-
writeStderrLine(error instanceof Error ? error.message : String(error));
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
__name(saveMcpApprovals, "saveMcpApprovals");
|
|
553
|
-
|
|
554
|
-
// packages/cli/src/commands/mcp/list.ts
|
|
555
|
-
var COLOR_GREEN = "\x1B[32m";
|
|
556
|
-
var COLOR_YELLOW = "\x1B[33m";
|
|
557
|
-
var COLOR_RED = "\x1B[31m";
|
|
558
|
-
var RESET_COLOR = "\x1B[0m";
|
|
559
|
-
async function getMcpServersFromConfig() {
|
|
560
|
-
const settings = loadSettings();
|
|
561
|
-
const extensionManager = new ExtensionManager({
|
|
562
|
-
isWorkspaceTrusted: isWorkspaceTrusted(settings.merged).isTrusted ?? true,
|
|
563
|
-
telemetrySettings: settings.merged.telemetry,
|
|
564
|
-
locale: getCurrentLanguage()
|
|
565
|
-
});
|
|
566
|
-
await extensionManager.refreshCache();
|
|
567
|
-
const extensions = extensionManager.getLoadedExtensions();
|
|
568
|
-
const mcpServers = assembleMcpServers(
|
|
569
|
-
settings.merged.mcpServers,
|
|
570
|
-
process.cwd()
|
|
571
|
-
);
|
|
572
|
-
for (const extension of extensions) {
|
|
573
|
-
if (extension.isActive) {
|
|
574
|
-
Object.entries(extension.config.mcpServers || {}).forEach(
|
|
575
|
-
([key, server]) => {
|
|
576
|
-
if (mcpServers[key]) {
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
mcpServers[key] = {
|
|
580
|
-
...server,
|
|
581
|
-
extensionName: extension.config.name
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
return mcpServers;
|
|
588
|
-
}
|
|
589
|
-
__name(getMcpServersFromConfig, "getMcpServersFromConfig");
|
|
590
|
-
async function testMCPConnection(serverName, config) {
|
|
591
|
-
const client = new Client({
|
|
592
|
-
name: "mcp-test-client",
|
|
593
|
-
version: "0.0.1"
|
|
594
|
-
});
|
|
595
|
-
let transport;
|
|
596
|
-
try {
|
|
597
|
-
transport = await createTransport(serverName, config, false);
|
|
598
|
-
} catch (_error) {
|
|
599
|
-
await client.close();
|
|
600
|
-
return "disconnected" /* DISCONNECTED */;
|
|
601
|
-
}
|
|
602
|
-
try {
|
|
603
|
-
await client.connect(transport, { timeout: 5e3 });
|
|
604
|
-
await client.ping();
|
|
605
|
-
await client.close();
|
|
606
|
-
return "connected" /* CONNECTED */;
|
|
607
|
-
} catch (_error) {
|
|
608
|
-
await transport.close();
|
|
609
|
-
return "disconnected" /* DISCONNECTED */;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
__name(testMCPConnection, "testMCPConnection");
|
|
613
|
-
async function getServerStatus(serverName, server) {
|
|
614
|
-
return await testMCPConnection(serverName, server);
|
|
615
|
-
}
|
|
616
|
-
__name(getServerStatus, "getServerStatus");
|
|
617
|
-
async function listMcpServers() {
|
|
618
|
-
const mcpServers = await getMcpServersFromConfig();
|
|
619
|
-
const serverNames = Object.keys(mcpServers);
|
|
620
|
-
if (serverNames.length === 0) {
|
|
621
|
-
writeStdoutLine("No MCP servers configured.");
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
writeStdoutLine("Configured MCP servers:\n");
|
|
625
|
-
const cwd = process.cwd();
|
|
626
|
-
let approvals;
|
|
627
|
-
for (const serverName of serverNames) {
|
|
628
|
-
const server = mcpServers[serverName];
|
|
629
|
-
let serverInfo = `${serverName}: `;
|
|
630
|
-
if (server.httpUrl) {
|
|
631
|
-
serverInfo += `${server.httpUrl} (http)`;
|
|
632
|
-
} else if (server.url) {
|
|
633
|
-
serverInfo += `${server.url} (sse)`;
|
|
634
|
-
} else if (server.command) {
|
|
635
|
-
serverInfo += `${server.command} ${server.args?.join(" ") || ""} (stdio)`;
|
|
636
|
-
}
|
|
637
|
-
if (isGatedMcpScope(server.scope)) {
|
|
638
|
-
approvals ??= loadMcpApprovals();
|
|
639
|
-
const state = approvals.getState(cwd, serverName, server);
|
|
640
|
-
if (state !== "approved") {
|
|
641
|
-
const statusText2 = state === "rejected" ? "Rejected" : "Pending approval";
|
|
642
|
-
writeStdoutLine(
|
|
643
|
-
`${COLOR_YELLOW}\u25CF${RESET_COLOR} ${serverInfo} - ${statusText2}`
|
|
644
|
-
);
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
const status = await getServerStatus(serverName, server);
|
|
649
|
-
let statusIndicator = "";
|
|
650
|
-
let statusText = "";
|
|
651
|
-
switch (status) {
|
|
652
|
-
case "connected" /* CONNECTED */:
|
|
653
|
-
statusIndicator = COLOR_GREEN + "\u2713" + RESET_COLOR;
|
|
654
|
-
statusText = "Connected";
|
|
655
|
-
break;
|
|
656
|
-
case "connecting" /* CONNECTING */:
|
|
657
|
-
statusIndicator = COLOR_YELLOW + "\u2026" + RESET_COLOR;
|
|
658
|
-
statusText = "Connecting";
|
|
659
|
-
break;
|
|
660
|
-
case "disconnected" /* DISCONNECTED */:
|
|
661
|
-
default:
|
|
662
|
-
statusIndicator = COLOR_RED + "\u2717" + RESET_COLOR;
|
|
663
|
-
statusText = "Disconnected";
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
writeStdoutLine(`${statusIndicator} ${serverInfo} - ${statusText}`);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
__name(listMcpServers, "listMcpServers");
|
|
670
|
-
var listCommand = {
|
|
671
|
-
command: "list",
|
|
672
|
-
describe: "List all configured MCP servers",
|
|
673
|
-
handler: /* @__PURE__ */ __name(async () => {
|
|
674
|
-
await listMcpServers();
|
|
675
|
-
}, "handler")
|
|
676
|
-
};
|
|
677
|
-
|
|
678
|
-
// packages/cli/src/commands/mcp/reconnect.ts
|
|
679
|
-
init_esbuild_shims();
|
|
680
|
-
async function getMcpServersFromConfig2(extensionManager) {
|
|
681
|
-
const settings = loadSettings();
|
|
682
|
-
const extManager = extensionManager ?? new ExtensionManager({
|
|
683
|
-
isWorkspaceTrusted: isWorkspaceTrusted(settings.merged).isTrusted ?? true,
|
|
684
|
-
telemetrySettings: settings.merged.telemetry,
|
|
685
|
-
locale: getCurrentLanguage()
|
|
686
|
-
});
|
|
687
|
-
if (!extensionManager) {
|
|
688
|
-
await extManager.refreshCache();
|
|
689
|
-
}
|
|
690
|
-
const extensions = extManager.getLoadedExtensions();
|
|
691
|
-
const mcpServers = assembleMcpServers(
|
|
692
|
-
settings.merged.mcpServers,
|
|
693
|
-
process.cwd()
|
|
694
|
-
);
|
|
695
|
-
for (const extension of extensions) {
|
|
696
|
-
if (extension.isActive) {
|
|
697
|
-
Object.entries(extension.config.mcpServers || {}).forEach(
|
|
698
|
-
([key, server]) => {
|
|
699
|
-
if (mcpServers[key]) {
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
mcpServers[key] = {
|
|
703
|
-
...server,
|
|
704
|
-
extensionName: extension.config.name
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
return mcpServers;
|
|
711
|
-
}
|
|
712
|
-
__name(getMcpServersFromConfig2, "getMcpServersFromConfig");
|
|
713
|
-
async function createMinimalConfig() {
|
|
714
|
-
const settings = loadSettings();
|
|
715
|
-
const cwd = process.cwd();
|
|
716
|
-
const fileFiltering = settings.merged.context?.fileFiltering;
|
|
717
|
-
const fileService = new FileDiscoveryService(
|
|
718
|
-
cwd,
|
|
719
|
-
fileFiltering?.customIgnoreFiles
|
|
720
|
-
);
|
|
721
|
-
const mcpServers = await getMcpServersFromConfig2();
|
|
722
|
-
const config = new Config({
|
|
723
|
-
sessionId: "mcp-reconnect",
|
|
724
|
-
targetDir: cwd,
|
|
725
|
-
cwd,
|
|
726
|
-
debugMode: false,
|
|
727
|
-
mcpServers,
|
|
728
|
-
pendingMcpServers: getPendingGatedMcpServers(mcpServers, cwd),
|
|
729
|
-
fileDiscoveryService: fileService,
|
|
730
|
-
mcpServerCommand: settings.merged.mcp?.serverCommand,
|
|
731
|
-
...fileFiltering !== void 0 ? { fileFiltering } : {}
|
|
732
|
-
});
|
|
733
|
-
await config.initialize();
|
|
734
|
-
return config;
|
|
735
|
-
}
|
|
736
|
-
__name(createMinimalConfig, "createMinimalConfig");
|
|
737
|
-
function createReconnectError(message, exitCode = 1) {
|
|
738
|
-
const error = new Error(message);
|
|
739
|
-
error.exitCode = exitCode;
|
|
740
|
-
return error;
|
|
741
|
-
}
|
|
742
|
-
__name(createReconnectError, "createReconnectError");
|
|
743
|
-
async function reconnectMcpServer(serverName) {
|
|
744
|
-
const mcpServers = await getMcpServersFromConfig2();
|
|
745
|
-
if (!mcpServers[serverName]) {
|
|
746
|
-
throw createReconnectError(
|
|
747
|
-
`Error: Server "${serverName}" not found in configuration.`
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
|
-
writeStdoutLine(`Reconnecting to server "${serverName}"...`);
|
|
751
|
-
try {
|
|
752
|
-
const config = await createMinimalConfig();
|
|
753
|
-
const toolRegistry = config.getToolRegistry();
|
|
754
|
-
await toolRegistry.discoverToolsForServer(serverName);
|
|
755
|
-
writeStdoutLine(`Successfully reconnected to server "${serverName}".`);
|
|
756
|
-
await config.shutdown();
|
|
757
|
-
} catch (error) {
|
|
758
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
759
|
-
throw createReconnectError(
|
|
760
|
-
`Failed to reconnect to server "${serverName}": ${message}`
|
|
761
|
-
);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
__name(reconnectMcpServer, "reconnectMcpServer");
|
|
765
|
-
async function reconnectAllMcpServers() {
|
|
766
|
-
const settings = loadSettings();
|
|
767
|
-
const extensionManager = new ExtensionManager({
|
|
768
|
-
isWorkspaceTrusted: isWorkspaceTrusted(settings.merged).isTrusted ?? true,
|
|
769
|
-
telemetrySettings: settings.merged.telemetry,
|
|
770
|
-
locale: getCurrentLanguage()
|
|
771
|
-
});
|
|
772
|
-
await extensionManager.refreshCache();
|
|
773
|
-
const mcpServers = await getMcpServersFromConfig2(extensionManager);
|
|
774
|
-
const serverNames = Object.keys(mcpServers);
|
|
775
|
-
if (serverNames.length === 0) {
|
|
776
|
-
writeStdoutLine("No MCP servers configured.");
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
writeStdoutLine("Reconnecting to all MCP servers...\n");
|
|
780
|
-
let config;
|
|
781
|
-
try {
|
|
782
|
-
config = await createMinimalConfig();
|
|
783
|
-
const toolRegistry = config.getToolRegistry();
|
|
784
|
-
for (const serverName of serverNames) {
|
|
785
|
-
try {
|
|
786
|
-
await toolRegistry.discoverToolsForServer(serverName);
|
|
787
|
-
writeStdoutLine(`\u2713 ${serverName}: Reconnected successfully`);
|
|
788
|
-
} catch (error) {
|
|
789
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
790
|
-
writeStdoutLine(`\u2717 ${serverName}: Failed - ${message}`);
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
} finally {
|
|
794
|
-
if (config) {
|
|
795
|
-
await config.shutdown();
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
__name(reconnectAllMcpServers, "reconnectAllMcpServers");
|
|
800
|
-
var reconnectCommand = {
|
|
801
|
-
command: "reconnect [server-name]",
|
|
802
|
-
describe: "Reconnect MCP server(s)",
|
|
803
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.usage("Usage: qwen mcp reconnect [options] [server-name]").positional("server-name", {
|
|
804
|
-
describe: "Name of the server to reconnect",
|
|
805
|
-
type: "string"
|
|
806
|
-
}).option("all", {
|
|
807
|
-
alias: "a",
|
|
808
|
-
describe: "Reconnect all configured servers",
|
|
809
|
-
type: "boolean",
|
|
810
|
-
default: false
|
|
811
|
-
}).conflicts("server-name", "all").check((argv) => {
|
|
812
|
-
const serverName = argv["server-name"];
|
|
813
|
-
const all = argv["all"];
|
|
814
|
-
if (!serverName && !all) {
|
|
815
|
-
throw new Error(
|
|
816
|
-
"Please specify a server name or use --all to reconnect all servers."
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
return true;
|
|
820
|
-
}), "builder"),
|
|
821
|
-
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
822
|
-
const serverName = argv["server-name"];
|
|
823
|
-
const all = argv["all"];
|
|
824
|
-
try {
|
|
825
|
-
if (all) {
|
|
826
|
-
await reconnectAllMcpServers();
|
|
827
|
-
} else if (serverName) {
|
|
828
|
-
await reconnectMcpServer(serverName);
|
|
829
|
-
}
|
|
830
|
-
} catch (error) {
|
|
831
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
832
|
-
const exitCode = error?.exitCode ?? 1;
|
|
833
|
-
writeStderrLine(message);
|
|
834
|
-
process.exit(exitCode);
|
|
835
|
-
}
|
|
836
|
-
}, "handler")
|
|
837
|
-
};
|
|
838
|
-
|
|
839
|
-
// packages/cli/src/commands/mcp/approve.ts
|
|
840
|
-
init_esbuild_shims();
|
|
841
|
-
function loadGatedServers(cwd) {
|
|
842
|
-
const settings = loadSettings(cwd);
|
|
843
|
-
const all = assembleMcpServers(settings.merged.mcpServers, cwd);
|
|
844
|
-
const gated = {};
|
|
845
|
-
for (const [serverName, config] of Object.entries(all)) {
|
|
846
|
-
if (isGatedMcpScope(config.scope)) {
|
|
847
|
-
gated[serverName] = config;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
return gated;
|
|
851
|
-
}
|
|
852
|
-
__name(loadGatedServers, "loadGatedServers");
|
|
853
|
-
async function setProjectServerStatus(name, status, all) {
|
|
854
|
-
const cwd = process.cwd();
|
|
855
|
-
const servers = loadGatedServers(cwd);
|
|
856
|
-
const names = Object.keys(servers);
|
|
857
|
-
if (names.length === 0) {
|
|
858
|
-
writeStdoutLine(
|
|
859
|
-
"No approval-requiring MCP servers found (looked in .mcp.json and .qwen/settings.json)."
|
|
860
|
-
);
|
|
861
|
-
return;
|
|
862
|
-
}
|
|
863
|
-
const verb = status === "approved" ? "Approved" : "Rejected";
|
|
864
|
-
const approvals = loadMcpApprovals();
|
|
865
|
-
const targets = all ? names : name ? [name] : [];
|
|
866
|
-
if (targets.length === 0) {
|
|
867
|
-
writeStdoutLine("Specify a server name or pass --all.");
|
|
868
|
-
return;
|
|
869
|
-
}
|
|
870
|
-
for (const target of targets) {
|
|
871
|
-
const config = servers[target];
|
|
872
|
-
if (!config) {
|
|
873
|
-
writeStdoutLine(
|
|
874
|
-
`Server "${target}" not found. Available: ${names.join(", ")}`
|
|
875
|
-
);
|
|
876
|
-
continue;
|
|
877
|
-
}
|
|
878
|
-
await approvals.setState(cwd, target, config, status);
|
|
879
|
-
writeStdoutLine(
|
|
880
|
-
`${verb} MCP server "${target}" (bound to its current config).`
|
|
881
|
-
);
|
|
882
|
-
}
|
|
883
|
-
if (status === "approved") {
|
|
884
|
-
writeStdoutLine(
|
|
885
|
-
"Approved servers connect in your next interactive session."
|
|
886
|
-
);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
__name(setProjectServerStatus, "setProjectServerStatus");
|
|
890
|
-
var approveCommand = {
|
|
891
|
-
command: "approve [name]",
|
|
892
|
-
describe: "Approve a gated MCP server (.mcp.json or workspace .qwen/settings.json)",
|
|
893
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.usage("Usage: qwen mcp approve [options] [name]").positional("name", {
|
|
894
|
-
describe: "Name of the gated server to approve",
|
|
895
|
-
type: "string"
|
|
896
|
-
}).option("all", {
|
|
897
|
-
describe: "Approve all gated servers in this workspace",
|
|
898
|
-
type: "boolean",
|
|
899
|
-
default: false
|
|
900
|
-
}), "builder"),
|
|
901
|
-
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
902
|
-
await setProjectServerStatus(
|
|
903
|
-
argv["name"],
|
|
904
|
-
"approved",
|
|
905
|
-
argv["all"]
|
|
906
|
-
);
|
|
907
|
-
}, "handler")
|
|
908
|
-
};
|
|
909
|
-
var rejectCommand = {
|
|
910
|
-
command: "reject [name]",
|
|
911
|
-
describe: "Reject a gated MCP server (.mcp.json or workspace .qwen/settings.json)",
|
|
912
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.usage("Usage: qwen mcp reject [options] [name]").positional("name", {
|
|
913
|
-
describe: "Name of the gated server to reject",
|
|
914
|
-
type: "string"
|
|
915
|
-
}).option("all", {
|
|
916
|
-
describe: "Reject all gated servers in this workspace",
|
|
917
|
-
type: "boolean",
|
|
918
|
-
default: false
|
|
919
|
-
}), "builder"),
|
|
920
|
-
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
921
|
-
await setProjectServerStatus(
|
|
922
|
-
argv["name"],
|
|
923
|
-
"rejected",
|
|
924
|
-
argv["all"]
|
|
925
|
-
);
|
|
926
|
-
}, "handler")
|
|
927
|
-
};
|
|
928
|
-
|
|
929
|
-
// packages/cli/src/commands/mcp.ts
|
|
930
|
-
var mcpCommand = {
|
|
931
|
-
command: "mcp",
|
|
932
|
-
describe: "Manage MCP servers",
|
|
933
|
-
builder: /* @__PURE__ */ __name((yargs) => yargs.command(addCommand).command(removeCommand).command(listCommand).command(reconnectCommand).command(approveCommand).command(rejectCommand).demandCommand(1, "You need at least one command before continuing.").version(false), "builder"),
|
|
934
|
-
handler: /* @__PURE__ */ __name(() => {
|
|
935
|
-
}, "handler")
|
|
936
|
-
};
|
|
937
|
-
|
|
938
|
-
export {
|
|
939
|
-
assembleMcpServers,
|
|
940
|
-
loadMcpApprovals,
|
|
941
|
-
getPendingGatedMcpServers,
|
|
942
|
-
getPromptableMcpServers,
|
|
943
|
-
mcpCommand
|
|
944
|
-
};
|
|
945
|
-
/**
|
|
946
|
-
* @license
|
|
947
|
-
* Copyright 2025 Google LLC
|
|
948
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
949
|
-
*/
|