connectiq-mcp-server 1.0.1

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.
Files changed (106) hide show
  1. package/.claude/commands/commit.md +18 -0
  2. package/.claude/commands/create-pr.md +42 -0
  3. package/.claude/settings.json +11 -0
  4. package/.github/workflows/publish.yml +63 -0
  5. package/.mcp.json +26 -0
  6. package/.prettierignore +2 -0
  7. package/.prettierrc +8 -0
  8. package/CLAUDE.md +68 -0
  9. package/README.md +229 -0
  10. package/build/config/ConfigManager.d.ts +43 -0
  11. package/build/config/ConfigManager.d.ts.map +1 -0
  12. package/build/config/ConfigManager.js +137 -0
  13. package/build/config/ConfigManager.js.map +1 -0
  14. package/build/handlers/promptHandlers.d.ts +19 -0
  15. package/build/handlers/promptHandlers.d.ts.map +1 -0
  16. package/build/handlers/promptHandlers.js +270 -0
  17. package/build/handlers/promptHandlers.js.map +1 -0
  18. package/build/handlers/resourceHandlers.d.ts +18 -0
  19. package/build/handlers/resourceHandlers.d.ts.map +1 -0
  20. package/build/handlers/resourceHandlers.js +264 -0
  21. package/build/handlers/resourceHandlers.js.map +1 -0
  22. package/build/handlers/toolHandlers.d.ts +19 -0
  23. package/build/handlers/toolHandlers.d.ts.map +1 -0
  24. package/build/handlers/toolHandlers.js +374 -0
  25. package/build/handlers/toolHandlers.js.map +1 -0
  26. package/build/index.d.ts +13 -0
  27. package/build/index.d.ts.map +1 -0
  28. package/build/index.js +101 -0
  29. package/build/index.js.map +1 -0
  30. package/build/parsers/HtmlParser.d.ts +53 -0
  31. package/build/parsers/HtmlParser.d.ts.map +1 -0
  32. package/build/parsers/HtmlParser.js +287 -0
  33. package/build/parsers/HtmlParser.js.map +1 -0
  34. package/build/parsers/XmlParser.d.ts +40 -0
  35. package/build/parsers/XmlParser.d.ts.map +1 -0
  36. package/build/parsers/XmlParser.js +110 -0
  37. package/build/parsers/XmlParser.js.map +1 -0
  38. package/build/services/ApiDocService.d.ts +69 -0
  39. package/build/services/ApiDocService.d.ts.map +1 -0
  40. package/build/services/ApiDocService.js +345 -0
  41. package/build/services/ApiDocService.js.map +1 -0
  42. package/build/services/DeviceInfoService.d.ts +75 -0
  43. package/build/services/DeviceInfoService.d.ts.map +1 -0
  44. package/build/services/DeviceInfoService.js +433 -0
  45. package/build/services/DeviceInfoService.js.map +1 -0
  46. package/build/services/ProjectInfoService.d.ts +43 -0
  47. package/build/services/ProjectInfoService.d.ts.map +1 -0
  48. package/build/services/ProjectInfoService.js +78 -0
  49. package/build/services/ProjectInfoService.js.map +1 -0
  50. package/build/services/SampleService.d.ts +46 -0
  51. package/build/services/SampleService.d.ts.map +1 -0
  52. package/build/services/SampleService.js +211 -0
  53. package/build/services/SampleService.js.map +1 -0
  54. package/build/types/index.d.ts +383 -0
  55. package/build/types/index.d.ts.map +1 -0
  56. package/build/types/index.js +5 -0
  57. package/build/types/index.js.map +1 -0
  58. package/build/utils/AsyncFileCache.d.ts +48 -0
  59. package/build/utils/AsyncFileCache.d.ts.map +1 -0
  60. package/build/utils/AsyncFileCache.js +108 -0
  61. package/build/utils/AsyncFileCache.js.map +1 -0
  62. package/build/utils/MarkdownConverter.d.ts +21 -0
  63. package/build/utils/MarkdownConverter.d.ts.map +1 -0
  64. package/build/utils/MarkdownConverter.js +262 -0
  65. package/build/utils/MarkdownConverter.js.map +1 -0
  66. package/build/utils/index.d.ts +7 -0
  67. package/build/utils/index.d.ts.map +1 -0
  68. package/build/utils/index.js +7 -0
  69. package/build/utils/index.js.map +1 -0
  70. package/build/utils/logging.d.ts +41 -0
  71. package/build/utils/logging.d.ts.map +1 -0
  72. package/build/utils/logging.js +51 -0
  73. package/build/utils/logging.js.map +1 -0
  74. package/eslint.config.js +44 -0
  75. package/package.json +60 -0
  76. package/server.json +34 -0
  77. package/src/config/ConfigManager.ts +182 -0
  78. package/src/handlers/promptHandlers.ts +369 -0
  79. package/src/handlers/resourceHandlers.ts +324 -0
  80. package/src/handlers/toolHandlers.ts +486 -0
  81. package/src/index.ts +119 -0
  82. package/src/parsers/HtmlParser.ts +343 -0
  83. package/src/parsers/XmlParser.ts +133 -0
  84. package/src/services/ApiDocService.ts +453 -0
  85. package/src/services/DeviceInfoService.ts +514 -0
  86. package/src/services/ProjectInfoService.ts +94 -0
  87. package/src/services/SampleService.ts +230 -0
  88. package/src/types/index.ts +435 -0
  89. package/src/utils/AsyncFileCache.ts +141 -0
  90. package/src/utils/MarkdownConverter.ts +318 -0
  91. package/src/utils/index.ts +7 -0
  92. package/src/utils/logging.ts +84 -0
  93. package/test/fixtures/mockConfig.ts +548 -0
  94. package/test/unit/config/ConfigManager.test.ts +316 -0
  95. package/test/unit/handlers/resourceHandlers.test.ts +317 -0
  96. package/test/unit/handlers/toolHandlers.test.ts +415 -0
  97. package/test/unit/parsers/HtmlParser.test.ts +351 -0
  98. package/test/unit/parsers/XmlParser.test.ts +207 -0
  99. package/test/unit/services/ApiDocService.test.ts +371 -0
  100. package/test/unit/services/DeviceInfoService.test.ts +896 -0
  101. package/test/unit/services/ProjectInfoService.test.ts +110 -0
  102. package/test/unit/services/SampleService.test.ts +361 -0
  103. package/test/unit/utils/MarkdownConverter.test.ts +327 -0
  104. package/tsconfig.json +20 -0
  105. package/tsconfig.test.json +8 -0
  106. package/vitest.config.ts +20 -0
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Create a git commit
3
+ ---
4
+
5
+ ## Context
6
+
7
+ - Current git status: `mcp__git__git_status`
8
+ - Current staged changes: `mcp__git__git_diff_staged`
9
+ - Recent commits: `mcp__git__git_log`
10
+
11
+ ## Your task
12
+
13
+ Based on the above changes, create a single git commit.
14
+
15
+ ## Common Notes
16
+
17
+ - Do not add "Generated with [Claude Code]..." to the commit message.
18
+ - Do not mention Claude as a co-author.
@@ -0,0 +1,42 @@
1
+ ---
2
+ allowed-tools: Bash(git log:*), Bash(gh pr list:*), Bash(gh issue list:*)
3
+ description: Create a GitHub pull request with proper description and metadata
4
+ ---
5
+
6
+ ## Context
7
+
8
+ - Current git status: `mcp__git__git_status`
9
+ - Commits ahead of main: !`git log --oneline main..HEAD`
10
+ - Changed files: `mcp__git__git_diff` with target `main`
11
+ - Existing open PRs: !`gh pr list --state open --limit 5`
12
+ - Related issues that can be linked: !`gh issue list --limit 10`
13
+
14
+ ## Your task
15
+
16
+ Create a well-structured pull request with proper description, labels, and reviewers based on the changes above.
17
+
18
+ ### Steps
19
+ 1. **Prepare branch**
20
+ - Ensure all changes are committed
21
+ - Push branch to remote
22
+ - Verify branch is up to date with main
23
+
24
+ 2. **Write PR description**
25
+ - Summarize changes clearly
26
+ - Include context and motivation
27
+ - List any breaking changes
28
+
29
+ 3. **Set up PR**
30
+ - Create (or update if already exists) PR with descriptive title
31
+ - Add appropriate labels
32
+ - Assign reviewers
33
+ - Link related issues
34
+
35
+ ### PR Template
36
+ - [ ] Feature A
37
+ - [ ] Bug fix B
38
+
39
+ ## Common Notes
40
+
41
+ - Do not add "Generated with [Claude Code]..." to the PR description.
42
+ - Do not mention Claude as a co-author.
@@ -0,0 +1,11 @@
1
+ {
2
+ "enabledPlugins": {
3
+ "code-review@claude-plugins-official": true,
4
+ "commit-commands@claude-plugins-official": true,
5
+ "feature-dev@claude-plugins-official": true,
6
+ "plugin-dev@claude-plugins-official": true,
7
+ "pr-review-toolkit@claude-plugins-official": true,
8
+ "ralph-wiggum@claude-plugins-official": true,
9
+ "typescript-lsp@claude-plugins-official": true
10
+ }
11
+ }
@@ -0,0 +1,63 @@
1
+ name: Publish to npm and MCP Registry
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+ id-token: write
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: "lts/*"
23
+ registry-url: "https://registry.npmjs.org"
24
+
25
+ - name: Install dependencies
26
+ run: npm ci
27
+
28
+ - name: Run linting
29
+ run: npm run lint
30
+
31
+ - name: Run tests
32
+ run: npm test
33
+
34
+ - name: Build
35
+ run: npm run build
36
+
37
+ - name: Extract version from tag
38
+ id: version
39
+ run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
40
+
41
+ - name: Update package.json version
42
+ run: npm version ${{ steps.version.outputs.VERSION }} --no-git-tag-version
43
+
44
+ - name: Update server.json version
45
+ run: |
46
+ jq '.version = "${{ steps.version.outputs.VERSION }}" | .packages[0].version = "${{ steps.version.outputs.VERSION }}"' server.json > server.json.tmp
47
+ mv server.json.tmp server.json
48
+
49
+ - name: Publish to npm
50
+ run: npm publish --access public
51
+ env:
52
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
53
+
54
+ - name: Download mcp-publisher
55
+ run: |
56
+ curl -sL https://github.com/anthropics/mcp-registry/releases/latest/download/mcp-publisher-linux-amd64 -o mcp-publisher
57
+ chmod +x mcp-publisher
58
+
59
+ - name: Authenticate with MCP Registry (OIDC)
60
+ run: ./mcp-publisher login github --oidc
61
+
62
+ - name: Publish to MCP Registry
63
+ run: ./mcp-publisher publish
package/.mcp.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": ["-y", "@upstash/context7-mcp"]
7
+ },
8
+ "git": {
9
+ "type": "stdio",
10
+ "command": "uvx",
11
+ "args": ["mcp-server-git"]
12
+ },
13
+ "github": {
14
+ "type": "stdio",
15
+ "command": "./mcp/github/command.sh"
16
+ },
17
+ "connectiq": {
18
+ "command": "node",
19
+ "args": ["build/index.js"],
20
+ "env": {
21
+ "CONNECTIQ_SDK_PATH": "/Users/eugenes/Library/Application Support/Garmin/ConnectIQ/Sdks/connectiq-sdk-mac-8.4.0-2025-12-03-5122605dc",
22
+ "CONNECTIQ_DEVICES_PATH": "/Users/eugenes/Library/Application Support/Garmin/ConnectIQ/Devices"
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,2 @@
1
+ node_modules/
2
+ build/
package/.prettierrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": false,
4
+ "tabWidth": 2,
5
+ "useTabs": false,
6
+ "trailingComma": "es5",
7
+ "printWidth": 80
8
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,68 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ MCP (Model Context Protocol) server that provides Claude Desktop with access to Garmin ConnectIQ SDK documentation, device specifications, sample projects, and project configuration data. Written in TypeScript, runs on Node.js 18+.
8
+
9
+ ## Build and Development Commands
10
+
11
+ ```bash
12
+ npm install # Install dependencies
13
+ npm run build # Compile TypeScript to build/
14
+ npm run dev # Watch mode compilation
15
+ npm run clean # Remove build directory
16
+ npm start # Run the server (requires SDK path)
17
+ npm run lint # Run ESLint
18
+ npm run lint:fix # Run ESLint with auto-fix
19
+ npm run format # Format code with Prettier
20
+ npm run format:check # Check formatting without changes
21
+ npm test # Run all tests
22
+ npm run test:watch # Run tests in watch mode
23
+ npm run test:coverage # Run tests with coverage report
24
+ ```
25
+
26
+ **Running a single test file:**
27
+ ```bash
28
+ npx vitest run test/unit/services/ApiDocService.test.ts
29
+ ```
30
+
31
+ The server requires the ConnectIQ SDK path via `CONNECTIQ_SDK_PATH` environment variable or `--sdk-path`/`-s` argument.
32
+
33
+ Optionally, set `CONNECTIQ_DEVICES_PATH` (or `--devices-path`/`-d`) for richer device data including fonts and display details.
34
+
35
+ ## Architecture
36
+
37
+ **Entry Point**: `src/index.ts` - Creates MCP server with stdio transport, initializes config and registers handlers.
38
+
39
+ **Layered Structure**:
40
+ - `config/ConfigManager.ts` - SDK path resolution (CLI arg → env var), validates SDK directories exist
41
+ - `handlers/` - MCP protocol handlers
42
+ - `toolHandlers.ts` - Registers 6 tools with Zod schemas (searchApiDocs, getDeviceInfo, listDevices, listSamples, getSampleCode, getProjectConfig)
43
+ - `resourceHandlers.ts` - Handles `connectiq://` URI resources
44
+ - `promptHandlers.ts` - Registers 4 prompts (review-connectiq-code, explain-api, device-compatibility, optimize-memory)
45
+ - `services/` - Business logic with caching
46
+ - `ApiDocService.ts` - Parses Toybox API HTML docs, search with relevance scoring, LRU cache (50 modules, 5 min TTL)
47
+ - `DeviceInfoService.ts` - Parses device XML from SDK `bin/devices/` directory
48
+ - `SampleService.ts` - Browses SDK `samples/` directory with path traversal protection
49
+ - `ProjectInfoService.ts` - Parses `bin/projectInfo.xml` for app types, permissions, sports
50
+ - `parsers/` - Data extraction
51
+ - `HtmlParser.ts` - Cheerio-based Toybox doc parsing
52
+ - `XmlParser.ts` - fast-xml-parser wrapper for SDK config files
53
+ - `types/index.ts` - Shared TypeScript interfaces
54
+ - `utils/` - Shared utilities
55
+ - `logging.ts` - MCP protocol logging wrapper (sends logs to client as notifications)
56
+ - `AsyncFileCache.ts` - Generic async file caching with TTL
57
+ - `MarkdownConverter.ts` - Turndown-based HTML to Markdown conversion
58
+
59
+ **Key Patterns**:
60
+ - All tool parameters validated with Zod schemas that get converted to JSON Schema for MCP
61
+ - Services use caching for performance (module docs, device list, sample list)
62
+ - Path traversal protection in sample file access using `resolve()` + `startsWith()` checks
63
+
64
+ ## Commit Guidelines
65
+
66
+ When creating commits:
67
+ - Do not add "Generated with [Claude Code]..." to commit messages
68
+ - Do not mention Claude as a co-author
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # ConnectIQ MCP Server
2
+
3
+ An MCP (Model Context Protocol) server that provides access to Garmin ConnectIQ SDK documentation, sample code, device information, and project configuration.
4
+
5
+ ## Features
6
+
7
+ - **API Documentation Search**: Search the Toybox API documentation for classes, methods, properties, and constants
8
+ - **Device Information**: Get specifications and capabilities for supported Garmin devices
9
+ - **Sample Code Access**: Browse and read sample project source code from the SDK
10
+ - **Project Configuration**: Access app types, permissions, languages, and activity sports
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install
16
+ npm run build
17
+ ```
18
+
19
+ ## Configuration
20
+
21
+ The server requires the path to a ConnectIQ SDK installation.
22
+
23
+ ### Required: SDK Path
24
+
25
+ Set via environment variable:
26
+ ```bash
27
+ export CONNECTIQ_SDK_PATH="/Users/username/Library/Application Support/Garmin/ConnectIQ/Sdks/connectiq-sdk-mac-8.4.0-2025-12-03-5122605dc"
28
+ ```
29
+
30
+ Or via command line argument:
31
+ ```bash
32
+ node build/index.js --sdk-path="/path/to/sdk"
33
+ # or
34
+ node build/index.js -s "/path/to/sdk"
35
+ ```
36
+
37
+ ### Optional: Devices Path
38
+
39
+ For richer device information (fonts, display details, part numbers), you can also provide the path to the ConnectIQ Devices directory:
40
+
41
+ ```bash
42
+ export CONNECTIQ_DEVICES_PATH="/Users/username/Library/Application Support/Garmin/ConnectIQ/Devices"
43
+ ```
44
+
45
+ Or via command line argument:
46
+ ```bash
47
+ node build/index.js --devices-path="/path/to/devices"
48
+ # or
49
+ node build/index.js -d "/path/to/devices"
50
+ ```
51
+
52
+ When the devices path is provided, `getDeviceInfo` returns enhanced data including vector fonts, display configurations, and firmware details.
53
+
54
+ ## Usage with Claude Desktop
55
+
56
+ Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json`):
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "connectiq": {
62
+ "command": "node",
63
+ "args": ["/path/to/connect-iq-mcp/build/index.js"],
64
+ "env": {
65
+ "CONNECTIQ_SDK_PATH": "/Users/username/Library/Application Support/Garmin/ConnectIQ/Sdks/connectiq-sdk-mac-8.4.0-2025-12-03-5122605dc",
66
+ "CONNECTIQ_DEVICES_PATH": "/Users/username/Library/Application Support/Garmin/ConnectIQ/Devices"
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ Note: `CONNECTIQ_DEVICES_PATH` is optional but recommended for richer device information.
74
+
75
+ ## Available Tools
76
+
77
+ ### searchApiDocs
78
+ Search ConnectIQ Toybox API documentation.
79
+
80
+ ```json
81
+ {
82
+ "query": "getDeviceSettings",
83
+ "module": "System",
84
+ "limit": 10
85
+ }
86
+ ```
87
+
88
+ ### getDeviceInfo
89
+ Get specifications for a specific Garmin device.
90
+
91
+ ```json
92
+ {
93
+ "deviceId": "fenix8"
94
+ }
95
+ ```
96
+
97
+ ### listDevices
98
+ List all available Garmin devices.
99
+
100
+ ```json
101
+ {
102
+ "query": "fenix"
103
+ }
104
+ ```
105
+
106
+ ### listSamples
107
+ List available sample projects.
108
+
109
+ ```json
110
+ {
111
+ "category": "datafield"
112
+ }
113
+ ```
114
+
115
+ ### getSampleCode
116
+ Read source code from a sample project.
117
+
118
+ ```json
119
+ {
120
+ "project": "SimpleDataField",
121
+ "file": "source/SimpleDataFieldView.mc"
122
+ }
123
+ ```
124
+
125
+ ### getProjectConfig
126
+ Get project configuration data.
127
+
128
+ ```json
129
+ {
130
+ "section": "permissions"
131
+ }
132
+ ```
133
+
134
+ ## Available Resources
135
+
136
+ The server exposes resources via the `connectiq://` protocol:
137
+
138
+ - `connectiq://api/{module}` - API documentation for a Toybox module (e.g., `connectiq://api/System`)
139
+ - `connectiq://samples/{project}` - Sample project information and file listing
140
+ - `connectiq://samples/{project}/{file}` - Specific file from a sample project
141
+ - `connectiq://devices/{deviceId}` - Device specifications as JSON
142
+
143
+ ## Development
144
+
145
+ ```bash
146
+ # Install dependencies
147
+ npm install
148
+
149
+ # Build
150
+ npm run build
151
+
152
+ # Watch mode
153
+ npm run dev
154
+
155
+ # Run the server
156
+ npm start
157
+
158
+ # Clean build artifacts
159
+ npm run clean
160
+ ```
161
+
162
+ ## Testing
163
+
164
+ The project uses [Vitest](https://vitest.dev/) for testing.
165
+
166
+ ```bash
167
+ # Run all tests
168
+ npm test
169
+
170
+ # Run tests in watch mode
171
+ npm run test:watch
172
+
173
+ # Run tests with coverage report
174
+ npm run test:coverage
175
+ ```
176
+
177
+ Test files are located in `test/unit/` and follow the `*.test.ts` naming convention.
178
+
179
+ ## Code Quality
180
+
181
+ The project uses ESLint for linting and Prettier for code formatting.
182
+
183
+ ```bash
184
+ # Run ESLint
185
+ npm run lint
186
+
187
+ # Run ESLint with auto-fix
188
+ npm run lint:fix
189
+
190
+ # Format code with Prettier
191
+ npm run format
192
+
193
+ # Check formatting without changes
194
+ npm run format:check
195
+ ```
196
+
197
+ ## Project Structure
198
+
199
+ ```
200
+ src/
201
+ ├── index.ts # Server entry point
202
+ ├── config/
203
+ │ └── ConfigManager.ts # SDK path resolution
204
+ ├── handlers/
205
+ │ ├── toolHandlers.ts # MCP tool registration
206
+ │ └── resourceHandlers.ts # MCP resource registration
207
+ ├── services/
208
+ │ ├── ApiDocService.ts # Toybox API search
209
+ │ ├── DeviceInfoService.ts # Device specs
210
+ │ ├── SampleService.ts # Sample code
211
+ │ └── ProjectInfoService.ts # App types/permissions
212
+ ├── parsers/
213
+ │ ├── HtmlParser.ts # HTML doc parsing
214
+ │ └── XmlParser.ts # XML config parsing
215
+ └── types/
216
+ └── index.ts # Shared interfaces
217
+
218
+ test/
219
+ ├── fixtures/
220
+ │ └── mockConfig.ts # Test configuration mocks
221
+ └── unit/
222
+ ├── config/ # ConfigManager tests
223
+ ├── parsers/ # Parser tests
224
+ └── services/ # Service tests
225
+ ```
226
+
227
+ ## License
228
+
229
+ MIT
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Configuration Manager for ConnectIQ SDK path resolution
3
+ */
4
+ import type { ConnectIQConfig } from "../types/index.js";
5
+ /**
6
+ * Resolve and validate ConnectIQ SDK configuration
7
+ */
8
+ export declare class ConfigManager {
9
+ /**
10
+ * Initialize configuration from CLI args or environment
11
+ * @throws Error if SDK path is not found or invalid
12
+ */
13
+ static initialize(): Promise<ConnectIQConfig>;
14
+ /**
15
+ * Resolve a path from CLI arguments or environment variable
16
+ */
17
+ private static resolvePath;
18
+ /**
19
+ * Resolve SDK path from CLI arguments or environment variable
20
+ */
21
+ private static resolveSdkPath;
22
+ /**
23
+ * Resolve devices path from CLI arguments or environment variable (optional)
24
+ */
25
+ private static resolveDevicesPath;
26
+ /**
27
+ * Validate that the SDK path contains expected directories
28
+ */
29
+ private static validateSdkStructure;
30
+ /**
31
+ * Build configuration object from SDK path and optional devices path
32
+ */
33
+ private static buildConfig;
34
+ /**
35
+ * Validate and optionally add devices path to config
36
+ */
37
+ private static validateDevicesPath;
38
+ /**
39
+ * Extract SDK version from compilerInfo.xml
40
+ */
41
+ private static extractSdkVersion;
42
+ }
43
+ //# sourceMappingURL=ConfigManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigManager.d.ts","sourceRoot":"","sources":["../../src/config/ConfigManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAWzD;;GAEG;AACH,qBAAa,aAAa;IACxB;;;OAGG;WACU,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IA0BnD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAwB1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAI7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAQjC;;OAEG;mBACkB,oBAAoB;IAuBzC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAc1B;;OAEG;mBACkB,mBAAmB;IAmBxC;;OAEG;mBACkB,iBAAiB;CAiBvC"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Configuration Manager for ConnectIQ SDK path resolution
3
+ */
4
+ import { join, resolve } from "node:path";
5
+ import { XMLParser } from "fast-xml-parser";
6
+ import { fileCache } from "../utils/index.js";
7
+ const ENV_VAR_NAME = "CONNECTIQ_SDK_PATH";
8
+ const CLI_ARG_PREFIX = "--sdk-path=";
9
+ const CLI_ARG_SHORT = "-s";
10
+ const DEVICES_ENV_VAR_NAME = "CONNECTIQ_DEVICES_PATH";
11
+ const DEVICES_CLI_ARG_PREFIX = "--devices-path=";
12
+ const DEVICES_CLI_ARG_SHORT = "-d";
13
+ /**
14
+ * Resolve and validate ConnectIQ SDK configuration
15
+ */
16
+ export class ConfigManager {
17
+ /**
18
+ * Initialize configuration from CLI args or environment
19
+ * @throws Error if SDK path is not found or invalid
20
+ */
21
+ static async initialize() {
22
+ const sdkPath = this.resolveSdkPath();
23
+ if (!sdkPath) {
24
+ throw new Error(`ConnectIQ SDK path not found. Please set the ${ENV_VAR_NAME} environment variable ` +
25
+ `or pass --sdk-path=/path/to/sdk as a command line argument.`);
26
+ }
27
+ const resolvedPath = resolve(sdkPath);
28
+ if (!(await fileCache.exists(resolvedPath))) {
29
+ throw new Error(`ConnectIQ SDK path does not exist: ${resolvedPath}`);
30
+ }
31
+ await this.validateSdkStructure(resolvedPath);
32
+ const devicesPath = this.resolveDevicesPath();
33
+ const config = this.buildConfig(resolvedPath);
34
+ await this.validateDevicesPath(config, devicesPath);
35
+ config.sdkVersion = await this.extractSdkVersion(config.compilerInfoPath);
36
+ return config;
37
+ }
38
+ /**
39
+ * Resolve a path from CLI arguments or environment variable
40
+ */
41
+ static resolvePath(longPrefix, shortArg, envVar) {
42
+ const args = process.argv.slice(2);
43
+ // Check long form: --arg=/path
44
+ for (const arg of args) {
45
+ if (arg.startsWith(longPrefix)) {
46
+ return arg.slice(longPrefix.length);
47
+ }
48
+ }
49
+ // Check short form: -a /path
50
+ const shortArgIndex = args.indexOf(shortArg);
51
+ if (shortArgIndex !== -1 && args[shortArgIndex + 1]) {
52
+ return args[shortArgIndex + 1];
53
+ }
54
+ // Fall back to environment variable
55
+ return process.env[envVar];
56
+ }
57
+ /**
58
+ * Resolve SDK path from CLI arguments or environment variable
59
+ */
60
+ static resolveSdkPath() {
61
+ return this.resolvePath(CLI_ARG_PREFIX, CLI_ARG_SHORT, ENV_VAR_NAME);
62
+ }
63
+ /**
64
+ * Resolve devices path from CLI arguments or environment variable (optional)
65
+ */
66
+ static resolveDevicesPath() {
67
+ return this.resolvePath(DEVICES_CLI_ARG_PREFIX, DEVICES_CLI_ARG_SHORT, DEVICES_ENV_VAR_NAME);
68
+ }
69
+ /**
70
+ * Validate that the SDK path contains expected directories
71
+ */
72
+ static async validateSdkStructure(sdkPath) {
73
+ const requiredPaths = [
74
+ { path: "doc/Toybox", name: "API documentation" },
75
+ { path: "bin/projectInfo.xml", name: "Project configuration" },
76
+ { path: "samples", name: "Sample projects" },
77
+ ];
78
+ const missingPaths = [];
79
+ for (const { path, name } of requiredPaths) {
80
+ const fullPath = join(sdkPath, path);
81
+ if (!(await fileCache.exists(fullPath))) {
82
+ missingPaths.push(`${name} (${path})`);
83
+ }
84
+ }
85
+ if (missingPaths.length > 0) {
86
+ throw new Error(`Invalid ConnectIQ SDK structure. Missing:\n - ${missingPaths.join("\n - ")}`);
87
+ }
88
+ }
89
+ /**
90
+ * Build configuration object from SDK path and optional devices path
91
+ */
92
+ static buildConfig(sdkPath) {
93
+ const config = {
94
+ sdkPath,
95
+ docPath: join(sdkPath, "doc", "Toybox"),
96
+ deviceRefPath: join(sdkPath, "resources", "device-reference"),
97
+ samplesPath: join(sdkPath, "samples"),
98
+ projectInfoPath: join(sdkPath, "bin", "projectInfo.xml"),
99
+ compilerInfoPath: join(sdkPath, "bin", "compilerInfo.xml"),
100
+ sdkVersion: "", // Will be populated
101
+ };
102
+ return config;
103
+ }
104
+ /**
105
+ * Validate and optionally add devices path to config
106
+ */
107
+ static async validateDevicesPath(config, devicesPath) {
108
+ if (devicesPath) {
109
+ const resolvedDevicesPath = resolve(devicesPath);
110
+ if (await fileCache.exists(resolvedDevicesPath)) {
111
+ config.devicesPath = resolvedDevicesPath;
112
+ }
113
+ else {
114
+ console.error(`Warning: Devices path does not exist: ${resolvedDevicesPath}`);
115
+ console.error("Device info will be loaded from SDK device-reference only.");
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Extract SDK version from compilerInfo.xml
121
+ */
122
+ static async extractSdkVersion(compilerInfoPath) {
123
+ try {
124
+ if (!(await fileCache.exists(compilerInfoPath))) {
125
+ return "unknown";
126
+ }
127
+ const xml = await fileCache.readFile(compilerInfoPath, "utf-8");
128
+ const parser = new XMLParser();
129
+ const result = parser.parse(xml);
130
+ return result?.compilerInfo?.version ?? "unknown";
131
+ }
132
+ catch {
133
+ return "unknown";
134
+ }
135
+ }
136
+ }
137
+ //# sourceMappingURL=ConfigManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigManager.js","sourceRoot":"","sources":["../../src/config/ConfigManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * MCP Prompt handlers for ConnectIQ SDK server
3
+ *
4
+ * Uses the high-level McpServer API for prompt registration with
5
+ * automatic listChanged notification support and Zod schema validation.
6
+ *
7
+ * Provides pre-built prompt templates for common ConnectIQ development tasks:
8
+ * - Code review for best practices
9
+ * - API documentation explanation
10
+ * - Device compatibility analysis
11
+ * - Memory optimization guidance
12
+ */
13
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
+ import type { SharedServices } from "../types/index.js";
15
+ /**
16
+ * Register all prompt handlers with the MCP server
17
+ */
18
+ export declare function registerPrompts(server: McpServer, services: SharedServices): void;
19
+ //# sourceMappingURL=promptHandlers.d.ts.map