@uluops/registry-mcp 0.1.0 → 0.2.4

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 (59) hide show
  1. package/CHANGELOG.md +131 -4
  2. package/LICENSE +21 -0
  3. package/README.md +100 -93
  4. package/dist/client/sdk-error-mapper.d.ts +29 -0
  5. package/dist/client/sdk-error-mapper.d.ts.map +1 -1
  6. package/dist/client/sdk-error-mapper.js +122 -20
  7. package/dist/client/sdk-error-mapper.js.map +1 -1
  8. package/dist/config/index.d.ts +7 -1
  9. package/dist/config/index.d.ts.map +1 -1
  10. package/dist/config/index.js +91 -14
  11. package/dist/config/index.js.map +1 -1
  12. package/dist/config/tool-registry.d.ts.map +1 -1
  13. package/dist/config/tool-registry.js +0 -8
  14. package/dist/config/tool-registry.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +19 -6
  17. package/dist/index.js.map +1 -1
  18. package/dist/tools/batch-publish.js +8 -8
  19. package/dist/tools/batch-publish.js.map +1 -1
  20. package/dist/tools/index.d.ts +1 -1
  21. package/dist/tools/index.d.ts.map +1 -1
  22. package/dist/tools/index.js +2 -4
  23. package/dist/tools/index.js.map +1 -1
  24. package/dist/tools/{check-forkable.d.ts → is-forkable.d.ts} +1 -1
  25. package/dist/tools/is-forkable.d.ts.map +1 -0
  26. package/dist/tools/{check-forkable.js → is-forkable.js} +1 -1
  27. package/dist/tools/is-forkable.js.map +1 -0
  28. package/dist/tools/render-definition.d.ts +3 -0
  29. package/dist/tools/render-definition.d.ts.map +1 -1
  30. package/dist/tools/render-definition.js +15 -1
  31. package/dist/tools/render-definition.js.map +1 -1
  32. package/dist/tools/update-and-publish.d.ts.map +1 -1
  33. package/dist/tools/update-and-publish.js +22 -10
  34. package/dist/tools/update-and-publish.js.map +1 -1
  35. package/dist/tools/update-definition.d.ts.map +1 -1
  36. package/dist/tools/update-definition.js +2 -7
  37. package/dist/tools/update-definition.js.map +1 -1
  38. package/dist/types/config.d.ts +6 -2
  39. package/dist/types/config.d.ts.map +1 -1
  40. package/dist/utils/error-guards.d.ts +21 -0
  41. package/dist/utils/error-guards.d.ts.map +1 -0
  42. package/dist/utils/error-guards.js +26 -0
  43. package/dist/utils/error-guards.js.map +1 -0
  44. package/dist/utils/logger.d.ts.map +1 -1
  45. package/dist/utils/logger.js +28 -3
  46. package/dist/utils/logger.js.map +1 -1
  47. package/dist/utils/read-yaml-file.d.ts.map +1 -1
  48. package/dist/utils/read-yaml-file.js +16 -1
  49. package/dist/utils/read-yaml-file.js.map +1 -1
  50. package/dist/utils/tool-handler.d.ts.map +1 -1
  51. package/dist/utils/tool-handler.js +20 -8
  52. package/dist/utils/tool-handler.js.map +1 -1
  53. package/package.json +21 -20
  54. package/dist/tools/check-forkable.d.ts.map +0 -1
  55. package/dist/tools/check-forkable.js.map +0 -1
  56. package/dist/tools/sync-models.d.ts +0 -12
  57. package/dist/tools/sync-models.d.ts.map +0 -1
  58. package/dist/tools/sync-models.js +0 -32
  59. package/dist/tools/sync-models.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,11 +7,136 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.4] - 2026-06-07
11
+
12
+ Docs + packaging polish. Adds the standard 5-badge set to the README matching the rest of the public UluOps packages, and closes a packaging hygiene gap — the package declared `"license": "MIT"` but shipped without the LICENSE file. No behavioural change.
13
+
14
+ ### Added
15
+
16
+ - LICENSE file (MIT, Copyright (c) 2026 UluOps) at the repo root. The package previously declared `"license": "MIT"` in `package.json` but the file was absent. Adding it makes the license terms reachable both from a GitHub-cloned consumer and from an unpacked npm tarball.
17
+ - LICENSE listed in the `files` array so it ships in the published tarball. Without this entry the LICENSE would have been added to the repo but excluded from the npm package — the same hygiene gap from a different angle.
18
+
19
+ ### Changed
20
+
21
+ - README header gains the five shields.io badges (npm version, MIT license, node engine, TypeScript 5.7+, tests passing) immediately under the package name, matching the `@uluops/core` package presentation. The tagline was already present from the v0.2.3 ship; this completes the visual alignment with the rest of the public UluOps surface. Tests badge points to `src/__tests__/` (the actual test home in this repo).
22
+
23
+ ## [0.2.3] - 2026-06-05
24
+
25
+ Polish release. Six tracker findings closed: documentation freshness,
26
+ filesystem availability + symlink hardening, src-tree naming alignment,
27
+ 402 upgrade-URL prompt-injection guard, and 19 lint warnings removed
28
+ from the security-boundary module.
29
+
30
+ ### Fixed
31
+
32
+ - **`readYamlFile` now wraps `realpathSync(WORKSPACE_DIR)` in a try/catch.** A typo'd `WORKSPACE_DIR` env var, an unmounted NFS path, or a fresh container where the dir hadn't been created yet previously threw an opaque `ENOENT` for the workspace root rather than the file the user actually asked about. The error message now names WORKSPACE_DIR explicitly and tells the user how to fix it.
33
+ - **`validateLogDir` now dereferences symlinks before the containment check (CWE-59).** A symlink at `LOG_DIR` could previously escape the cwd/`/tmp/` constraint because `resolve()` doesn't follow symlinks. Also dereferences the comparison anchors (cwd, `/tmp/`) so macOS's `/tmp` → `/private/tmp` symlink no longer breaks the legitimate `/tmp/...` case. Only active when `ENABLE_FILE_LOGGING=true`.
34
+ - **402 `upgradeUrl` now passes through a protocol/host guard before being embedded in MCP responses (CWE-601).** A compromised or malicious registry server could previously emit `javascript:`, `data:`, or off-domain URLs in the 402 response body, landing them in the consuming agent's context window as prompt-injection bait. The guard restricts the embedded URL to `https://` and host suffix `.uluops.ai` (or apex `uluops.ai`); anything else is dropped and the agent sees an upgrade message without a follow-able URL. Mirrors the SSRF defense in `config/index.ts`.
35
+
36
+ ### Changed
37
+
38
+ - **`src/tools/check-forkable.ts` renamed to `src/tools/is-forkable.ts`.** The file registers `is_forkable` (renamed in v1.13.0 of the legacy package); the source filename was a legacy artifact. Internal-only rename — the tool name, schema, and behavior are unchanged.
39
+ - **19 `@typescript-eslint/strict-boolean-expressions` lint warnings cleared from `sdk-error-mapper.ts`.** The security-boundary module is now lint-clean. Every implicit truthiness check was converted to explicit `!== undefined` / `!== ''` / `=== true` form. No behavior change — but the file is now easier to reason about as code paths near credential redaction.
40
+ - **`isApiKey` detection in `src/index.ts` uses explicit `=== true`** for the optional-chained `startsWith('ulr_')`. Same intent as before; falls through to session-token auth when `apiKey` is undefined. Linter-friendly.
41
+ - **README test count updated to 348** (was stale at 329).
42
+
43
+
44
+
45
+ Hardening pass against the ship-pipeline findings. No new tools. No
46
+ breaking changes to existing tool contracts (the new `render_definition`
47
+ `overwrite` parameter defaults to `false` — agents that previously
48
+ silently overwrote files now receive a clear error response and need to
49
+ opt in).
50
+
51
+ ### Fixed
52
+
53
+ - **`patchYamlVersion` now handles prerelease and build-metadata semver.**
54
+ The regex `\d+\.\d+\.\d+` was extended to `\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?(?:\+[A-Za-z0-9.-]+)?`. Previously, source YAML with `version: 1.0.0-rc.1` would leave the `-rc.1` suffix stranded after the replacement, producing malformed YAML that the API would reject. Closes the AF-006 audit trigger that was acknowledged at v0.2.0 ship time.
55
+ - **`update_and_publish` create-fallback now guards `created.version`.** A malformed SDK response with a missing `version` field would have been silently passed through to `publish()`, producing a `/versions/undefined` URL and a 404 for a draft that was just successfully created. The handler now throws a descriptive error if `created.version` is missing or empty.
56
+ - **`render_definition` no longer silently overwrites existing files.** New `overwrite: boolean` parameter (default `false`). When false (the default) and `output_path` resolves to an existing file, the tool returns a clear MCP error rather than destroying the prior content. Agents that need replacement semantics must explicitly pass `overwrite: true`.
57
+ - **`batch_publish` per-item errors now carry rich SDK context.** Previously each failed-item entry only carried `error` (message) and `status`. The per-item catch now routes through a new `extractErrorContext(error)` helper that surfaces 402 `upgrade_url` + `required_tier` + `current_tier`, 429 `retry_after`, and 409 `nextAvailable` exactly as single-call tools do via `mapSdkErrorToMcp`.
58
+ - **MCP server now auto-runs on the proper ESM entry-point check** instead of `NODE_ENV !== 'test'`. A stray `NODE_ENV=test` in the user's shell, CI, or `direnv` no longer silently disables `main()` — the harness would have started and hung waiting for stdio JSON-RPC that never arrived. Tests already import `main` directly and call it; no test changes needed.
59
+
60
+ ### Changed
61
+
62
+ - **`isNumericSchema` swapped Zod `_def.innerType` access for Zod's public `unwrap()` / `removeDefault()` API.** Avoids coupling to Zod private internals that can rename across minor versions and would silently disable numeric coercion at the MCP boundary if Zod's `_def` shape ever changes.
63
+ - **`isPublishedStatusError` extracted to a shared `src/utils/error-guards.ts` module.** Previously this 3-line guard was duplicated verbatim across `update-definition.ts` and `update-and-publish.ts`. A future change to the underlying API error message now updates one location instead of two.
64
+ - **Added `prepublishOnly: npm run build` script.** Future `npm publish` runs no longer rely on the maintainer remembering to build first.
65
+
66
+ ### Added
67
+
68
+ - **`extractErrorContext(error)` helper in `client/sdk-error-mapper.ts`** — returns the same structured fields (`status`, `required_tier`, `upgrade_url`, `retry_after`, `nextAvailable`) that `mapSdkErrorToMcp` produces, but without wrapping them in an MCP envelope. Used by `batch_publish`.
69
+
70
+ ### Tests
71
+
72
+ 348 tests pass (was 345, +3 regression coverage):
73
+ - New: `patches prerelease semver versions in yaml during create fallback`
74
+ - New: `refuses to overwrite an existing file when overwrite is not opted into`
75
+ - New: `writes to existing file when overwrite: true is passed`
76
+
77
+ ## [0.2.1] - 2026-06-05
78
+
79
+ ### Changed
80
+
81
+ - **Backend URL resolution deferred to the SDK.** Previously the MCP server
82
+ shadowed `@uluops/registry-sdk`'s `DEFAULT_BASE_URL` with its own copy
83
+ and effectively required `ULUOPS_REGISTRY_URL` (treating empty/undefined
84
+ as "use the shadow constant"). The SDK already resolves the correct
85
+ production URL (`https://api.uluops.ai/api/v1/registry`) by default and
86
+ switches to localhost when `NODE_ENV=development`; the MCP now passes
87
+ `baseUrl` through as `undefined` when the env var is unset/empty and lets
88
+ the SDK own URL resolution. Public consumers no longer set anything but
89
+ `ULUOPS_API_KEY`. README's configuration table reduced to consumer-
90
+ relevant variables; `ULUOPS_REGISTRY_URL` removed from the public
91
+ surface (still honored by the code when explicitly set).
92
+ - **SSRF defense and host allowlist now gate on `baseUrl !== undefined`.**
93
+ When the operator does not set `ULUOPS_REGISTRY_URL` the SDK uses a
94
+ trusted compile-time constant, so the URL-parse/allowlist/private-host
95
+ checks are skipped — they only run when an operator explicitly provides
96
+ a URL that needs validation. Identical behavior for any URL that was
97
+ previously accepted; previously-rejected URLs are still rejected.
98
+ - **Pairs with `@uluops/setup@0.6.4`** which stopped stamping
99
+ `ULUOPS_REGISTRY_URL` into `.mcp.json` files during onboarding, and with
100
+ `@uluops/ops-mcp@0.2.1` which applied the same fix to the ops tracker.
101
+
102
+ ### Internal
103
+
104
+ - `DEFAULT_BASE_URL` constant removed from `src/config/index.ts`.
105
+ - `ApiClientConfig.baseUrl` type widened to `string | undefined`.
106
+ - Startup log apiUrl line shows `(SDK default)` when baseUrl is unset.
107
+
108
+ ## [0.2.0] - 2026-06-05
109
+
110
+ First release of the monorepo `@uluops/registry-mcp` package at parity
111
+ with the standalone `uluops-registry-mcp` 0.1.1 codebase, prepared for
112
+ first public npm publish under the scoped name.
113
+
114
+ ### Added
115
+
116
+ - **`list_languages` and `get_language` tools** — language registry
117
+ read tools surfaced through the MCP server.
118
+
10
119
  ### Changed
11
120
 
12
- - Bumps `@uluops/sdk-core` from `^0.9.0` to `0.11.0` (exact pin) and `@uluops/registry-sdk`
13
- to `0.30.0` (exact pin). Aligns with the sdk-core schema-removal cascade. The MCP server's
14
- own Zod-based tool input parsing is unaffected — it never used sdk-core's `options.schema`.
121
+ - **`@uluops/registry-sdk` bumped `^0.27.2` `0.30.2`** (three minor
122
+ versions). Pulls in 0.29.0 publish-warning surfacing, 0.30.x sdk-core
123
+ security hardening cascade, and the schema-removal cleanup.
124
+ - **`@uluops/sdk-core` confirmed at `0.11.1`** with `redirect: 'error'`
125
+ on all fetch sites, control-character stripping, and widened sensitive-
126
+ key coverage (`x-api-key`, `set-cookie`, `proxy-authorization`).
127
+ - **All runtime and dev dependencies pinned to exact versions** per the
128
+ 2026-06-01 UluOps supply-chain hardening policy.
129
+ - **`vitest` and `@vitest/coverage-v8` bumped to `4.1.8`** — eliminates
130
+ the moderate-severity esbuild advisory chained through vite. `npm audit`
131
+ now reports 0 vulnerabilities.
132
+
133
+ ### Not included
134
+
135
+ - **`sync_models` admin tool deliberately excluded.** Calls a private
136
+ registry admin endpoint not exposed through the public SDK; reserved
137
+ for internal use and intentionally never shipped in this public package.
138
+
139
+ ### Historical lineage (legacy `uluops-registry-mcp` versions below)
15
140
 
16
141
  ## [1.14.0] - 2026-05-20
17
142
 
@@ -134,7 +259,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
134
259
  - Error sanitization stripping sensitive data (API keys, tokens, stack traces) from MCP responses
135
260
  - Test suite with 194 tests covering all tools, resources, and registry config
136
261
 
137
- [Unreleased]: https://github.com/Uluops/-uluops-registry-mcp/compare/v1.14.0...HEAD
262
+ [Unreleased]: https://github.com/Uluops/-uluops-registry-mcp/compare/v0.2.1...HEAD
263
+ [0.2.1]: https://github.com/Uluops/-uluops-registry-mcp/compare/v0.2.0...v0.2.1
264
+ [0.2.0]: https://github.com/Uluops/-uluops-registry-mcp/releases/tag/v0.2.0
138
265
  [1.14.0]: https://github.com/Uluops/-uluops-registry-mcp/compare/v1.13.0...v1.14.0
139
266
  [1.13.0]: https://github.com/Uluops/-uluops-registry-mcp/compare/v1.12.0...v1.13.0
140
267
  [1.12.0]: https://github.com/Uluops/-uluops-registry-mcp/compare/v1.11.0...v1.12.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UluOps
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,33 +1,34 @@
1
- # UluOps Registry MCP Client v1.1.0
1
+ **[UluOps](https://uluops.ai)** · Operating Intelligence as Infrastructure
2
2
 
3
- MCP (Model Context Protocol) client for the UluOps Registry API. Provides **31 tools** and **4 resources** that enable Claude Code to browse, create, validate, and manage AI workflow definitions (agents, commands, workflows, pipelines).
3
+ ---
4
4
 
5
- ## Quick Setup (30 seconds)
5
+ # @uluops/registry-mcp
6
6
 
7
- ```bash
8
- git clone git@github.com:Uluops/-uluops-registry-mcp.git
9
- cd -uluops-registry-mcp
10
- ./setup.sh YOUR_API_KEY
11
- ```
7
+ [![npm version](https://img.shields.io/npm/v/@uluops/registry-mcp.svg)](https://www.npmjs.com/package/@uluops/registry-mcp)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+ [![Node.js Version](https://img.shields.io/node/v/@uluops/registry-mcp)](https://nodejs.org)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg)](https://www.typescriptlang.org/)
11
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](src/__tests__/)
12
+
13
+ MCP (Model Context Protocol) server for the [UluOps](https://uluops.ai) Registry API. Provides **44 tools** and **4 resources** that let Claude Code, OpenCode, Gemini CLI, and other MCP-compatible harnesses browse, create, validate, version, and analyze AI workflow definitions (agents, commands, workflows, pipelines).
12
14
 
13
- The setup script installs dependencies, builds the project, and prints the `.mcp.json` config snippet to paste into your project or `~/.claude/.mcp.json`.
15
+ ## Quick start
14
16
 
15
- Or do it manually:
17
+ The recommended way to install this is via [@uluops/setup](https://www.npmjs.com/package/@uluops/setup), which writes the MCP config for you:
16
18
 
17
19
  ```bash
18
- npm install && npm run build
20
+ npx @uluops/setup
19
21
  ```
20
22
 
21
- Then add to your `.mcp.json`:
23
+ If you'd rather wire it up by hand, add this block to your harness's MCP config (e.g. `~/.claude.json` for Claude Code, `~/.config/opencode/opencode.json` for OpenCode):
22
24
 
23
25
  ```json
24
26
  {
25
27
  "mcpServers": {
26
28
  "uluops-registry": {
27
- "command": "node",
28
- "args": ["/absolute/path/to/registry-uluops-mcp/dist/index.js"],
29
+ "command": "npx",
30
+ "args": ["-y", "@uluops/registry-mcp"],
29
31
  "env": {
30
- "ULUOPS_REGISTRY_URL": "http://localhost:3001/api/v1",
31
32
  "ULUOPS_API_KEY": "your-api-key"
32
33
  }
33
34
  }
@@ -35,39 +36,35 @@ Then add to your `.mcp.json`:
35
36
  }
36
37
  ```
37
38
 
38
- Restart Claude Code to pick up the new server.
39
-
40
- ## Design Philosophy
41
-
42
- **Thin Client Pattern**: This MCP client contains **zero business logic**. All data processing, validation, storage, and rendering are handled by the registry API. The client's sole responsibility is protocol translation between MCP's stdio-based JSON-RPC and the backend's REST API.
39
+ Get an API key at [app.uluops.ai/settings/api-keys](https://app.uluops.ai/settings/api-keys), then restart your harness.
43
40
 
44
41
  ## Configuration
45
42
 
46
- All configuration is passed via environment variables in the `env` block of `.mcp.json`. No `.env` file needed.
43
+ All configuration is passed via environment variables in the `env` block. No `.env` file is needed.
47
44
 
48
45
  | Variable | Description | Required | Default |
49
46
  |----------|-------------|----------|---------|
50
- | `ULUOPS_REGISTRY_URL` | Registry API URL | Yes | - |
51
- | `ULUOPS_API_KEY` | API authentication key | Yes | - |
52
- | `ULUOPS_REGISTRY_TIMEOUT` | Request timeout (ms) | No | 30000 |
53
- | `ULUOPS_REGISTRY_RETRIES` | Retry attempts | No | 3 |
54
- | `LOG_LEVEL` | Logging level | No | info |
55
- | `ENABLE_FILE_LOGGING` | Write logs to disk | No | false |
56
- | `LOG_DIR` | Log file directory | No | ./logs |
57
- | `VERBOSE_LOGGING` | Verbose security decision logging | No | false |
58
- | `LOG_PERFORMANCE_METRICS` | Log performance metrics | No | false |
47
+ | `ULUOPS_API_KEY` | API authentication key | Yes | |
48
+ | `ULUOPS_ORG_SLUG` | Organization slug for scoped requests | No | |
49
+ | `ULUOPS_REGISTRY_TIMEOUT` | Request timeout (ms) | No | `30000` |
50
+ | `ULUOPS_REGISTRY_RETRIES` | Retry attempts | No | `3` |
51
+ | `LOG_LEVEL` | Logging level (`error`, `warn`, `info`, `debug`) | No | `info` |
52
+ | `ENABLE_FILE_LOGGING` | Write logs to disk | No | `false` |
53
+ | `LOG_DIR` | Log file directory | No | `./logs` |
54
+ | `VERBOSE_LOGGING` | Verbose security decision logging | No | `false` |
55
+ | `LOG_PERFORMANCE_METRICS` | Log performance metrics | No | `false` |
59
56
  | `WORKSPACE_DIR` | Base directory for `file_path` containment (CWE-22 protection) | No | cwd |
60
57
  | `OUTPUT_BASE_DIR` | Base directory for `output_path` containment (CWE-22 protection) | No | cwd |
61
58
 
62
- A `.env.example` is included as a template showing available variables. This file is **not** auto-loaded — copy it to `.env` or set variables directly in `.mcp.json`.
59
+ ## Design philosophy
63
60
 
64
- ## Quick Start Examples
61
+ **Thin client pattern.** This MCP server contains **zero business logic**. All data processing, validation, storage, and rendering are handled by the registry API. The server's sole responsibility is protocol translation between MCP's stdio JSON-RPC and the backend REST API.
65
62
 
66
- Once configured, Claude Code can use the registry tools:
63
+ ## Quick examples
67
64
 
68
- ```jsonc
69
- // These are MCP tool calls — Claude Code invokes them automatically.
65
+ Once configured, your harness can invoke these tools through MCP:
70
66
 
67
+ ```jsonc
71
68
  // Browse published definitions
72
69
  list_definitions({ "type": "agent", "status": "published", "limit": 10 })
73
70
 
@@ -77,93 +74,114 @@ get_definition({ type: "agent", name: "code-validator", include_yaml: true })
77
74
  // Search across all definition types
78
75
  search_definitions({ query: "validation", type: "agent" })
79
76
 
80
- // Resolve a model alias
81
- resolve_alias({ alias: "sonnet" })
82
-
83
- // Validate YAML before publishing
77
+ // Validate YAML before publishing (inline or by file path)
84
78
  validate_definition({ type: "agent", yaml: "..." })
85
-
86
- // Or validate from a file path instead of inline YAML
87
79
  validate_definition({ type: "agent", file_path: "/path/to/agent.yaml" })
88
80
 
89
81
  // Create and publish a definition
90
- create_definition({ type: "agent", name: "my-agent", yaml: "name: my-agent\nversion: 1.0.0\n..." })
82
+ create_definition({ type: "agent", name: "my-agent", yaml: "..." })
91
83
  publish_definition({ type: "agent", name: "my-agent", version: "1.0.0" })
92
84
 
93
- // Compare versions — section summary (default)
94
- diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0" })
85
+ // One-call create-or-update-and-publish
86
+ update_and_publish({ type: "agent", name: "my-agent", version: "1.1.0", yaml: "..." })
95
87
 
96
- // Compare versions structural diff with classification
97
- diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0", format: "fields" })
98
- // Returns: fields[], classified[], suggestedBump, summary, sections
88
+ // Compare versions in three different formats
89
+ diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0" }) // section summary
90
+ diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0", format: "fields" }) // structural diff + suggested bump
91
+ diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0", format: "unified" }) // git-style diff
99
92
 
100
- // Compare versions — unified line diff
101
- diff_versions({ type: "agent", name: "code-validator", from: "1.0.0", to: "1.1.0", format: "unified" })
102
- // Returns: unified (git-style diff string)
93
+ // Analytics
94
+ get_effectiveness({ type: "agent", name: "code-validator", version: "1.1.0" })
95
+ compare_effectiveness({ type: "agent", name: "code-validator", versions: ["1.0.0", "1.1.0"] })
103
96
  ```
104
97
 
105
- ## Available Tools
98
+ ## Available tools
106
99
 
107
- ### Core Tools (P0)
100
+ ### Core tools (P0)
108
101
  | Tool | Description |
109
102
  |------|-------------|
110
103
  | `list_definitions` | List definitions with filters (type, status, domain, visibility, search, tags, pagination) |
111
- | `get_definition` | Get a single definition by type+name, optionally with YAML/runtime/refs |
104
+ | `get_definition` | Get a single definition by type + name, optionally with YAML / runtime / refs |
112
105
  | `search_definitions` | Search definitions by keyword |
113
106
  | `list_models` | List AI models with optional filters |
114
- | `resolve_alias` | Resolve alias (e.g. "sonnet") to provider+modelId |
107
+ | `resolve_alias` | Resolve an alias (e.g. `sonnet`) to provider + modelId |
115
108
  | `validate_definition` | Validate YAML without storing (accepts `yaml` or `file_path`) |
116
- | `render_definition` | Get rendered markdown for a definition. Use `output_path` to write directly to a file |
109
+ | `render_definition` | Get rendered markdown for a definition. `output_path` writes directly to a file |
117
110
 
118
- ### Definition Management Tools (P1)
111
+ ### Definition management (P1)
119
112
  | Tool | Description |
120
113
  |------|-------------|
121
114
  | `create_definition` | Create a new draft definition (accepts `yaml` or `file_path`) |
122
- | `update_definition` | Update a draft definition (`yaml`/`file_path`, visibility, description, tags). Smart version-up: if the target version is published or doesn't exist and YAML is provided, automatically creates a new draft instead of failing |
115
+ | `update_definition` | Update a draft definition. Smart version-up: if target version is published or doesn't exist and YAML is provided, automatically creates a new draft |
123
116
  | `publish_definition` | Publish a draft definition |
124
117
  | `deprecate_definition` | Deprecate with reason and optional successor |
118
+ | `archive_definition` | Archive a deprecated definition (terminal lifecycle state) |
125
119
  | `delete_definition` | Delete a draft (published definitions cannot be deleted) |
126
120
 
127
- ### Version & Dependency Tools (P1)
121
+ ### Composite workflows (P1)
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `update_and_publish` | Update a draft and publish it in one call. Inherits smart version-up + create fallback from `update_definition` |
125
+ | `batch_publish` | Publish up to 20 definition versions in one call. Continues on individual failures, returns both published and failed items |
126
+
127
+ ### Versions & dependencies (P1)
128
128
  | Tool | Description |
129
129
  |------|-------------|
130
130
  | `list_versions` | List all versions of a definition |
131
- | `diff_versions` | Compare two versions. Supports `format`: `sections` (default summary), `fields` (structural diff with classification + suggested bump), `unified` (git-style line diff) |
131
+ | `diff_versions` | Compare two versions. `format`: `sections` (default), `fields` (structural + suggested bump), `unified` (git-style) |
132
132
  | `get_dependencies` | Forward dependency graph |
133
133
  | `get_dependents` | Reverse dependency graph |
134
134
  | `get_execution_stats` | Execution statistics for a definition version |
135
135
  | `list_forks` | List forks of a definition |
136
136
 
137
- ### Fork Tools (P2)
137
+ ### Forks (P2)
138
138
  | Tool | Description |
139
139
  |------|-------------|
140
140
  | `fork_definition` | Fork a definition |
141
141
  | `is_forkable` | Check if a definition version can be forked |
142
142
  | `get_fork_lineage` | Fork ancestry chain |
143
143
 
144
- ### Translation Tools (P2)
144
+ ### Translation (P2)
145
145
  | Tool | Description |
146
146
  |------|-------------|
147
147
  | `retranslate_definition` | Retranslate with the latest translator version |
148
148
  | `upgrade_definition` | Upgrade a definition from legacy format (accepts `yaml` or `file_path`) |
149
149
  | `get_translator_version` | Get current translator version |
150
150
 
151
- ### Model Tools (P2)
151
+ ### Models & languages (P2)
152
152
  | Tool | Description |
153
153
  |------|-------------|
154
- | `get_model` | Get specific model details by provider+modelId |
154
+ | `get_model` | Get specific model details by provider + modelId |
155
155
  | `list_providers` | List AI providers |
156
156
  | `list_aliases` | List all model aliases |
157
- | `sync_models` | Sync model catalog (admin) |
157
+ | `list_languages` | List supported definition languages (ADL, CDL, WDL, PDL) |
158
+ | `get_language` | Get a definition language with its current JSON Schema |
158
159
 
159
- ### Execution & User Tools (P2)
160
+ ### Execution & users (P2)
160
161
  | Tool | Description |
161
162
  |------|-------------|
162
163
  | `record_execution` | Record a definition execution (idempotent) |
163
164
  | `get_user` | Get public user profile |
164
165
  | `batch_users` | Batch user lookup (max 100) |
165
166
 
166
- ## Available Resources
167
+ ### Analytics (P3)
168
+ | Tool | Description |
169
+ |------|-------------|
170
+ | `get_effectiveness` | Effectiveness metrics for a definition: pass rate, scores, taxonomy, health score |
171
+ | `get_health` | Health grade and issue profile for a definition |
172
+ | `get_ecosystem_overview` | Ecosystem-wide analytics overview |
173
+ | `get_lineage` | Lineage graph for a definition (versions + forks as a tree) |
174
+ | `get_evolution` | Version-over-version metrics with trend detection |
175
+ | `get_translation_analytics` | Versions grouped by translator version with aggregate metrics |
176
+ | `compare_effectiveness` | Compare effectiveness across 2–5 definition versions side-by-side |
177
+ | `get_diff_impact` | Structural diff combined with metric deltas between two versions |
178
+
179
+ ### Session
180
+ | Tool | Description |
181
+ |------|-------------|
182
+ | `set_default_type` | Set (or clear) a session-level default for the `type` parameter. When set, definition tools use this type unless explicitly overridden |
183
+
184
+ ## Available resources
167
185
 
168
186
  MCP resources provide read-only access to registry data via the `registry://` URI scheme.
169
187
 
@@ -171,58 +189,47 @@ MCP resources provide read-only access to registry data via the `registry://` UR
171
189
  |----------|-----|-------------|
172
190
  | Definitions | `registry://definitions` | Published definitions (up to 100) |
173
191
  | Models | `registry://models` | AI model catalog |
174
- | Definition Types | `registry://definition-types` | Static list: agent, command, workflow, pipeline |
192
+ | Definition types | `registry://definition-types` | Static list: agent, command, workflow, pipeline |
175
193
  | Providers | `registry://providers` | AI provider list |
176
194
 
177
- ### Resource Usage
178
-
179
195
  ```typescript
180
- // List published definitions
181
196
  read_resource("registry://definitions")
182
-
183
- // Browse available AI models
184
197
  read_resource("registry://models")
185
-
186
- // Get supported definition types with descriptions
187
198
  read_resource("registry://definition-types")
188
199
  ```
189
200
 
190
- ## Rate Limiting Configuration
201
+ ## Rate limiting
191
202
 
192
- This client uses [mcp-secure-server](https://github.com/anthropics/mcp-secure-server) with configuration optimized for Claude Code's usage patterns. Source of truth: `src/index.ts` (global) and `src/config/tool-registry.ts` (per-tool).
203
+ This server uses [mcp-secure-server](https://github.com/aself101/mcp-secure-server) with configuration tuned for typical harness usage patterns. Source of truth: `src/index.ts` (global) and `src/config/tool-registry.ts` (per-tool).
193
204
 
194
205
  | Setting | Value | Notes |
195
206
  |---------|-------|-------|
196
207
  | Security level | `basic` | |
197
208
  | Max requests/min | 120 | Global rate limit |
198
209
  | Burst threshold | 15 | Requests within burst window |
199
- | Burst window | 5000ms | |
200
- | Automation detection | Disabled | Claude Code is trusted automation |
210
+ | Burst window | 5000 ms | |
211
+ | Automation detection | Disabled | The calling harness is trusted automation |
201
212
 
202
- Per-tool quotas are configured in `src/config/tool-registry.ts`. Read-heavy tools (list, get, search) allow up to 240 req/min. Write tools (create, update, publish) are 30-60 req/min. Admin operations like `sync_models` are tightly limited (10 req/min).
213
+ Per-tool quotas are configured in `src/config/tool-registry.ts`. Read-heavy tools (list, get, search) allow up to 240 req/min. Write tools (create, update, publish) are 3060 req/min.
203
214
 
204
215
  ## Development
205
216
 
206
217
  ```bash
207
- # Install dependencies
218
+ git clone git@github.com:Uluops/-uluops-registry-mcp.git
219
+ cd -uluops-registry-mcp
208
220
  npm install
209
-
210
- # Development mode with watch
211
- npm run dev
212
-
213
- # Run tests
214
- npm test
215
-
216
- # Type checking
221
+ npm run build
222
+ npm test # 348 tests
217
223
  npm run typecheck
218
-
219
- # Linting
220
224
  npm run lint
221
-
222
- # Build for production
223
- npm run build
224
225
  ```
225
226
 
227
+ ## Requirements
228
+
229
+ - **Node.js:** ≥ 18
230
+ - **Platform:** Linux, macOS, or WSL2
231
+ - **Auth:** UluOps API key ([get one here](https://app.uluops.ai/settings/api-keys))
232
+
226
233
  ## License
227
234
 
228
235
  MIT
@@ -12,6 +12,35 @@ import type { McpToolResponse } from '../types/index.js';
12
12
  * and truncation.
13
13
  */
14
14
  export declare const sanitizeErrorMessage: typeof sanitizeString;
15
+ export interface ExtractedErrorContext {
16
+ /** Sanitized human-readable message. */
17
+ message: string;
18
+ /** HTTP status code if available on the SDK error. */
19
+ status?: number;
20
+ /** 402-only: tier required for access. */
21
+ required_tier?: string;
22
+ /** 402-only: caller's current tier. */
23
+ current_tier?: string;
24
+ /** 402-only: definition reference. */
25
+ definition?: {
26
+ type?: string;
27
+ name?: string;
28
+ };
29
+ /** 402-only: upgrade URL (mcp-source-tagged). */
30
+ upgrade_url?: string;
31
+ /** 409-only: next available version hint. */
32
+ nextAvailable?: unknown;
33
+ /** 429-only: server-recommended retry delay in seconds. */
34
+ retry_after?: number;
35
+ }
36
+ /**
37
+ * Extract the same structured-error fields as `mapSdkErrorToMcp` produces,
38
+ * but without wrapping them in an `McpToolResponse`. Useful inside batch
39
+ * loops where each per-item failure should embed the rich error context
40
+ * (402 upgrade URL, 429 retry-after, 409 nextAvailable) into the parent
41
+ * response rather than producing one MCP error envelope per failure.
42
+ */
43
+ export declare function extractErrorContext(error: unknown): ExtractedErrorContext;
15
44
  /**
16
45
  * Map an SDK error to an MCP tool response.
17
46
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sdk-error-mapper.d.ts","sourceRoot":"","sources":["../../src/client/sdk-error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,uBAAiB,CAAC;AAkCnD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAqGhE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAahE"}
1
+ {"version":3,"file":"sdk-error-mapper.d.ts","sourceRoot":"","sources":["../../src/client/sdk-error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,uBAAiB,CAAC;AA6DnD,MAAM,WAAW,qBAAqB;IACpC,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAuDzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAkHhE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAahE"}