本文へ移動
cccskills
無料GitHub で公開

qa-find-bugs-mcp

Hunt bugs in the Beancount.io remote MCP server by driving the real POST /api-gateway/mcp endpoint with JSON-RPC and real MCP clients, checking transport, discovery, credential boundaries, tool and resource results, the result envelope and prompts against REST/GraphQL controls, reproducing failures, tracing root causes, and deduplicating findings. Use for MCP QA or an agent-endpoint bug hunt. Skip ordinary code review, bug implementation, browser, native-mobile, and CLI QA.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-ioスター 315(GitHub 315 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(2)

  • SKILL.md12.4 KB
  • evals/evals.json2.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

MCP QA bug hunt

Read the shared QA contract first, then backend-cluster/backend-v2/AGENTS.md, backend-cluster/backend-v2/docs/mcp.md (the customer contract: tools, resources, prompts, envelope, failure codes), ADR 0007 (docs/adrs/ADR007-backend-v2-mcp-surface.md, the endpoint contract) and ADR 0008 (surface parity). Exercise the real endpoint over HTTP; unit tests and source inspection support a finding but do not replace a live journey.

Arguments: optional base URL, journey names, ledger owner/name, wN, SHIP=1, DRY_RUN=1. Default to https://beancount.io and report mode. A base URL changes the deployment under test; record the server name and version initialize reports and whether it matches local HEAD before calling a source fix missing from production. DRY_RUN=1 still allows disposable writes on a designated QA ledger needed to reproduce bugs.

Prepare targets and credentials

  • Record branch, HEAD, dirty files, Node version, target base URL, the initialize response's serverInfo and negotiated protocolVersion, the credential kind (API key or OAuth token), its scopes and pin, and the chosen synthetic ledger. Never record the credential itself.

  • The endpoint is POST {base}/api-gateway/mcp. Send Accept: application/json, text/event-stream, a JSON content type and MCP-Protocol-Version. Responses may be SSE-framed; parse data: lines rather than assuming one JSON document. The server is stateless: every POST is independent, initialize is not a prerequisite for a call, and there is no session id.

  • Make requests with the bundled helper so the credential never reaches argv, a transcript or a tool call:

    node .agents/skills/qa-shared/scripts/qa-mcp.mjs [--credentials-file FILE] [--url URL] <command>
    

    Commands: initialize, tools-list, resources-list, prompts-list, call <tool> [json], read <uri>, prompt <name> [json], rpc <method> [json], and raw --method GET|DELETE|POST [--accept TEXT] [--body TEXT] for transport checks. --anonymous omits the credential. It reads QA_MCP_TOKEN (falling back to BEANCOUNT_MCP_TOKEN) from the repo-root ./.env (preferred), the environment, or --credentials-file (not --env-file, which Node itself consumes after the script path; an explicit file wins over both), prints status, an allowlist of headers and the parsed JSON-RPC messages, redacts bcio_ prefixes and the token value, exits 2 for usage or credential problems and 3 for network failures or hangs. Run it from the repo root; --url defaults to the production endpoint and accepts HTTP only on loopback.

  • Use a user-designated QA credential: a bcio_ key minted on a dedicated QA account for a synthetic ledger, ideally one read/write key pinned to the ledger and one ledger.read key on the same ledger, both short-lived. The token lives in the repo-root ./.env unless the user names another file; ask for the variable names or file path, never for the value. Do not mint keys on, or point tools at, a personal account or ledger. Browser cookies from qa-login.mjs are not MCP credentials; the endpoint refuses them by design.

  • Without a credential, continue the anonymous transport and discovery checks and mark every authenticated journey unverified.

  • Disposable writes, accounts and admin journeys belong on the already running local deploy/docker-mac stack (http://localhost:42601, see its README for ports and DEV_PREMIUM_USER_IDS for local key minting). Use it only when it is already up; .pm/DO_NOT_DO.md forbids provisioning a second stack for MCP testing. Label local results as local, with the backend image or HEAD they ran.

  • yarn mcp:conformance <base-url> [--token …] [--read-only-token …] inside backend-cluster/backend-v2/ runs ADR 0007's checklist and only observes; run it first against the target and treat a failed check as a candidate. yarn mcp:agent-eval drives real Claude Code and Codex sessions and is billed; run it only when the user asks for client journeys.

  • Store evidence under the gitignored repo-root .tmp/qa-<date>/: the exact helper command, sanitized request and response, status, headers and timings. Bound every request with a timeout; a hang is a result.

Sweep whole journeys

Use selected journey names to narrow this table; otherwise survey the surface and deepen the journeys that show failures. Report each skipped group and why.

JourneyObservable promise
transportAnonymous POST returns 401 with WWW-Authenticate: Bearer resource_metadata=…, and that URL returns 200 with an RFC 9728 document naming an authorization server that also resolves. Authenticated GET/DELETE return 405 with Allow: POST and complete; anonymous GET still returns 401. Missing Accept values or a wrong content type fail before tool execution. A notification returns 202; an unknown method returns a JSON-RPC error. /mcp behaves as docs/mcp.md states.
discoveryinitialize negotiates each supported protocol version and returns serverInfo and instructions. tools/list, resources/templates/list and prompts/list match the documented inventory: every tool has a title, description, inputSchema and an object outputSchema; names are unique; prompt arguments are declared; resources/list returns the documented instance set (static reads plus capped source files per ledger), not templates. Compare with mcp-tools.ts, mcp-resources.ts, mcp-prompts.ts.
boundariesA ledger.read key gets isError: true with FORBIDDEN on every write and admin tool, never a success or an internal error. A pinned key naming another ledger is refused; an unpinned key without ledger is refused with a hint naming listLedgers; resource URIs obey the same pin. A revoked or expired credential fails on the next request with UNAUTHENTICATED or 401. A browser session cookie is refused with the discovery hint.
readsrunBqlQuery and runBqlQueryStructured agree with REST query and GraphQL queryShell on rows, columns, decimals and dates; structuredContent and the text block describe the same result. listLedgers paging, checkLedger, getLedgerContext, getEntryContext, listLedgerFiles and readLedgerFiles line ranges match ledger contents and their REST counterparts. Empty, missing and forbidden cases return the documented code, not an empty success.
resourcesVocabulary, analysis, journal, statement and file templates expand as documented, including reserved {+path}, query parameters and JSON-encoded array filters. MIME types and contents shapes match the doc; a failure is a JSON-RPC error whose data.code matches the table, with the message unprefixed. Each read matches the REST route with the same suffix.
writesdry_run previews leave the ledger unchanged in a fresh request and in REST. appendLedgerText inserts in date order and checkLedger stays clean; addLedgerEntries refuses unbalanced input with UNBALANCED and honors allowInvalid; createLedgerFiles, updateLedgerFiles and deleteLedgerFiles each put all their files in one commit; updateEntrySource and deleteEntrySource return CONFLICT on a stale sha256sum; renameLedgerFile preserves content. Verify persistence through readLedgerFiles and REST, and confirm exactly one commit per operation.
promptsprompts/get returns each playbook; malformed month or ledger is refused; every tool and beancount:// URI the text cites exists in this deployment's lists; a pinned credential is told its ledger. Compare served text with mcp-prompts.ts and classify a difference as deployment lag.
envelopeEvery failure carries isError: true and { ok: false, error: { code, message, hint } }; success carries { ok: true, result }; retryAfter appears only with RATE_LIMITED. Missing required arguments are BAD_USER_INPUT, not INTERNAL_SERVER_ERROR. Unexpected errors are masked in production; a DomainError keeps its message. ok and isError never disagree.
limitsThe handshake methods are not charged; write budgets are smaller than read budgets; RATE_LIMITED names retryAfter. Probe at human pace with a few extra calls, never a flood, and never against production for write budgets.
accountcreateLedger, updateLedger, deleteLedger, setLedgerCollaborator, removeLedgerCollaborator, leaveLedger, setLedgerStar and account resources honor scopes and relationships. API-key and SSH-key management, account deletion, and plan tiers and usage are deliberately absent from MCP (ADR 019, 2026-10-09 amendment); their absence is not a bug, and their presence on a deployment is either deployment lag or a regression. Create or delete only qa-<yyyymmdd>- resources on the designated QA account; never change collaborators, banks or billing on a pre-existing account.
clientsOnly when requested: a real Claude Code or Codex session connects with a bearer key, lists the same tools, exposes the four prompts, and completes a read journey; yarn mcp:agent-eval is the deep, billed harness. Record client versions and cost.

After a surprising response, capture the full sanitized exchange, then repeat it in a fresh request. Compare with the same operation on REST (/api-gateway/v1/…) or GraphQL using the same credential where the surface accepts it; a discrepancy is a parity candidate owned by backend-v2, not automatically an MCP bug. Distinguish BAD_USER_INPUT, NOT_FOUND, FORBIDDEN, UNAUTHENTICATED, PREMIUM_REQUIRED, RATE_LIMITED, SERVICE_UNAVAILABLE and INTERNAL_SERVER_ERROR before naming a defect. A Cloudflare or bot-protection page is not an application error.

Reproduce, research, and hand off

Reproduce from a fresh request with the same credential kind and target, and check a nearby working control (another tool, the REST route, or a second ledger). Documented behaviors are not bugs: 405 on authenticated GET, an empty resources/list, SSE framing, a loosened published outputSchema, PREMIUM_REQUIRED on a free account, and error text that states a limit without naming a plan. Deployment lag is not a bug either: when the served inventory or prompt text differs from HEAD, cite the commit that already changed it.

Trace the route in src/features/ai-agent/api/mcp-route.ts (identity, pin, method set), the registry and result wrapper in src/server/api/composition-root.ts, tool descriptors in mcp-tools.ts and src/features/ai-agent/tools/, resources in mcp-resources.ts and mcp-resource-template.ts, error translation in mcp-errors.ts and mcp-result-text.ts, prompts in mcp-prompts.ts, the op table in src/server/api/op-class.ts, the limiter in rate-limit.ts and the protected services the adapters delegate to. Existing suites to compare with: mcp-route-methods, mcp-errors, mcp-output-schema, mcp-prompt-list, mcp-tool-list, mcp-resources-list, surface-parity and the *-parity contract tests. A proposed fix names the owning package and, per the parity workflow, every eligible REST/GraphQL/MCP surface it must change together.

Apply the shared root-cause, caller search, board/history dedupe and optional pm/ship steps. In the finding record, replace route/device evidence with base URL, serverInfo, protocol version, credential kind, scopes and pin (never the value), the exact helper command or JSON-RPC body, status, relevant headers, the sanitized response and the REST/GraphQL control. Include a minimal synthetic reproducer in public filing text.

Finish with findings by severity, coverage/skips, dedupe/filing status, and cleanup: revoke keys minted by this run, delete only qa-<yyyymmdd>- resources, and report anything left behind. Do not implement fixes unless requested; if requested, add contract coverage through the adapters and run yarn typecheck, yarn test and yarn generate-v1-openapi inside backend-cluster/backend-v2/ before handoff.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Prepare supported accrual and reversal drafts for a period from an explicitly stated schedule — basis, service interval, day-count, recognized-to-date, already-booked, required adjustment — posted only through the suite's propose/confirm/check flow with stable schedule identity. Skip recording one-off entries the user describes (beancount-add), explaining how a balance moved (beancount-roll-forward), tax or depreciation advice, automatic reversals, and ledgers hosted on Beancount.io.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

Record one-off entries the user describes in a local Beancount ledger through bea — a purchase, bill, paycheck, or transfer between their own accounts (including splits and pasted receipt text), opening or closing an account, a price, or a note. Propose the exact entries from existing accounts, check whether one is already recorded, and write only after confirmation with a passing check; it never changes existing entries. Skip bank or card export files (beancount-import), statements (beancount-reconcile), finance-app migrations, options trades (beancount-options), investment trades, dividends, splits, and vests (beancount-trade), month-end close, edits to existing entries, and ledgers hosted on Beancount.io.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

Answer explicit requests for facts from a local Beancount ledger using shown, reproducible bea queries and reports for spending, trends, net worth, holdings, subscriptions and anomalies. Do not select this skill merely to gather preliminary inputs for buy/sell decisions or tax recommendations, even if ledger facts could help. Strictly read-only; figures come from executed queries. Skip ledgers hosted on Beancount.io, recording transactions (beancount-add), reconciliation, migration, ledger edits, option pricing or greeks, investment or tax advice, and general Beancount, BQL, or `bea` documentation questions (including what `bea ask` does).

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

Close an accounting period in a local Beancount ledger by reconciling each active account through beancount-reconcile, checking assertions and recurring gaps, reviewing flags, then proposing a commit with the period reports. Use for month-end close or wrapping up the books. Surface incomplete work and require a passing check before a confirmed commit; never push. Skip closing a single account (a `close` directive; beancount-add) and ledgers hosted on Beancount.io.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

Record bank/card transactions in an existing local Beancount ledger from CSV, OFX/QFX, QIF or PDF statements, including PDF-only banks with no CSV export. For a PDF ledger import, read this SKILL.md before the PDF helper's guide to establish account, deduplication and confirmation rules, then use the helper for extraction. Import broker activity CSVs or holdings/cost-basis exports as lot-carrying entries or opening lots. Read this guide before beancount-trade for these files; skip described trades (beancount-trade). Normalize signs, suggest categories from existing accounts, review duplicates and confirm before bea writes; PDF statements must tie out and end with a balance assertion. Skip standalone PDF extraction/OCR, summarization or editing without a ledger import; account-versus-statement comparisons (beancount-reconcile), full finance-app migrations, reusable importer authoring, individual options trades, single manual entries (beancount-add), ledger `option` settings, and ledgers hosted on Beancount.io.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

Write or repair a reusable Beangulp importer from a sample bank export for a local ledger, with reviewed golden files and a passing test harness. Use when a source needs a tested Python importer or its format changed, e.g. "write a beangulp importer for my bank's CSV" or "my importer broke after the bank renamed its columns". Wire the confirmed runner through bea ingest; keep generate/test in the authoring project. Skip one-off imports, reconciliation, finance-app migration, ledger writes, and ledgers hosted on Beancount.io.

日本語の概要は準備中です。原文の説明を表示しています。

bex-co/beancount-io3152026年10月26日 更新

bex-co のスキルをすべて見る

このスキルの問題を報告する