Skip to content

Add local MCP dogfood testing workflow - #49

Merged
SPerekrestova merged 2 commits into
mainfrom
devin/1781092086-mcp-dogfood-testing
Jun 15, 2026
Merged

Add local MCP dogfood testing workflow#49
SPerekrestova merged 2 commits into
mainfrom
devin/1781092086-mcp-dogfood-testing

Conversation

@SPerekrestova

Copy link
Copy Markdown
Owner

Summary

Adds a deterministic dogfood path that runs the built MCP server exactly like a client would: npm run dogfood:local builds build/index.js, spawns it over stdio with StdioClientTransport, injects the existing e2e nock preload fixture, isolates HOME, and drives a user-like flow through:

listTools → runner_doctor → start_problem → request_hint → run_local_tests → get_session_state

The smoke covers available local runners (python3, go, java) without requiring LeetCode credentials or live network access, so Devin/CI-like environments can validate the MCP behavior directly. It also documents a second path for a real local Claude/agent setup, including the MCP config command and a copy-paste prompt for testing the server as a practicing user while avoiding accidental live submissions.

Verified locally with npm run build, npm run test:types, npx prettier --check ., npm run dogfood:local, npm test, and npm run test:e2e.

Link to Devin session: https://app.devin.ai/sessions/3e6f3e63f6e54852b9bf6da1c792774f
Requested by: @SPerekrestova

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7cdde504-e75b-4e43-8afd-47e8ac01aad9

📥 Commits

Reviewing files that changed from the base of the PR and between 4d44985 and 1655a2b.

📒 Files selected for processing (1)
  • scripts/dogfood-local.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/dogfood-local.ts

📝 Walkthrough

Walkthrough

Adds a local dogfood testing workflow: a new scripts/dogfood-local.ts runner that spawns the built MCP server over stdio with an isolated HOME and nock fixture preload, drives a sequence of MCP tool calls (runner_doctor, start_problem, request_hint, run_local_tests, get_session_state), and validates results. Wired via dogfood:local npm script and documented in DOGFOOD_TESTING.md and README.md.

Changes

Dogfood Local Testing Runner

Layer / File(s) Summary
Dogfood runner script implementation
scripts/dogfood-local.ts
Defines constants, fixture data, and per-language runner smoke configurations; implements JSON parsing helpers for MCP text responses; spawns the server via StdioClientTransport with isolated HOME and NODE_OPTIONS preload; validates run_local_tests results via assertRunPassed; orchestrates the full tool-call sequence in main() including server lifecycle management and cleanup.
npm script and TypeScript config
package.json, tsconfig.test.json
Adds dogfood:local npm script that builds and runs the dogfood runner; expands tsconfig.test.json to include scripts/**/*.ts for TypeScript compilation.
Documentation
DOGFOOD_TESTING.md, README.md
DOGFOOD_TESTING.md documents both the deterministic local run and local-agent dogfooding workflows with commands, expected behaviors, and guidance on which approach to use. README.md adds a Dogfood Testing section linking to the full workflow documentation.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch devin/1781092086-mcp-dogfood-testing

Comment @coderabbitai help to get the list of available commands and usage tips.

@SPerekrestova SPerekrestova left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for correctness. Two concrete issues to address in scripts/dogfood-local.ts:

  1. stderr: "pipe" is set on StdioClientTransport but never drained — risk of the server deadlocking once stderr exceeds the pipe buffer (~64 KB), especially during Go/Java runs.
  2. home and fixtureDir are mkdtemp'd before client.connect(), but a connect failure bypasses main's finally { cleanup }, leaving temp dirs (and possibly the child process) leaked.

Rest LGTM — fixture/preload reuse is clean, the runtime-availability gate is sensible, and the typed JSON unwrap is solid.


Generated by Claude Code

Comment thread scripts/dogfood-local.ts Outdated
args: [SERVER_BIN],
env,
cwd: REPO_ROOT,
stderr: "pipe"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deadlock risk: stderr: "pipe" without a consumer.

When StdioClientTransport is configured with stderr: "pipe", the child's stderr is piped to a Readable that the caller is expected to drain. This script never reads from transport.stderr, so once the child writes ~64 KB of stderr the OS pipe buffer fills and the server blocks on its next write. That can hang the smoke (notably on the Go/Java runs, where compilation diagnostics or logger output land on stderr).

The existing e2e harness (tests/e2e/harness/spawn-server.ts:114) uses stderr: "inherit" precisely to avoid this. Recommend matching that, or alternatively piping transport.stderr to process.stderr after connect.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1655a2b: switched the dogfood transport to stderr: "inherit", matching the e2e harness so server stderr is continuously drained by the parent process.

Comment thread scripts/dogfood-local.ts Outdated
home,
cleanup: async () => {
try {
await client.close();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temp directories leak if client.connect fails.

spawnDogfoodServer mkdtemps home and fixtureDir (and writes fixture.json) before calling client.connect(transport). If connect throws (transport spawn failure, handshake error, preload exit-1 from a bad fixture), the function rejects without returning the SpawnedDogfoodServer, so main's finally { await spawned.cleanup() } never runs and both temp dirs are leaked in os.tmpdir() for every failed run. The spawned child process can also leak depending on how the SDK handles a partial start.

The e2e harness handles this with try { await client.connect(transport); } catch (e) { await cleanup(); throw e; } — worth mirroring here.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1655a2b: spawnDogfoodServer() now builds a cleanup closure before client.connect(), calls it on connect failure, and then rethrows so temp dirs are removed even if spawn/handshake/preload setup fails.

@SPerekrestova
SPerekrestova merged commit 8b5c19b into main Jun 15, 2026
2 checks passed
@SPerekrestova
SPerekrestova deleted the devin/1781092086-mcp-dogfood-testing branch June 15, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant