Skip to main content

field-test

Exercise git tools, resources, and prompts against a live HTTP server via MCP JSON-RPC over curl. Starts the server, surfaces the catalog, runs real and adversarial inputs, and produces a tight report with concrete findings and numbered follow-up options. Use after adding or modifying definitions, or when the user asks to test, try out, or verify the MCP surface.

Informations de source

Dépôt
cyanheads/git-mcp-server
Dernière activité de la source
23 avril 2026 à 21:27
Langue détectée de SKILL.md
anglais
Étoiles
243
Forks
58

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
field-test
description
Exercise git tools, resources, and prompts against a live HTTP server via MCP JSON-RPC over curl. Starts the server, surfaces the catalog, runs real and adversarial inputs, and produces a tight report with concrete findings and numbered follow-up options. Use after adding or modifying definitions, or when the user asks to test, try out, or verify the MCP surface.
metadata
{"author":"cyanheads","version":"1.0","type":"debug"}
## Context Unit tests verify handler logic with mocked context. Field testing exercises the real HTTP transport with real JSON-RPC: starts the server, calls `initialize`, surfaces the catalog, runs inputs, and checks what a client actually sees. It catches what unit tests miss — awkward input shapes, unhelpful errors, missing `responseFormatter` output, drift between `structuredContent` and `content[]`, edge-case surprises, and git-specific behavior around conflicts, bare repos, protected branches, working directory state, etc. **Actively call the tools. Don't read code and guess.** For git tools specifically: prefer a throwaway test repo (`/tmp/field-test-repo` initialized with `git init` and a seed commit) over the project itself so state changes are bounded and easy to clean up. --- ## Steps ### 1. Start the server Write the helper to `/tmp/mcp-field-test.sh` once, then source it in every subsequent Bash call. Helper keeps PID / URL / session id in `/tmp/mcp-field-test.env` so state survives across tool invocations. ```bash cat > /tmp/mcp-field-test.sh <<'HELPER_EOF' #!/bin/bash # Field-test helper: manage an MCP HTTP server + JSON-RPC session across shell calls. STATE_FILE="/tmp/mcp-field-test.env" [ -f "$STATE_FILE" ] && . "$STATE_FILE" mcp_start() { local dir="${1:-$PWD}" echo "building $dir ..." (cd "$dir" && bun run rebuild) >/tmp/mcp-build.log 2>&1 \ || { echo "BUILD FAILED — see /tmp/mcp-build.log"; return 1; } echo "starting server ..." (cd "$dir" && bun run start:http) >/tmp/mcp-server.log 2>&1 & local pid=$! local line="" for _ in $(seq 1 40); do line=$(grep -Eo 'listening at http://[^" ]+/mcp' /tmp/mcp-server.log | head -1) [ -n "$line" ] && break sleep 0.25 done if [ -z "$line" ]; then echo "server failed to start — see /tmp/mcp-server.log" kill "$pid" 2>/dev/null return 1 fi local url="${line#listening at }" local port; port=$(echo "$url" | sed -E 's|.*:([0-9]+)/.*|\1|') cat > "$STATE_FILE" <<EOF export MCP_PID=$pid export MCP_URL=$url export MCP_PORT=$port EOF . "$STATE_FILE" echo "ready pid=$pid url=$url" } mcp_init() { [ -z "$MCP_URL" ] && { echo "run mcp_start first"; return 1; } local hdr="/tmp/mcp-init-headers.txt" curl -sS -D "$hdr" -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"field-test","version":"1.0"}}}' >/dev/null local sid; sid=$(grep -i '^mcp-session-id:' "$hdr" | awk '{print $2}' | tr -d '\r\n') [ -z "$sid" ] && { echo "no session id returned"; return 1; } cat > "$STATE_FILE" <<EOF export MCP_PID=$MCP_PID export MCP_URL=$MCP_URL export MCP_PORT=$MCP_PORT export MCP_SID=$sid EOF . "$STATE_FILE" curl -sS -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Mcp-Session-Id: $sid" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized"}' >/dev/null echo "session=$sid" } # Usage: mcp_call METHOD [JSON_PARAMS] # Prints the JSON-RPC response (SSE framing stripped). Pipe to `jq`. mcp_call() { [ -z "$MCP_SID" ] && { echo "run mcp_init first"; return 1; } local method="$1"; local params="${2:-}" local body if [ -z "$params" ]; then body=$(printf '{"jsonrpc":"2.0","id":%d,"method":"%s"}' "$RANDOM" "$method") else body=$(printf '{"jsonrpc":"2.0","id":%d,"method":"%s","params":%s}' "$RANDOM" "$method" "$params") fi curl -sS -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Mcp-Session-Id: $MCP_SID" \ -d "$body" | sed -n 's/^data: //p' } mcp_stop() { [ -n "$MCP_PID" ] && kill "$MCP_PID" 2>/dev/null rm -f "$STATE_FILE" echo "stopped" } HELPER_EOF . /tmp/mcp-field-test.sh mcp_start /Users/casey/Developer/github/git-mcp-server ``` **Notes** - `MCP_HTTP_PORT` is a _starting_ port — the server auto-increments if taken. Helper parses the real URL from the log (`HTTP transport listening at ...`). - If `bun run rebuild` fails, stop. Don't field-test broken code — fix the build first. - If a server is already listening on the project's port (`lsof -i :<port>`), confirm with the user before killing it; it may be their own session. - `MCP_AUTH_MODE=none` is the default dev configuration — no auth headers needed. ### 2. Initialize the session ```bash . /tmp/mcp-field-test.sh mcp_init ``` Runs `initialize`, captures the session id, sends `notifications/initialized`. ### 3. Prepare a test repository Most git tools require a working directory. Create a sandboxed repo once: ```bash TEST_REPO=/tmp/field-test-repo rm -rf "$TEST_REPO" && mkdir -p "$TEST_REPO" (cd "$TEST_REPO" && \ git init -q && \ git config user.email "field-test@example.com" && \ git config user.name "Field Test" && \ echo "initial" > README.md && \ git add README.md && \ git commit -q -m "initial commit") echo "test repo ready at $TEST_REPO" ``` Pass `$TEST_REPO` as the `path` argument in tool calls (never `.`, since that resolves to session state). For tests that don't need a repo (e.g. `git_clone`, `git_set_working_dir`), use `/tmp/field-test-dest` or similar. ### 4. Surface the catalog ```bash . /tmp/mcp-field-test.sh mcp_call tools/list | jq '.result.tools[] | {name, description, inputSchema}' mcp_call resources/list | jq '.result.resources[] | {uri, name, mimeType}' mcp_call prompts/list | jq '.result.prompts[] | {name, description, arguments}' ``` Present a compact catalog to the user: each definition's name + 1-line description. Flag vague or missing descriptions as you go — those feed into the report. ### 5. Plan the test pass **Budget.** This server exposes ~29 git tools. Don't run every category against every tool — the cross-product is infeasible. Apply the **universal battery** to everything; apply **situational categories** only when the tool triggers them. **Universal battery — run on every tool** | Category | What to verify | | :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ | | Happy path | One realistic input against `$TEST_REPO`. Output shape matches `outputSchema`. `content[]` text reads clearly to a human. | | `structuredContent` ↔ `content[]` parity | Every field in `structuredContent` is surfaced in the text. Parity gap = client-specific blindness. | | Input error | One invalid input (wrong type or missing required). Error text says _what_, _why_, _how to fix_. | **Situational — add only when triggered** | Trigger | Add category | | :--------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | | `verbosity` / `fields` / `include` parameter | Field selection: verify `minimal` / `standard` / `full` actually differ | | Array return with `query` / `filter` inputs (e.g. `git_log`) | Empty result: does response explain _why_ (echo criteria, suggest broadening)? | | Destructive flags (`--hard`, `--force`, `git_clean`) | Confirm guard: does the tool require explicit flag to proceed? | | Conflict-producing operations (`git_merge`, `git_rebase`, `git_cherry_pick`, `git_pull`) | Construct a conflict on purpose; confirm `{ success: true, conflicts: true, conflictedFiles: [...] }` shape | | Requires remote (`git_fetch`, `git_pull`, `git_push`, `git_clone`) | Either point at a local bare repo file:// URL or skip with a note | | Bare-repo-only behavior (`git_init --bare`) | Verify `isBare: true` surfaces; verify `git_add`/`git_commit` reject | | `annotations.readOnlyHint: true` | Confirm no mutation happened | | Session working directory (`path: "."`) | Run `git_set_working_dir`, then a read-only tool with `path: "."` to confirm resolution | | Chained workflows (status → add → commit → log) | Run one representative chain end-to-end | **Resources.** `git-working-directory.resource.ts`: happy path, unset state (before `git_set_working_dir` is called). **Prompts.** `git-wrapup.prompt.ts`: happy path, skim message quality. **Sampling strategy.** Run the universal battery on all 29 tools, but pick roughly 30–40% for situational testing. Weight toward: write-shaped tools, tools with complex schemas, tools that integrate multiple operations (`git_merge`, `git_rebase`, `git_stash`, `git_worktree`). List which ones you skipped in the report. **External state.** - `git_push` / `git_clone` against real remotes: use `file://` URLs to local bare repos, or skip with a note. - Tools that write to real external systems should never touch the user's real `origin`. ### 6. Execute Use `TaskCreate` — one task per tool (or logical group). Mark complete as you go. Don't batch. For each call, capture: input sent, response (trim huge payloads to files), whether `isError: true` appeared, anything surprising (slow response, parity drift, unhelpful text, crash). **Interpreting responses**
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub