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
Merge origin/main into feature/add-datasource-relevance-filter
Resolved conflict in src/tools/datasources.py by adapting the query
relevance filter to main's dict envelope convention:
- get_data_sources now returns {dataSources, hint} (from main) and
additionally carries a `message` field when `query` is supplied
- Empty results use a query-specific hint (_DATASOURCES_EMPTY_QUERY_HINT)
instead of the 'add a repository' hint when filtering yields nothing
- Tests updated from json.loads(JSON string) assertions to dict shape
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4. Tool translates MCP call to CodeAlive API request (with `X-CodeAlive-*` headers)
121
-
5. Response parsed, formatted as XML or text, returned to AI client
121
+
5. Response parsed and returned to the AI client — as a `dict` for metadata/discovery tools, as an XML string for `fetch_artifacts`, or as plain text for `chat`
122
122
123
123
### Environment Variables
124
124
@@ -172,6 +172,17 @@ This project uses **loguru** for structured JSON logging. All logs go to **stder
172
172
173
173
7.**Use `logger.configure(patcher=...)` for global context injection** (like OTel trace_id). Do NOT pass `patcher` to `logger.add()` — loguru 0.7.x does not support it there.
174
174
175
+
8.**Tool-call failures are warnings with full structured arguments.** Do not log MCP
176
+
tool-call failures as `error` unless the whole server process is failing. A bad
177
+
tool call is recoverable input for the model loop, same as backend agent tools.
178
+
Log it as `logger.warning(..., tool_arguments={...})` or with `.bind(tool_arguments=...)`.
179
+
Do not redact `tool_arguments` in the logger path; the purpose is to recover the
180
+
exact failing invocation. Authorization headers remain masked via `log_api_request()`.
181
+
182
+
9.**Tool-call lifecycle logs are debug.** The per-tool "started" and "completed"
183
+
messages from `ObservabilityMiddleware` must be `logger.debug`, not `logger.info`.
184
+
Info-level logs should not be emitted for every agent step/tool step.
185
+
175
186
### OTel Trace Correlation
176
187
177
188
Every log record automatically gets `trace_id` and `span_id` injected by `_otel_patcher` (registered via `logger.configure`). The `ObservabilityMiddleware` also uses `logger.contextualize(trace_id=..., tool=...)` so all logs within a tool call carry the correlation ID. Do not duplicate this — it's automatic.
@@ -194,29 +205,79 @@ The `ObservabilityMiddleware` creates a span per tool call with these attributes
194
205
195
206
On errors, the span gets `StatusCode.ERROR` + `record_exception()`. Do not add redundant span creation inside tool functions — the middleware handles it.
196
207
208
+
#### Required MCP observability fix pattern
209
+
210
+
When touching MCP tool observability, update both the generic middleware and the
211
+
tool-specific body:
212
+
213
+
- In `src/middleware/observability_middleware.py`, extract tool arguments from
214
+
the incoming `tools/call` message (FastMCP currently exposes this through the
215
+
message payload; keep the extraction defensive). Add them to the log context,
216
+
e.g. `with logger.contextualize(trace_id=trace_id, tool=tool_name,
must log these branches as Warning with full arguments:
232
+
233
+
```python
234
+
tool_arguments = {
235
+
"identifier": identifier,
236
+
"profile": profile,
237
+
"max_count_per_type": max_count_per_type,
238
+
}
239
+
```
240
+
241
+
- missing/empty `identifier`
242
+
-`max_count_per_type` outside `1..1000`
243
+
- unsupported `profile` fallback branch
244
+
- backend `HTTPStatusError` / unexpected exception before delegating to
245
+
`handle_api_error(...)`
246
+
247
+
The API request/response helpers stay `Debug` and keep their existing masking
248
+
rules. Do not put raw response bodies into warning logs.
249
+
197
250
### Adding New Tools — Observability Checklist
198
251
199
252
When adding a new tool, ensure:
200
253
1. The tool receives `ctx: Context` as its first argument (required for lifespan context and logging)
201
254
2. API requests include all four `X-CodeAlive-*` headers: `Integration`, `Tool`, `Client`, plus `Authorization`
202
255
3. Call `log_api_request()` before and `log_api_response()` after the HTTP call
203
-
4. Errors go through `handle_api_error(ctx, e, "description", method=_TOOL_NAME)` — this ensures the `[tool_name]` prefix in error messages
256
+
4. Errors are logged as Warning with full `tool_arguments` before they go through `handle_api_error(ctx, e, "description", method=_TOOL_NAME)` — this ensures the `[tool_name]` prefix in error messages and preserves the exact failed call in logs
204
257
5. The middleware automatically wraps the tool in an OTel span — no manual span creation needed
205
258
206
259
## Tool Response Conventions
207
260
208
-
### Response format: dict for metadata, XML for content
209
-
210
-
Tools that return **search metadata** (identifiers, match counts, line numbers)
211
-
return a `dict`. FastMCP serializes it automatically via `pydantic_core.to_json`,
212
-
which preserves Unicode — no manual `json.dumps()` needed. Examples:
Copy file name to clipboardExpand all lines: README.md
+49-12Lines changed: 49 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -140,8 +140,8 @@ Replace `YOUR_API_KEY_HERE` with your actual API key.
140
140
**Option 1: Remote HTTP (Recommended)**
141
141
142
142
1. Open Cursor → Settings (`Cmd+,` or `Ctrl+,`)
143
-
2. Navigate to **"MCP"** in the left panel
144
-
3. Click **"Add new MCP server"**
143
+
2. Navigate to **"Tools & MCP"** in the left panel (older builds called this **"Tools & Integrations"**)
144
+
3. Click **"New MCP Server"**
145
145
4. Paste this configuration:
146
146
147
147
```json
@@ -157,7 +157,9 @@ Replace `YOUR_API_KEY_HERE` with your actual API key.
157
157
}
158
158
```
159
159
160
-
5. Save and restart Cursor
160
+
5. Save — Cursor reloads the server automatically. The entry is stored in `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global).
161
+
162
+
> **Tip:** Cursor also supports a one-click install deeplink — `cursor://anysphere.cursor-deeplink/mcp/install?name=codealive&config=BASE64_CONFIG`. Only follow deeplinks from trusted sources.
161
163
162
164
**Option 2: Docker (STDIO)**
163
165
@@ -179,29 +181,64 @@ Replace `YOUR_API_KEY_HERE` with your actual API key.
179
181
</details>
180
182
181
183
<details>
182
-
<summary><b>Codex</b></summary>
184
+
<summary><b>Codex (CLI, App, IDE Extension)</b></summary>
185
+
186
+
OpenAI Codex ships in three form-factors that **share the same configuration**: the **Codex CLI**, the **Codex App** (macOS / Windows), and the **Codex IDE Extension** (VS Code `openai.chatgpt` and JetBrains 2025.3+). All three read `~/.codex/config.toml`, so one snippet covers every Codex surface. A project-level `.codex/config.toml` in the repo root is also supported for trusted projects.
183
187
184
-
OpenAI Codex CLI supports MCP via `~/.codex/config.toml`.
> **Note:** Streamable HTTP support requires `rmcp_client = true` under a `[features]` section in your Codex configuration.
212
+
> **Note:** Streamable HTTP requires `[features].rmcp_client = true`. The old top-level `experimental_use_rmcp_client = true` flag is deprecated. `bearer_token_env_var` is preferred over inline `headers = { Authorization = "Bearer …" }` because it keeps secrets out of the config file.
No `[features]` flag is needed for stdio. `env_vars` forwards values from the parent shell — safer than embedding the key in `args`.
239
+
240
+
**Codex App UI:** Settings → MCP Servers → Add Server. The UI writes the same `~/.codex/config.toml` entry. The CLI and IDE extension pick it up automatically.
Copy file name to clipboardExpand all lines: manifest.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
"manifest_version": "0.4",
3
3
"name": "codealive-mcp",
4
4
"display_name": "CodeAlive",
5
-
"version": "2.0.3",
5
+
"version": "2.0.4",
6
6
"description": "Semantic code search and codebase Q&A for Claude Desktop using your CodeAlive account or self-hosted deployment.",
7
7
"long_description": "CodeAlive gives Claude Desktop access to semantic code search, artifact fetch, repository discovery, and architecture-aware codebase Q&A. This extension runs locally via MCP and supports both CodeAlive Cloud and self-hosted deployments.",
0 commit comments