You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Per-platform allowed tools — explicit defaults exported from cyrus-core — cyrus-core now exports three canonical lists (LINEAR_DEFAULT_ALLOWED_TOOLS, SLACK_DEFAULT_ALLOWED_TOOLS, GITHUB_DEFAULT_ALLOWED_TOOLS) plus a getDefaultAllowedTools(platform) resolver. Each list is completely explicit — workspace MCP prefixes (mcp__linear, mcp__cyrus-tools, mcp__cyrus-docs, and for Slack mcp__slack) are members of the list, not implicitly appended at runtime. cyrus-hosted imports the same constants so the source of truth lives in one place. (CYHOST-967)
EdgeConfig accepts slackAllowedTools and githubAllowedTools — two optional top-level keys for team-level platform overrides. When unset, the resolver falls back to the matching cyrus-core default. (CYHOST-967)
EdgeConfig accepts slackMcpConfigs, linearMcpConfigs, githubMcpConfigs — three optional arrays of filesystem paths to custom-integration .mcp.json files, one per surface. Slack chat sessions load the files in slackMcpConfigs directly (chat is repo-agnostic, no repository.mcpConfigPath lookup). Linear- and GitHub/GitLab-triggered issue sessions use the per-platform list only when the routed repo does NOT have its own allowedTools override; if the repo has its own allow-list, the agent uses repository.mcpConfigPath instead so the repo's permission rules and its server set always come from the same scope. Native MCP servers (Linear, Cyrus tools, Cyrus docs, and Slack when SLACK_BOT_TOKEN is set) are still spun up inline by the runtime — these lists govern custom integrations only. (CYHOST-967)
Changed
Claude sessions now run with strictMcpConfig: true. Per Claude Code's --strict-mcp-config semantics, the SDK now only uses MCP servers explicitly passed via mcpConfig / mcpServers — it will not silently pick up servers from the user's ~/.claude.json, project .mcp.json, or any other ambient configuration. Closes a gap where unrelated MCP servers on the host could bleed into a session and grant tools the agent shouldn't have. (CYHOST-967)
ToolPermissionResolver is now additive-only — no implicit MCP appending, no SLACK_BOT_TOKEN-conditional injection. Previously buildAllowedTools and buildChatAllowedTools appended mcp__linear, mcp__cyrus-tools, mcp__cyrus-docs (and conditionally mcp__slack when SLACK_BOT_TOKEN was set in the process env) to every returned list. Now the explicit per-platform defaults include those prefixes verbatim, the resolver returns lists as-is, and getWorkspaceMcpTools() is removed. The "readOnly" preset now resolves to SLACK_DEFAULT_ALLOWED_TOOLS (the curated read-only set) instead of the bare getReadOnlyTools() list. (CYHOST-967)
GitHub- and GitLab-triggered sessions now go through buildGithubAllowedTools. EdgeWorker previously called buildAllowedTools(repository).filter(t => t !== "mcp__slack") — a subtractive hack to strip the auto-appended Slack MCP prefix. With explicit defaults the filter is unnecessary, and routing through buildGithubAllowedTools means the team's githubAllowedTools override actually takes effect. (CYHOST-967)
Slack chat sessions no longer pull the "first repo's" mcpConfigPath. Chat sessions are repo-agnostic at the session level, so the prior fallback that loaded whichever repo happened to be configured first into the chat session's MCP set is gone. Slack now loads exactly the files in slackMcpConfigs (which cyrus-hosted derives from the team's Slack allowed-tools array); native MCP servers continue to run inline. (CYHOST-967)
EdgeConfig.defaultAllowedTools renamed to linearAllowedTools. Reflects what it actually controls (Linear-triggered sessions specifically, not a global default). The legacy field is still accepted on parse and migrated forward so older self-host configs keep working. (CYHOST-967)
Self-reported failure modes. Every customer-facing agent session now has access to a new mcp__cyrus-tools__log_failure_mode MCP tool and is instructed (via a shared system-prompt addendum appended to all Linear prompt flavors, the Slack entrypoint, and the GitHub entrypoint) to call it when the user expresses dissatisfaction or when it recognizes it has made 3+ unsuccessful attempts at the same problem. The tool POSTs to cyrus-hosted, which opens (or comments on) a Linear ticket in the internal failure-modes project so the Cyrus team can intervene before churn. Self-reporting is internal — users are not told about it. (CYPACK-1226)
Fixed
slackAllowedTools, githubAllowedTools, and the per-platform MCP config keys (slackMcpConfigs, linearMcpConfigs, githubMcpConfigs) are now honored after config hot-reload.ConfigManager.loadConfigSafely() previously merged a hardcoded whitelist of fields from the parsed config.json and silently dropped every per-platform allow-list / MCP config key, so Slack and GitHub sessions kept resolving to the cyrus-core defaults even when the workspace had a tighter override on disk. The merge and the change-detection list now include all six platform keys. (CYHOST-967)
Self-Managed GitLab MR replies — EdgeWorker was instantiating GitLabCommentService with no apiBaseUrl, so every MR-reply request on a Self-Managed instance hit gitlab.com and 404'd. The base URL is now derived from the URL origin of the first configured repo with a gitlabUrl, so MR replies post against the correct host. Thanks @tenforty (#1191)
Stop hook no longer blocks sessions for pre-existing untracked files — Replaces the previous unconditional first-stop block (CYPACK-1204) with a more targeted git-aware guardrail. Cyrus now scopes the end-of-session check to tracked changes and unpushed commits, ignoring stray untracked files (local scratch files, env files, IDE artifacts) outside .gitignore. New files Cyrus creates via Write/Edit are still flagged via git add --intent-to-add if left uncommitted, so the "forgot to ship new work" check is preserved. (CYPACK-1196, #1204)
Security
Patched 4 transitive dependency advisories — Bumped pnpm.overrides for brace-expansion (≥5.0.6, DoS via large numeric ranges defeating max protection), ws (≥8.20.1, uninitialized memory disclosure on close() with TypedArray reason), protobufjs (≥7.5.8, DoS via unbounded recursive JSON descriptor expansion), and uuid (≥11.1.1, missing buffer bounds check in v3/v5/v6). pnpm audit now reports zero advisories. (CYPACK-1230, #1238)
Patched 9 transitive dependency advisories — Bumped pnpm.overrides for hono (≥4.12.18, fixes CSS injection / JWT validation / Cache Middleware cross-user leakage), fast-uri (≥3.1.2, path traversal + host confusion), ip-address (≥10.1.1, Address6 XSS), @anthropic-ai/sdk (≥0.91.1, insecure default file permissions in local filesystem memory tool), and @opentelemetry/sdk-node / @opentelemetry/exporter-prometheus (≥0.217.0, Prometheus exporter process crash via malformed HTTP request). pnpm audit now reports zero advisories. (CYPACK-1206)