## MODIFIED Requirements ### Requirement: MCP tools for skill discovery and retrieval The system SHALL expose `list_skills`, `search_skills`, and `get_skill` as MCP tools on the same MCP server surface used for device capabilities. The tools SHALL present a unified catalog merged from cloud-synced skills and local skills (delegating to the `local-skill-management` read-merge surface), and SHALL return each skill with an `origin` of `"cloud"` or `"local"` and a `locally_overridden` flag when a local override shadows a cloud skill. The responses SHALL NOT expose any entitlement, subscription, or cloud-management-internal fields to the LLM. #### Scenario: LLM lists available skills across both origins - **WHEN** an MCP client calls `list_skills` - **THEN** it receives the merged set of cloud-synced and local skills visible to it, each with id, name, description, kind, tags, `origin`, and `locally_overridden` #### Scenario: LLM searches across both origins - **WHEN** an MCP client calls `search_skills` with a query string - **THEN** it receives matching skills from both origins ranked by relevance, each tagged with `origin` #### Scenario: LLM fetches a skill, observing any active override - **WHEN** an MCP client calls `get_skill` with a skill id that has an active local override - **THEN** it receives the override's content, tagged `origin = "cloud"` and `locally_overridden = true` ### Requirement: Skill MCP errors are semantic The system SHALL translate skill-level errors (skill not found, skill not visible/entitled, invalid/unavailable flow template, and authoring errors such as attempting to delete a cloud skill with no override) into clear, semantic MCP tool error responses, consistent in style with the device-capability tool error handling. A request for a cloud skill that is unknown or not visible to the caller SHALL produce an indistinguishable not-found error (no existence leak). #### Scenario: Requesting a non-visible cloud skill - **WHEN** `get_skill` is called with a cloud skill id that exists but is not visible to the caller's host and has no override - **THEN** the tool returns a semantic "not found" error rather than a raw database or internal exception #### Scenario: Deleting a cloud skill that has no override - **WHEN** `delete_skill` is called with a cloud skill id that has no local override - **THEN** the tool returns a semantic error indicating there is no local override to remove, without revoking any cloud entitlement ## ADDED Requirements ### Requirement: Authoring MCP tools dispatch by origin The system SHALL expose `create_skill`, `update_skill`, and `delete_skill` as MCP tools on the agent's MCP server, always registered (no enable/disable gate). Their behaviour SHALL dispatch by the target skill's origin: `create_skill` creates a new local skill; `update_skill` edits a local skill or creates/updates a local override for a cloud skill; `delete_skill` deletes a local skill or removes a local override for a cloud skill. None of these tools SHALL ever write to the synced store or mutate a cloud skill directly; override semantics are governed by the `local-skill-management` capability. #### Scenario: Create a new local skill - **WHEN** the LLM calls `create_skill` with content for a new skill - **THEN** a new local skill is created with `origin = "local"` and is thereafter discoverable via the read tools #### Scenario: Update dispatches by origin - **WHEN** the LLM calls `update_skill` with a local skill id - **THEN** the local skill is edited; and **WHEN** called with a cloud skill id - **THEN** a local override for that cloud id is created or updated (the cloud/synced store is untouched) #### Scenario: Delete dispatches by origin - **WHEN** the LLM calls `delete_skill` with a local skill id - **THEN** the local skill is deleted; and **WHEN** called with a cloud skill id that has an override - **THEN** the override is removed and the cloud skill resurfaces on the next read