Skip to content
Draft
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
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,11 @@ you to run `ucode <agent>` (existing agent sessions need a restart before the MC
#### Add skill scopes without replacing existing ones

`ucode skill add` registers skills additively, keeping anything already configured. With `--mcp` it
adds the schemas to the connection's scope, otherwise it downloads their skills to disk. `--skills`
narrows a download to a subset of one schema's skills. With no selection flags, a searchable picker
lists finalized skills visible in the metastore.
adds the schemas to every configured agent's scope, or only to `--agents` when supplied. Agents that
are not configured yet are set up first. Without `--mcp`, it downloads skills to disk; download mode
always writes both directory families and does not accept `--agents`. `--skills` narrows a download
to a subset of one schema's skills. With no selection flags, a searchable picker lists finalized
skills visible in the metastore.

```bash
# Browse the metastore and choose skills to download.
Expand All @@ -236,6 +238,9 @@ ucode skill add
# Add schemas to the skills MCP scope, keeping any already configured.
ucode skill add --location main.default,ml.prod --mcp

# Add a schema only to selected agents.
ucode skill add --location main.default --mcp --agents claude,codex

# Download a schema's skills to disk, keeping existing downloads.
ucode skill add --location main.default

Expand Down Expand Up @@ -380,6 +385,7 @@ The output looks like:
| `ucode configure skills --location main.default --mcp` | Expose a schema's skills as MCP tools (override-only) instead of downloading |
| `ucode skill add` | Interactively choose finalized metastore skills to download |
| `ucode skill add --location main.default --mcp` | Add schemas to the skills MCP scope, keeping any already configured (additive; never replaces) |
| `ucode skill add --location main.default --mcp --agents claude` | Set up selected agents if needed and add schemas only to their MCP scopes |
| `ucode skill add --location main.default` | Download a schema's skills to disk without removing existing downloads |
| `ucode skill add --skills main.default.my-skill` | Download a named subset of skills (bare names need `--location`; fully-qualified names stand alone) |
| `ucode setup` | Author the managed config's agents and models (workspace admins only) |
Expand Down
58 changes: 47 additions & 11 deletions src/ucode/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
purge_cross_workspace_mcp_residue,
remove_mcp_command,
revert_mcp_configs,
skill_locations_for_client,
)
from ucode.skills_download import (
configure_skills_download_command,
Expand Down Expand Up @@ -1068,17 +1069,31 @@ def status() -> int:
if not skill_mcp_entry:
print_kv("Skills", "not configured")
else:
locations = skill_mcp_entry.get("skill_locations") or []
print_kv(
"Skill MCP Locations",
", ".join(locations) if locations else "none — utility tools only",
)
configured_agents = [
str(MCP_CLIENTS[client]["display"])
for client in (skill_mcp_entry.get("clients") or [])
if client in MCP_CLIENTS
configured_clients = [
client for client in (skill_mcp_entry.get("clients") or []) if client in MCP_CLIENTS
]
print_kv("Configured", ", ".join(configured_agents) if configured_agents else "none")
scopes = {
client: skill_locations_for_client(skill_mcp_entry, client)
for client in configured_clients
}
if len({tuple(locations) for locations in scopes.values()}) <= 1:
locations = next(
iter(scopes.values()), list(skill_mcp_entry.get("skill_locations") or [])
)
print_kv(
"Skill MCP Locations",
", ".join(locations) if locations else "none — utility tools only",
)
configured_agents = [
str(MCP_CLIENTS[client]["display"]) for client in configured_clients
]
print_kv("Configured", ", ".join(configured_agents) if configured_agents else "none")
else:
for client, locations in scopes.items():
print_kv(
f"{MCP_CLIENTS[client]['display']} skill MCP locations",
", ".join(locations) if locations else "none — utility tools only",
)

print_heading("Tracing")
tracing = state.get("tracing") or {}
Expand Down Expand Up @@ -1353,6 +1368,14 @@ def skills_add(
"Not valid with --mcp.",
),
] = None,
agents: Annotated[
str | None,
typer.Option(
"--agents",
help="(--mcp only) Comma-separated coding agents whose skills MCP scope should "
"be updated. Any that aren't configured yet are set up first.",
),
] = None,
) -> None:
"""Add Databricks Skills to your coding tools, keeping any already configured.

Expand All @@ -1369,6 +1392,11 @@ def skills_add(
requested_skills = (
None if skills is None else {s.strip() for s in skills.split(",") if s.strip()}
)
requested_agents = (
None
if agents is None
else ({agent.strip().lower() for agent in agents.split(",") if agent.strip()} or None)
)
if mcp and path is not None:
raise RuntimeError("--path is not supported when using --mcp")
if mcp and requested_skills is not None:
Expand All @@ -1389,6 +1417,8 @@ def skills_add(
"`<catalog>.<schema>.<name>` values "
f"(invalid: {', '.join(sorted(invalid_skills))})."
)
if not mcp and agents is not None:
raise RuntimeError("--agents is only supported when using --mcp")
if requested_skills is not None and not locations:
schemas = {".".join(parts[:2]) for parts in qualified_skill_parts.values()}
bare = sorted(skill for skill in requested_skills if skill not in qualified_skill_parts)
Expand Down Expand Up @@ -1426,7 +1456,13 @@ def skills_add(
None if requested_skills is None else {s.split(".")[-1] for s in requested_skills}
)
if mcp:
add_skills_command(locations)
scope = (
_configure_agents_for_mcp(sorted(requested_agents)) if requested_agents else None
)
if scope is None:
add_skills_command(locations)
else:
add_skills_command(locations, agents=scope)
else:
configure_skills_download_command(locations, path=path, skills=selected_skills)
except (RuntimeError, ValueError) as exc:
Expand Down
Loading
Loading