MCPcopy Create free account
hub / github.com/FSoft-AI4Code/CodeWiki / CawBackend

Class CawBackend

codewiki/src/be/caw_backend.py:123–324  ·  view source on GitHub ↗

Routes LLM operations through the claude / codex CLI subscription.

Source from the content-addressed store, hash-verified

121_patch_codex_tool_timeout()
122# --- end stopgap --------------------------------------------------------------
123
124
125# --- claude-code allowedTools stopgap -----------------------------------------
126# Custom MCP-server tools (added via `--mcp-config`) are not auto-approved under
127# `acceptEdits`, and `bypassPermissions` may be disabled by an org managed
128# policy (see the cwd note below), so caw's `--dangerously-skip-permissions`
129# alone is not enough: CodeWiki's own toolkit (str_replace_editor,
130# read_code_components, generate_sub_module_documentation) gets denied
131# ("you haven't granted it yet"), the agent writes nothing, and the run
132# "succeeds" with an empty module tree. Grant the toolkit explicitly with
133# `--allowedTools` using the permission rule syntax:
134# https://code.claude.com/docs/en/settings#permission-rule-syntax
135# `--allowedTools` flag: https://code.claude.com/docs/en/cli-reference
136# caw's ClaudeCodeSession only ever emits `--disallowedTools`, so rewrite its
137# `claude` command to add `--allowedTools mcp__<server>` for every server in
138# the --mcp-config. The patch swaps the `subprocess` module reference INSIDE
139# caw.providers.claude_code for a thin proxy — the global subprocess.Popen
140# class stays untouched (isinstance / subclass safe) and no other claude
141# invocation in this process is affected. Belongs upstream in caw; remove
142# once it grows a first-class allowed_tools knob for its toolkit servers.
143_CLAUDE_ALLOWED_PATCH_APPLIED = False
144
145
146def _with_allowed_tools(cmd):
147 """Append ``--allowedTools mcp__<server>,...`` to a ``claude`` command.
148
149 Pure ``list -> list`` transform. Applies only when *cmd* is a claude
150 invocation carrying ``--mcp-config`` and no explicit allow-list already;
151 otherwise (or on any error) *cmd* is returned unchanged.
152 """
153 import json
154
155 try:
156 if not (
157 isinstance(cmd, (list, tuple))
158 and cmd
159 and os.path.basename(str(cmd[0])) == "claude"
160 and "--mcp-config" in cmd
161 and "--allowedTools" not in cmd
162 and "--allowed-tools" not in cmd
163 ):
164 return cmd
165 # caw emits a single `--mcp-config <path>`; only the first occurrence
166 # is considered.
167 cfg_path = cmd[list(cmd).index("--mcp-config") + 1]
168 with open(cfg_path) as f:
169 servers = list(json.load(f).get("mcpServers", {}).keys())
170 if not servers:
171 return cmd
172 allowed = ",".join(f"mcp__{s}" for s in servers)
173 logger.info("Injected --allowedTools for MCP servers: %s", servers)
174 return list(cmd) + ["--allowedTools", allowed]
175 except Exception as e: # noqa: BLE001 — never break the spawn on a patch hiccup
176 logger.warning("claude allowedTools patch skipped: %s", e)
177 return cmd
178
179
180def _patch_claude_allowed_tools() -> None:

Callers 1

get_backendFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected