Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/loud-rings-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@arkts/mcp": patch
---

feat: update README
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@
"cfworker",
"cppjieba",
"harmonyos",
"LOCALAPPDATA",
"minisearch",
"modelcontextprotocol",
"Naily",
"nodejieba",
"ohosvscode",
"vstils"
]
}
146 changes: 145 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,147 @@
# ArkTS MCP Server

ArkTS MCP 服务器,正在开发中。
面向 [ArkTS](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts) 的 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 服务器,可在 Cursor 等 AI 工具中提供 HarmonyOS / OpenHarmony 文档检索等能力。

## 功能

- 启动标准 MCP stdio 服务,供编辑器与 Agent 调用
- 提供 HarmonyOS 开发者文档目录检索工具 `docs_get_catalog_tree`
- 支持中文 / 英文目录
- 支持全文搜索与完整目录获取

## 安装

### 独立可执行文件(推荐)

从 [GitHub Releases](https://github.com/ohosvscode/mcp/releases) 下载对应平台压缩包,或使用安装脚本。

**macOS / Linux**

国内网络(jsDelivr 镜像,推荐):

```bash
curl -fsSL https://cdn.jsdelivr.net/gh/ohosvscode/mcp@main/install.sh | bash
```

官方源:

```bash
curl -fsSL https://raw.githubusercontent.com/ohosvscode/mcp/main/install.sh | bash
```

**Windows (PowerShell)**

国内网络(jsDelivr 镜像,推荐):

```powershell
irm https://cdn.jsdelivr.net/gh/ohosvscode/mcp@main/install.ps1 | iex
```

官方源:

```powershell
irm https://raw.githubusercontent.com/ohosvscode/mcp/main/install.ps1 | iex
```

> 安装脚本本身可通过 jsDelivr 加速获取;Release 中的可执行文件压缩包仍从 GitHub Releases 下载。若下载 Release 较慢,可手动从 [Releases 页面](https://github.com/ohosvscode/mcp/releases) 选择对应平台 zip 后解压,再执行 `arkts-mcp` 或使用 `--no-global` / `-NoGlobal` 仅本地安装。

安装脚本会:

1. 自动检测平台(`darwin-x64`、`darwin-arm64`、`linux-x64`、`linux-arm64`、`win-x64`、`win-arm64`)
2. 下载最新 Release 压缩包(含 pre-release)
3. 解压到当前目录
4. 注册全局命令 `arkts-mcp`

可选参数:

```bash
./install.sh --version 0.0.1-alpha.2
./install.sh --dir ~/apps/arkts-mcp --no-global
```

```powershell
.\install.ps1 -Version 0.0.1-alpha.2
.\install.ps1 -Dir "$env:LOCALAPPDATA\arkts-mcp" -NoGlobal
```

### npm

```bash
pnpm add -g @arkts/mcp
# 或
npx @arkts/mcp
```

## 在 Cursor 中使用

在 MCP 配置中加入 `arkts-mcp`:

```json
{
"mcpServers": {
"arkts": {
"command": "arkts-mcp"
}
}
}
```

若使用 npm 安装且命令不在 PATH 中,可改为:

```json
{
"mcpServers": {
"arkts": {
"command": "npx",
"args": ["@arkts/mcp"]
}
}
}
```

本地开发时可指向构建产物:

```json
{
"mcpServers": {
"arkts": {
"command": "node",
"args": ["dist/bin.mjs"]
}
}
}
```

## CLI

| 命令 | 说明 |
| --- | --- |
| `arkts-mcp` | 启动 MCP 服务器(stdio) |
| `arkts-mcp update` | 更新到最新 Release |
| `arkts-mcp update --version <version>` | 更新到指定版本 |
| `arkts-mcp uninstall` | 卸载全局命令并删除安装文件 |
| `arkts-mcp --help` | 查看帮助 |
| `arkts-mcp --version` | 查看版本 |

`update` / `uninstall` 仅适用于通过 `install.sh` / `install.ps1` 安装的独立可执行文件。

## 开发

环境要求见 [package.json](./package.json) 中的 `packageManager` 与 [.node-version](./.node-version)。

```bash
pnpm install
pnpm build # 构建 npm 包,输出到 dist/
pnpm build --build-exe # 同时构建独立可执行文件,输出到 target/
pnpm test # 运行测试
```

独立可执行文件构建完成后,产物位于 `target/`,包含:

- `arkts-mcp`(Windows 为 `arkts-mcp.exe`)
- `lib/`(原生依赖,如 nodejieba)
- `assets/`(如图标等资源)

## 许可证

[MIT](./LICENSE)
199 changes: 199 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#Requires -Version 5.1
[CmdletBinding()]
param(
[string] $Dir = (Get-Location).Path,
[string] $Version = '',
[switch] $NoGlobal
)

$ErrorActionPreference = 'Stop'

$Repo = 'ohosvscode/mcp'
$BinaryName = 'arkts-mcp.exe'
$GithubApi = "https://api.github.com/repos/$Repo"
$Headers = @{
'Accept' = 'application/vnd.github+json'
'User-Agent' = 'arkts-mcp-installer'
}

function Write-Usage {
@"
Usage: .\install.ps1 [options]

Download the arkts-mcp executable for this platform, extract it here, and register it globally.

Options:
-Dir DIR Install directory (default: current directory)
-Version TAG Release tag or version (default: latest release)
-NoGlobal Do not add the install directory to the user PATH

Examples:
irm https://cdn.jsdelivr.net/gh/$Repo/main/install.ps1 | iex
irm https://raw.githubusercontent.com/$Repo/main/install.ps1 | iex
.\install.ps1 -Version 0.0.1-alpha.2
"@
}

function Get-PlatformArtifact {
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
switch ($arch) {
'Arm64' { return 'win-arm64' }
'X64' { return 'win-x64' }
default { throw "Unsupported Windows architecture: $arch" }
}
}

function Get-ReleaseJson {
param([string] $VersionTag)

if ([string]::IsNullOrWhiteSpace($VersionTag)) {
try {
return Invoke-RestMethod -Uri "$GithubApi/releases/latest" -Headers $Headers
}
catch {
$releases = @(Invoke-RestMethod -Uri "$GithubApi/releases?per_page=1" -Headers $Headers)
if ($releases.Count -eq 0) {
throw 'No releases found'
}
return $releases[0]
}
}

$normalized = $VersionTag.TrimStart('v')
$normalized = $normalized -replace '^@arkts/mcp@', ''
$candidates = @(
$VersionTag,
"v$normalized",
"@arkts/mcp@$normalized"
)

foreach ($candidate in $candidates) {
try {
return Invoke-RestMethod -Uri "$GithubApi/releases/tags/$candidate" -Headers $Headers
}
catch {
continue
}
}

throw "Release not found for version: $VersionTag"
}

function Get-ReleaseAsset {
param(
[object] $Release,
[string] $Platform
)

$asset = $Release.assets | Where-Object { $_.name -match "^$([regex]::Escape($Platform))-.*\.zip$" } | Select-Object -First 1
if (-not $asset) {
throw "No release asset found for platform: $Platform"
}
return $asset
}

function Save-FileWithProgress {
param(
[string] $Url,
[string] $Destination
)

Write-Host 'Downloading...'

if (Get-Command curl.exe -ErrorAction SilentlyContinue) {
& curl.exe -fL --progress-bar -o $Destination $Url
if ($LASTEXITCODE -ne 0) {
throw "Download failed: $Url"
}
return
}

$request = [System.Net.HttpWebRequest]::Create($Url)
$request.UserAgent = 'arkts-mcp-installer'
$request.AllowAutoRedirect = $true
$response = $request.GetResponse()
$total = $response.ContentLength
$stream = $response.GetResponseStream()
$fileStream = [System.IO.File]::Open($Destination, [System.IO.FileMode]::Create)
$buffer = New-Object byte[] 8192
$read = 0
$downloaded = 0L

while (($read = $stream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$fileStream.Write($buffer, 0, $read)
$downloaded += $read
if ($total -gt 0) {
$percent = [math]::Floor(($downloaded * 100) / $total)
Write-Progress -Activity 'Downloading arkts-mcp' -Status "$downloaded / $total bytes" -PercentComplete $percent
}
}

Write-Progress -Activity 'Downloading arkts-mcp' -Completed
$fileStream.Close()
$stream.Close()
$response.Close()
}

function Install-GlobalCommand {
param([string] $InstallDirectory)

$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$normalizedInstall = $InstallDirectory.TrimEnd('\')
$pathEntries = $userPath -split ';' | Where-Object { $_ -ne '' }

if ($pathEntries -notcontains $normalizedInstall) {
$newPath = if ([string]::IsNullOrWhiteSpace($userPath)) {
$normalizedInstall
}
else {
"$userPath;$normalizedInstall"
}
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
$env:Path = "$env:Path;$normalizedInstall"
Write-Host "Added to user PATH: $normalizedInstall"
}
else {
Write-Host "Install directory already in user PATH: $normalizedInstall"
}

Write-Host "Global command available: $BinaryName"
}

if ($PSBoundParameters.ContainsKey('Help')) {
Write-Usage
exit 0
}

$platform = Get-PlatformArtifact
$installDir = (Resolve-Path -Path $Dir).Path
New-Item -ItemType Directory -Force -Path $installDir | Out-Null

Write-Host "Platform: $platform"
Write-Host "Install directory: $installDir"

$release = Get-ReleaseJson -VersionTag $Version
$asset = Get-ReleaseAsset -Release $release -Platform $platform
$zipPath = Join-Path $installDir $asset.name

Write-Host "Asset: $($asset.name)"
Save-FileWithProgress -Url $asset.browser_download_url -Destination $zipPath

Write-Host 'Extracting...'
Expand-Archive -Path $zipPath -DestinationPath $installDir -Force
Remove-Item -Path $zipPath -Force

$binaryPath = Join-Path $installDir $BinaryName
if (-not (Test-Path -LiteralPath $binaryPath)) {
throw "Expected binary not found after extraction: $binaryPath"
}

if (-not $NoGlobal) {
Install-GlobalCommand -InstallDirectory $installDir
}

Write-Host ''
Write-Host 'Installation complete.'
Write-Host "Run: $BinaryName --help"
if (-not $NoGlobal) {
Write-Host 'Open a new terminal if the command is not available yet.'
}
Loading
Loading