fix(mcp): widen DependencyType to str so all bd dep types validate#3133
Merged
maphew merged 2 commits intoApr 10, 2026
Merged
Conversation
The Pydantic Literal at models.py:23 only whitelisted 4 dependency types
(blocks, related, parent-child, discovered-from), but the bd CLI emits ~19
(see internal/types/types.go: blocks, parent-child, conditional-blocks,
waits-for, related, discovered-from, replies-to, relates-to, duplicates,
supersedes, authored-by, assigned-to, approved-by, attests, tracks, until,
caused-by, validates, delegated-from).
Any mcp__beads__show() on an issue with a non-whitelisted dep edge crashed
with `pydantic literal_error`, e.g.:
1 validation error for Issue
dependencies.0.dependency_type
Input should be 'blocks', 'related', 'parent-child' or 'discovered-from'
[type=literal_error, input_value='relates-to', input_type=str]
Brief mode hit the same error because BriefDep reused the same Literal.
Fix: change DependencyType from a Literal to a plain `str`, mirroring how
IssueStatus and IssueType are already handled in the same file. The bd CLI
is the source of truth for valid dep types and validates them itself; the
MCP layer doesn't need a redundant whitelist that drifts from the CLI.
Also updated the user-facing docstrings in server.py and tools.py to stop
claiming only 4 dep types exist.
Verified: synthesizing an Issue with a 'relates-to' LinkedIssue now
validates cleanly. All 141 unit tests pass (the 4 failures in
test_compaction_config.py are pre-existing — they hardcode
/Users/stevey/src/dave/beads/... paths).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
integrations/beads-mcp/src/beads_mcp/models.py:23defines:But the
bdCLI emits ~19 dependency types (seeinternal/types/types.go:769-805):Any
mcp__beads__show()call on an issue with a non-whitelisted dep edge crashes withpydantic literal_error. Repro from a real session today:brief=truedoesn't help —BriefDepreuses the sameLiteral. The CLI (bd show) is unaffected because it doesn't go through Pydantic.This blocks any agent workflow that uses
mcp__beads__show()over a knowledge graph that hasrelates-to,replies-to,duplicates,supersedes, etc. edges. PR #1469 added CLI display support forrelates-toback in February — the MCP layer just never caught up.Related: #1750 (MCP Pydantic validation error on
listwhen issues have dependencies — same class of bug, different call site).Fix
Change
DependencyTypefrom aLiteralto a plainstr, mirroring howIssueStatusandIssueTypeare already handled in the same file (lines 21-22). ThebdCLI is the source of truth and validates dep types itself (DependencyType.IsValid()ininternal/types/types.go:805); the MCP layer doesn't need a redundant whitelist that drifts from the CLI.Also updated the user-facing docstrings in
server.pyandtools.pyto stop claiming only 4 dep types exist — they now mention the common four and point tointernal/types/types.gofor the full list.Verification
Synthesizing an
Issuewith arelates-toLinkedIssuenow validates cleanly:Test suite: 141 unit tests pass, 7 model/dep-specific tests pass. Note: there are 4 pre-existing failures in
tests/test_compaction_config.pythat hardcode/Users/stevey/src/dave/beads/...paths — unrelated to this change, fail on any non-Steve machine.Why a
strand not an expandedLiteral?I considered listing all 19 types in the
Literal, but:internal/types/types.goover time (e.g.,delegated-fromis recent). ALiteralwill drift again.IsValid()method knows the live set.IssueStatusandIssueTypealready made the same call (and for the same reason — custom statuses/types viabd config set), so this is internally consistent.If you'd prefer the literal approach for type safety / IDE autocomplete, happy to switch.