Content
# BlueOS MCP Server
Local STDIO MCP service for identifying, creating, modifying, and checking Vivo BlueOS projects. The current version only operates on project files, does not control BlueOS Studio GUI, and does not perform signing, packaging, uploading, or deletion.
## Capabilities
- Identify common applications and watch face projects
- Read, deeply merge, update, and verify `src/manifest.json`
- Create ordinary pages and register `router.pages`
- Create basic watch faces and register `router.watchfaces`
- Add application or watch face feature declarations (idempotent)
- Verify UX three-segment structure, single root node, tag closure, resource path, and common API features
- Safely copy image, font, and audio resources
- Generate complete Markdown project report
- All project write paths are restricted within `projectRoot`; manifest modification is backed up before modification
## Environment and Installation
Requires Node.js 20 or higher.
```powershell
cd F:\watch\blueos-mcp-server
npm install
npm run build
npm test
npm run test:mcp
```
Development mode:
```powershell
npm run dev
```
Production startup:
```powershell
npm start
```
STDIO is a protocol channel, and the service will not print ordinary logs to stdout after normal startup.
## Codex Configuration
Add the following to the user-level `~/.codex/config.toml` or the trusted project's `.codex/config.toml`:
```toml
[mcp_servers.blueos]
command = "node"
args = ["F:/watch/blueos-mcp-server/dist/index.js"]
startup_timeout_sec = 20
tool_timeout_sec = 60
enabled = true
```
You can also directly run TypeScript during development:
```toml
[mcp_servers.blueos]
command = "npx"
args = ["tsx", "F:/watch/blueos-mcp-server/src/index.ts"]
startup_timeout_sec = 20
tool_timeout_sec = 60
enabled = true
```
Restart the Codex session after modifying the configuration and check the MCP tool list. You can also add local services using the Codex CLI:
```powershell
codex mcp add blueos -- node F:/watch/blueos-mcp-server/dist/index.js
```
## Tools
### `blueos.inspect_project`
Input:
```json
{ "projectRoot": "D:/Projects/MyBlueOSApp" }
```
Output example:
```json
{
"isBlueOSProject": true,
"projectRoot": "D:/Projects/MyBlueOSApp",
"hasPackageJson": true,
"hasManifest": true,
"hasAppUx": true,
"hasPagesDir": true,
"projectType": "app",
"pages": ["Demo"],
"watchfaces": [],
"warnings": []
}
```
### `blueos.read_manifest`
Input:
```json
{ "projectRoot": "D:/Projects/MyBlueOSApp" }
```
Output is the parsed complete manifest JSON object.
### `blueos.validate_manifest`
Input:
```json
{ "projectRoot": "D:/Projects/MyBlueOSApp" }
```
Output example:
```json
{
"valid": false,
"errors": [
{ "code": "ROUTER_PAGE_FILE_MISSING", "message": "router.pages declared Detail, but the corresponding .ux file does not exist" }
],
"warnings": []
}
```
Checks required fields, `versionCode`, `config.designWidth`, `features`, ordinary application/watch face routing, duplicate paths, icons, page components, and watch face preview images.
### `blueos.create_page`
Input:
```json
{
"projectRoot": "D:/Projects/MyBlueOSApp",
"pageName": "StressPage",
"routePath": "/stress",
"title": "Stress Monitoring",
"setAsEntry": false
}
```
Creates `src/pages/StressPage/index.ux` and updates the existing object or array `router.pages`. The new route shape for the object is:
```json
{
"StressPage": { "path": "/stress", "component": "pages/StressPage" }
}
```
### `blueos.update_manifest`
Input:
```json
{
"projectRoot": "D:/Projects/MyBlueOSApp",
"patch": {
"versionName": "1.1.0",
"versionCode": 2,
"config": { "designWidth": 466 }
}
}
```
Object field deep merge, array and scalar overall replacement. Automatically runs manifest verification after writing; `success: false` indicates that the modification has been written but the verification has not passed, and the details are in `validation`.
### `blueos.add_feature`
Ordinary application:
```json
{
"projectRoot": "D:/Projects/MyBlueOSApp",
"featureName": "blueos.communication.network.fetch",
"target": "app"
}
```
Watch face:
```json
{
"projectRoot": "D:/Projects/MyBlueOSWatchface",
"featureName": "blueos.app.router",
"target": "watchface",
"watchPath": "watch3000"
}
```
If the feature already exists, do not write files, do not produce meaningless backups, and return the modified array.
### `blueos.create_watchface`
Input:
```json
{
"projectRoot": "D:/Projects/MyBlueOSWatchface",
"watchId": 3000,
"watchName": "Stress Dynamic Watch Face",
"packageName": "com.example.watch.stress",
"previewImage": "assets/preview.png",
"editable": true,
"designWidth": 466
}
```
Creates `src/watch3000/index.ux`, optionally creates `edit.ux`, and writes `router.watchfaces.watch3000`. If the project is empty, it will also create the minimum `package.json`, `src/app.ux`, and manifest. The tool will not forge a preview image; if the preview image is missing, it will return a `WATCHFACE_PREVIEW_MISSING` warning instead of making the creation fail.
### `blueos.validate_ux_file`
Input:
```json
{
"filePath": "D:/Projects/MyBlueOSApp/src/pages/Demo/index.ux",
"projectRoot": "D:/Projects/MyBlueOSApp"
}
```
`projectRoot` is optional; if provided, it will also check resource paths and manifest features. Output:
```json
{
"valid": true,
"errors": [],
"warnings": [
{ "code": "STYLE_EMPTY", "message": "style tag is empty, the page may not have styles" }
]
}
```
Feature checking is a static heuristic rule, currently covering network fetch and routing APIs; it cannot replace the BlueOS compiler.
### `blueos.add_asset`
Input:
```json
{
"projectRoot": "D:/Projects/MyBlueOSApp",
"sourceFile": "C:/Users/User/Desktop/bg.png",
"targetDir": "src/assets/images",
"renameTo": "stress-bg.png",
"conflictStrategy": "autoRename"
}
```
`conflictStrategy` can be `autoRename` (default), `overwrite`, or `error`. Allows common image, font, and audio extensions. Output includes the target absolute path and BlueOS reference path:
```json
{
"success": true,
"targetFile": "D:/Projects/MyBlueOSApp/src/assets/images/stress-bg.png",
"blueosPath": "/assets/images/stress-bg.png"
}
```
### `blueos.generate_report`
Input:
```json
{ "projectRoot": "D:/Projects/MyBlueOSApp" }
```
Output Markdown report, including project status, severe errors, warnings, unregistered pages, and suggestions for repair.
## Write Operation Return Convention
`create_page`, `update_manifest`, `add_feature`, `create_watchface`, and `add_asset` all return:
```json
{
"success": true,
"changedFiles": ["src/manifest.json"],
"createdFiles": [],
"backupFiles": [".backups/manifest-20260702-153000.json"],
"summary": "Specific change summary"
}
```
Manifest backups are stored in the project root directory `.backups/`. Multiple modifications within the same second will choose a subsequent unused second-level file name to avoid overwriting historical backups. All JSON is written back with two-space indentation and a trailing newline.
Failed return specific error code:
```json
{
"success": false,
"errorCode": "MANIFEST_NOT_FOUND",
"message": "src/manifest.json not found, please confirm if projectRoot is the BlueOS project root directory"
}
```
## Security Boundary
- All target write paths will be verified to belong to `projectRoot` after normalization.
- Existing directories will also resolve real paths to prevent writing out of the project via symbolic links.
- `update_manifest` rejects `__proto__`, `prototype`, `constructor`, and other prototype pollution fields.
- No deletion tools are provided, no GUI is called, and no official build CLI is assumed.
- `add_asset` allows reading user-specified source files outside the project, but the target must always be within the project.
## Test Samples
Fixtures:
```text
tests/fixtures/sample-blueos-app/
tests/fixtures/sample-blueos-watchface/
```
Automatic test coverage: normal recognition, missing manifest, missing app.ux, missing routing pages, unregistered pages, missing watch face preview images, feature idempotence, creating pages, creating watch faces, cross-directory write rejection, and UX single root node.
```powershell
npm test
npm run test:mcp
```
`test:mcp` will build first, then start the service using the official MCP TypeScript SDK's STDIO client, confirm that exactly 10 tools are registered, and actually call `blueos.inspect_project`.
## Known Boundaries
- Different BlueOS versions may have additional manifest fields; this service retains unknown fields and does not treat unknown fields as errors.
- UX static checking is not a complete syntax compiler; complex template expressions should still be finally verified in BlueOS Studio.
- The first version does not perform building, signing, simulator, application store uploading, or GUI automatic clicking.