Skip to content
Merged
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
24 changes: 14 additions & 10 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -910,16 +910,6 @@ <h2>Browser Rendering</h2>
</div>
</details>
</div>
<div class="section">
<h2>Skills</h2>
<p style="font-size:11px;color:var(--muted);margin-bottom:6px">Skills are SKILL.md files the agent loads on demand. Built-in skills ship with Dodo; personal skills you author here. Workspace skills (per-session, from <code>.dodo/skills/</code> etc.) are not shown here.</p>
<div id="skills-list"></div>
</div>
<div class="section">
<h2>Tools</h2>
<p style="font-size:11px;color:var(--muted);margin-bottom:6px">Tools available to the agent. Dimmed entries are gated on session config (codemode, browser) or reachable only inside a codemode block (most git ops). Configure MCP integrations below to add more.</p>
<div id="tool-catalog-list"></div>
</div>
<div class="section">
<h2>Integrations</h2>
<div id="integrations-list"></div>
Expand All @@ -934,6 +924,20 @@ <h2>Integrations</h2>
<button onclick="addIntegration()">Add</button>
</details>
</div>
<div class="section">
<details>
<summary><h2 style="display:inline;margin:0">Skills</h2></summary>
<p style="font-size:11px;color:var(--muted);margin-bottom:6px">Skills are SKILL.md files the agent loads on demand. Built-in skills ship with Dodo; personal skills you author here. Workspace skills (per-session, from <code>.dodo/skills/</code> etc.) are not shown here.</p>
<div id="skills-list"></div>
</details>
</div>
<div class="section">
<details>
<summary><h2 style="display:inline;margin:0">Tools</h2></summary>
<p style="font-size:11px;color:var(--muted);margin-bottom:6px">Tools available to the agent. Dimmed entries are gated on session config (codemode, browser) or reachable only inside a codemode block (most git ops). Configure MCP integrations above to add more.</p>
<div id="tool-catalog-list"></div>
</details>
</div>
<div class="section">
<h2>Secrets</h2>
<div id="passkey-status"></div>
Expand Down
42 changes: 23 additions & 19 deletions src/user-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1468,25 +1468,29 @@ export class UserControl extends DurableObject<Env> {
this.ctx.storage.sql.exec("INSERT OR IGNORE INTO user_config (key, value, updated_at) VALUES (?, ?, ?)", key, String(value), now);
}

const existingCount = (Array.from(this.ctx.storage.sql.exec("SELECT COUNT(*) AS n FROM approved_mcps WHERE is_deleted = 0"))[0] as SqlRow | null);
if (Number(existingCount?.n ?? 0) === 0) {
const { getDeployMcpCatalog } = await import("./mcp-catalog");
const seedNow = Date.now();
for (const entry of getDeployMcpCatalog(this.env)) {
this.ctx.storage.sql.exec(
`INSERT INTO approved_mcps (mcp_url, id, display_name, description, setup_guide, known_hosts, auth_type, status, is_deleted, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 'enabled', 0, ?, ?)`,
entry.url,
entry.id,
entry.name,
entry.description ?? null,
entry.setupGuide ?? null,
JSON.stringify(entry.knownHosts ?? []),
entry.auth_type ?? "static_headers",
seedNow,
seedNow,
);
}
// Seed `approved_mcps` from the code-level catalog. We use `INSERT OR IGNORE`
// keyed by `mcp_url` so:
// - On first run, every catalog entry is inserted.
// - On subsequent runs, only NEW entries (not yet in the table) are
// inserted; admin-edited rows and soft-deleted rows are preserved.
// This is how adding a new entry to `mcp-catalog.ts` propagates to all
// existing UserControl DOs without an explicit migration.
const { getDeployMcpCatalog } = await import("./mcp-catalog");
const seedNow = Date.now();
for (const entry of getDeployMcpCatalog(this.env)) {
this.ctx.storage.sql.exec(
`INSERT OR IGNORE INTO approved_mcps (mcp_url, id, display_name, description, setup_guide, known_hosts, auth_type, status, is_deleted, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 'enabled', 0, ?, ?)`,
entry.url,
entry.id,
entry.name,
entry.description ?? null,
entry.setupGuide ?? null,
JSON.stringify(entry.knownHosts ?? []),
entry.auth_type ?? "static_headers",
seedNow,
seedNow,
);
}
}

Expand Down