Commit 07eaa94
feat: IDE-aware datamate transport, enabled-state persistence, and /mcps command (#893)
* feat: datamate stdio local transport + extension single-gateway mode
- Add stdio transport support for datamate MCP (vs HTTP-only before)
- Single-gateway mode: when .vscode/mcp.json has "datamate" key, always
use it as server name — prevents duplicate tool sets from extension
- syncDatamateUrlFromVscodeMcp: use updatedAt field as change signal for
the "datamate" entry (works for both stdio and HTTP), URL comparison
for all other remote entries
- Strip ALTIMATE_EXTENSION_RPC from persisted mcp-discover configs to
avoid stale socket paths across VS Code sessions
- persistMcpEnabled: write enabled/disabled flag to disk on MCP
connect/disconnect so it survives session restarts
- Add /altimate/mcp/reload-datamate endpoint to re-sync and reconnect
without full server restart
- MCP.ToolsChanged subscription in prompt loop for traceability
- Merge main: preserve trace consumer in serve.ts, restore exports on
isAnthropicLikeModel and insertReminders
* feat: [AI-6948] register mcps slash command in server command list (#885)
Co-authored-by: saravmajestic <saravmajestic@altimate.ai>
* fix: address review comments + stale config cache in reload-datamate + improve logging
* refactor: replace hardcoded IDE paths with glob scan for mcp.json
Instead of checking .vscode/mcp.json, .cursor/mcp.json, and
.github/copilot/mcp.json separately, scan all mcp.json files
under the project root and use the first one that contains a
datamate entry. This is IDE-agnostic and will work with any
editor that writes an mcp.json.
- Remove IDE_MCP_SOURCES constant
- Add findAllMcpJsonFiles() using Glob.scan(**/mcp.json)
- Add extractServersMap() helper to try both "servers" and "mcpServers" keys
- Update readDatamateTransportFromIde() and syncDatamateUrlFromVscodeMcp()
to use the new scan approach
* fix(mcps): bypass LLM for /mcps list, enable, disable commands
Add direct handler in SessionPrompt.command for the mcps slash command.
Instead of routing through the AI template, the handler calls MCP.status(),
MCP.connect(), and MCP.disconnect() directly and returns a structured
MessageV2.WithParts response, matching the TUI HTTP API behavior.
- /mcps (no args): queries MCP.status() and renders a markdown table
- /mcps enable <name>: calls MCP.connect(name) and reports result
- /mcps disable <name>: calls MCP.disconnect(name) and confirms
* fix(mcps): move /mcps bypass handler before Command.get() check
The /mcps direct handler was added after the Command.get() call and
"Command not found" error, so it never fired — /mcps was not in
the registered commands list and would throw before reaching the bypass.
Move the handler to run before Command.get() so it short-circuits
cleanly for the built-in /mcps, /mcps enable, and /mcps disable
commands without requiring a registered command entry.
* fix(mcp-discover): strip enabled:false when explicitly adding server to config
* fix(mcp-discover): set enabled:true when user explicitly adds server to config
When the user asks to add an MCP server via /discover-and-add-mcps, the
config entry should have enabled:true so /mcps shows it as connected.
Previously the strip of the auto-discovery enabled:false left no enabled
field, which caused ambiguity in the UI even though mcp/index.ts treats
missing as enabled=true at runtime.
* fix(mcp-discover): add updatedAt timestamp and connect MCP immediately after config write
- Add updatedAt: new Date().toISOString() when writing MCP server to config so
clients can detect config changes without restarting
- Call MCP.connect(name) immediately after addMcpToConfig so the server becomes
active in the current session — /mcps now shows connected without restart
* chore: move isAnthropicLikeModel NOTE docblock back above function
* chore: strip altimate_change markers from altimate/ subtree, inline DATAMATE_KEY
* fix: address review comments — glob ignore, type guard, persist from disk, dedup respond()
* fix: add model param to respond() helper — was undefined in closure causing no-reply on /mcps
* fix: [AI-6948] discover MCPs from project root instead of git worktree
`/discover-and-add-mcps` found no servers (and auto-discovery added none) for
non-git projects: `Instance.worktree` resolves to "/" when there is no `.git`,
so the scan looked under the filesystem root and missed the workspace's
`.vscode/mcp.json` (datamate). The `add` action also resolved its
project-scoped config path against "/".
- `mcp-discover.ts`: use `Instance.directory` (project root) instead of
`Instance.worktree` for the discovery scan, persisted-name read, and the
project-scoped config write target
- `config.ts`: same `Instance.worktree` -> `Instance.directory` for the
background auto-discovery caller
- `discover.ts`: replace the hardcoded IDE paths with a recursive
`**/mcp.json` glob scan rooted at the project directory (IDE-agnostic,
trying both `servers` and `mcpServers` keys), keeping the non-`mcp.json`
sources (`.mcp.json`, `.gemini/settings.json`, `~/.claude.json`)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: [AI-6948] address PR review — preserve MCP config fields on disk writes
Resolves the review findings on the `/mcps` enable/disable persistence and
datamate transport sync paths.
- `mcp/config.ts`: `readMcpEntryFromDisk` now uses `getNodeValue` instead of a
manual children walk. `jsonc-parser` only populates `Node.value` for
primitives, so the old walk silently dropped `command` arrays and
`environment`/`headers` objects — corrupting local stdio (and remote-with-
headers) entries on the next write via `persistMcpEnabled`.
- `altimate/datamate-transport.ts`: same `getNodeValue` fix for the two sibling
walkers; preserve non-transport fields (`enabled`, `timeout`, `oauth`, …) when
rebuilding the synced datamate entry; widen the `**/mcp.json` ignore list
(`target`, `.next`, `out`, `vendor`, `coverage`, `.venv`, `.turbo`).
- `mcp/index.ts`: serialize `persistMcpEnabled` (promise chain) so concurrent
enable/disable can't interleave read-modify-write and clobber each other.
- `server/server.ts`: `reload-datamate` returns HTTP 500 (not 200) on error so
the extension can distinguish failure.
- `session/prompt.ts`: `/mcps enable|disable` validates the server name against
config and reports clearly when it's unknown (was silent).
- `test/mcp/config.test.ts`: add `readMcpEntryFromDisk` round-trip tests,
including the persist-enabled flow that previously corrupted local entries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: [AI-6948] preserve IDE source precedence in mcp.json glob scan
The `**/mcp.json` glob scan sorted purely alphabetically, which let
`.cursor/mcp.json` override `.vscode/mcp.json` for same-named servers — a
regression vs the previous fixed-source order (.vscode > .cursor >
.github/copilot). Caught by the `discover-adversarial` precedence test.
Order globbed files by IDE precedence first, then alphabetically, restoring
first-source-wins semantics while staying IDE-agnostic for any other mcp.json.
Also align the ignore list with `datamate-transport.ts`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: [AI-6948] balance altimate_change markers (CI Marker Guard + integrity tests)
Two pre-existing marker imbalances on the branch failed the "Require-markers
regression backstop" job and the `altimate_change marker integrity` tests
(origin/main is balanced; these were introduced by earlier merge commits on
this branch):
- `cli/cmd/serve.ts` (6 start / 4 end): close the trace-import region after its
import, and close the branding region after the rebranded log line (the
sync-datamate region stays nested inside it).
- `session/prompt.ts` (43 start / 44 end): remove a duplicate `altimate_change
end` left by a merge — the MCP-ToolsChanged region is already closed before
`while (true)`, and the SessionStatus region right after has its own pair.
Comment-only changes; no behavior impact. Verified with
`bun run script/upstream/analyze.ts --require-markers --strict` (38/38) and the
marker-integrity suites (118/0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: saravmajestic <saravmajestic@altimate.ai>
Co-authored-by: altimate-harness-bot[bot] <274995457+altimate-harness-bot[bot]@users.noreply.github.com>
Co-authored-by: Saravanan <sarav.majestic@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent ae69109 commit 07eaa94
13 files changed
Lines changed: 906 additions & 34 deletions
File tree
- packages/opencode
- src
- altimate
- tools
- cli/cmd
- command
- config
- mcp
- server
- session
- util
- test/mcp
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
0 commit comments