{"name":"io.github.navapbc/rebar","slug":"navapbc-rebar","title":null,"description":"Event-sourced ticket tracker + Jira reconciler, exposed as a Python library, CLI, and MCP server.","url":"https://mcp.market/server/navapbc-rebar","rating":null,"grade":"C","score":60,"certified":false,"status":"active","category":"devtools","tags":["devtools"],"presence":{"score":31,"stars":4,"forks":1,"downloads_week":89,"last_push_at":"2026-09-20T20:45:48.000Z","license":"Apache-2.0"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/navapbc/rebar","website":null,"version":"0.13.1","remotes":[],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"nava-rebar","version":"0.13.1","runtimeHint":"uvx","transport":{"type":"stdio"},"environmentVariables":[{"description":"Path to the repo root that holds the .tickets-tracker store (defaults to the git toplevel of the working dir).","name":"REBAR_ROOT"},{"description":"Set to 1 to expose only the read tools (no write/mutation tools).","name":"REBAR_MCP_READONLY"},{"description":"Set to 1 to enable the billable LLM tools (review_code / scan_spec / verify_completion / review_plan); off by default.","name":"REBAR_MCP_ALLOW_LLM"},{"description":"Set to 1 to allow the live (mutating) Jira reconcile mode; otherwise reconcile is dry-run only.","name":"REBAR_MCP_ALLOW_JIRA_SYNC"},{"description":"Transport for the MCP server: 'stdio' (default) or 'http' (the optional Streamable-HTTP transport).","name":"REBAR_MCP_TRANSPORT"},{"description":"Bind host for the Streamable-HTTP transport (default 127.0.0.1).","name":"REBAR_MCP_HTTP_HOST"},{"description":"Bind port for the Streamable-HTTP transport (1-65535; default 8000).","name":"REBAR_MCP_HTTP_PORT"},{"description":"URL path the Streamable-HTTP transport serves on (default /mcp).","name":"REBAR_MCP_HTTP_PATH"},{"description":"Comma-separated allowlist of exact host:port values accepted by the Streamable-HTTP DNS-rebinding protection; empty defaults to loopback.","name":"REBAR_MCP_HTTP_ALLOWED_HOSTS"},{"description":"Comma-separated allowlist of exact Origin values accepted by the Streamable-HTTP DNS-rebinding protection; empty defaults to loopback.","name":"REBAR_MCP_HTTP_ALLOWED_ORIGINS"},{"description":"Set to 1 to acknowledge TLS is terminated at the edge; required to bind the Streamable-HTTP transport to a non-loopback host.","name":"REBAR_MCP_HTTP_TLS_AT_EDGE"},{"description":"Set to 1 to acknowledge running the Streamable-HTTP transport without a token verifier; required to boot the HTTP transport while auth is off.","name":"REBAR_MCP_ALLOW_UNAUTHENTICATED_HTTP"},{"description":"Set to 1 to enable MCP authentication (the composite token verifier + Resource-Server wiring); off by default.","name":"REBAR_MCP_AUTH_ENABLED"},{"description":"Comma-separated, ordered list of token-verifier strategies to compose (closed set: static, jwt, introspection, proxy, custom).","name":"REBAR_MCP_AUTH_STRATEGIES"},{"description":"OAuth authorization-server issuer URL advertised in the Protected-Resource Metadata (RFC 9728) when auth is enabled.","name":"REBAR_MCP_AUTH_ISSUER_URL"},{"description":"The single resource identifier (RFC 8707 audience) for this server; the composite verifier re-checks every accepted token against it.","name":"REBAR_MCP_AUTH_RESOURCE_SERVER_URL"},{"description":"Comma-separated scopes a caller must hold; the SDK returns 403 insufficient_scope when a principal lacks one.","name":"REBAR_MCP_AUTH_REQUIRED_SCOPES"},{"description":"Path to the JSON secrets file for the static-bearer verifier (stores only SHA-256 digests of the accepted tokens).","name":"REBAR_MCP_AUTH_STATIC_TOKENS_FILE"},{"description":"HTTPS JWKS endpoint the `jwt` verifier fetches signing keys from (an OIDC provider's .well-known/jwks.json).","name":"REBAR_MCP_AUTH_JWT_JWKS_URI"},{"description":"Expected `iss` claim for the `jwt` verifier; falls back to REBAR_MCP_AUTH_ISSUER_URL when unset.","name":"REBAR_MCP_AUTH_JWT_ISSUER"},{"description":"Comma-separated PINNED, asymmetric-only JWS algorithms for the `jwt` verifier (default RS256,ES256); a symmetric algorithm on a JWKS source is refused.","name":"REBAR_MCP_AUTH_JWT_ALGORITHMS"},{"description":"Clock-skew leeway in seconds applied to exp/nbf validation by the `jwt` verifier (default 60).","name":"REBAR_MCP_AUTH_JWT_LEEWAY"},{"description":"Minimum seconds between JWKS refetches triggered by an unknown key id (the concurrency-safe flood guard; default 30).","name":"REBAR_MCP_AUTH_JWT_JWKS_REFETCH_COOLDOWN"},{"description":"HTTP timeout in seconds for the `jwt` verifier's JWKS fetch (default 10).","name":"REBAR_MCP_AUTH_JWT_JWKS_TIMEOUT"},{"description":"When set, the `jwt` verifier requires the JWT header `typ` to equal this (e.g. at+JWT per RFC 9068); unset skips the check.","name":"REBAR_MCP_AUTH_JWT_EXPECTED_TYP"},{"description":"Set to 1 to permit a private/link-local/loopback JWKS host (SSRF guard is on by default); off by default.","name":"REBAR_MCP_AUTH_JWT_ALLOW_PRIVATE_JWKS_HOST"},{"description":"The `introspection` verifier's RFC 7662 endpoint URL (must be https://); the opaque token is POSTed here on every request (no caching).","name":"REBAR_MCP_AUTH_INTROSPECTION_ENDPOINT"},{"description":"The client id the `introspection` verifier presents to the Authorization Server via HTTP Basic (client_secret_basic).","name":"REBAR_MCP_AUTH_INTROSPECTION_CLIENT_ID"},{"description":"The NAME of the env var holding the introspection client secret (never the secret itself); must be present + non-empty at startup or the server refuses to start (fail-closed).","name":"REBAR_MCP_AUTH_INTROSPECTION_CLIENT_SECRET_ENV"},{"description":"Set to 1 to permit a private/link-local/loopback introspection endpoint host (SSRF guard is on by default); off by default.","name":"REBAR_MCP_AUTH_INTROSPECTION_ALLOW_PRIVATE_HOST"},{"description":"Set to 1 to accept an active introspection response that OMITS `aud` (many AS do); off by default (fail-closed reject).","name":"REBAR_MCP_AUTH_INTROSPECTION_ALLOW_MISSING_AUD"},{"description":"The NAME of the env var holding the trusted-proxy shared secret (never the secret itself); must be present + non-empty at startup or the `proxy` verifier refuses to start (fail-closed).","name":"REBAR_MCP_AUTH_PROXY_SECRET_ENV"},{"description":"The header the fronting proxy sends its shared secret on; the identity is trusted only when this matches (constant-time; default x-proxy-auth).","name":"REBAR_MCP_AUTH_PROXY_SECRET_HEADER"},{"description":"The header carrying the proxy-authenticated principal identity, trusted only when the secret header validates (default x-forwarded-user).","name":"REBAR_MCP_AUTH_PROXY_IDENTITY_HEADER"},{"description":"Comma-separated fixed scope set granted to proxy-authenticated principals; empty by default (the principal holds no scopes).","name":"REBAR_MCP_AUTH_PROXY_SCOPES"},{"description":"The `custom` strategy's `module:factory` import string, resolving to a factory that returns a TokenVerifier; a TRUSTED operator config value that loads and executes the operator-configured code at startup (fail-closed on any load error).","name":"REBAR_MCP_AUTH_CUSTOM_IMPORT"}]}],"tools":[{"name":"archive_ticket","description":"Archive a ticket (excludes it from the default list).","write_action":false,"price_micros":0,"input_schema":null},{"name":"attach_commits","description":"Retroactively link commits to a ticket by SHA (union-add, idempotent).","write_action":false,"price_micros":0,"input_schema":null},{"name":"audit_trail","description":"The full audit read surface for a ticket (story 46f0): its FULL retained plan-review sidecar history (newest-first), its completion attestation + sidecar record, and the associated code reviews (``code_review`` tickets that link ``relates_to`` this ticket, each with its own retained sidecar history). Best-effort aggregation over the observability sidecars — individual reader failures degrade to ``","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_check_access","description":"Run the six-step live Jira capability check and return its typed verdict.","write_action":true,"price_micros":0,"input_schema":null},{"name":"bridge_fsck","description":"Offline bridge audit -> {unknown_event_types, binding_drift, store_integrity}.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_pause","description":"Persist a durable reconciliation pause with its operator reason.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_preview","description":"Compute proposed Jira changes without applying them.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_projects_list","description":"Return the store's bridge-projects sync mapping ``{key: {\"repos\": [...]}}``.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_projects_remove","description":"Remove a bridge project key from the mapping (error if absent).","write_action":true,"price_micros":0,"input_schema":null},{"name":"bridge_projects_set","description":"Set a bridge project key's repos (REPLACE semantics; idempotent).","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_resume","description":"Clear the durable reconciliation pause.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_run","description":"Run one scheduled bridge profile and strictly deliver its ticket events.","write_action":true,"price_micros":0,"input_schema":null},{"name":"bridge_status","description":"Read the durable bridge status snapshot and optional freshness assertion.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bridge_sync","description":"Apply proposed Jira changes, optionally with an explicit change limit.","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_ac","description":"Check the ticket has an Acceptance Criteria block ({verdict, criteria_count, reason, passed}).","write_action":false,"price_micros":0,"input_schema":null},{"name":"claim_ticket","description":"Atomically claim an OPEN ticket (-> in_progress + assignee).","write_action":false,"price_micros":0,"input_schema":null},{"name":"clarity_check","description":"Score ticket clarity (score / verdict / threshold / passed).","write_action":false,"price_micros":0,"input_schema":null},{"name":"comment_ticket","description":"Append a comment to a ticket.","write_action":false,"price_micros":0,"input_schema":null},{"name":"compact_ticket","description":"Compact a ticket's event log (or all tickets if id omitted).","write_action":false,"price_micros":0,"input_schema":null},{"name":"create_idea","description":"Capture an undesigned idea: create an epic in status 'idea' atomically.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_identity","description":"Create an identity entity: a gate-/graph-exempt ticket recording a person/agent. ``name`` is the title; ``email`` plus ``mappings`` (list of {provider, external_id}) and ``keys`` (OpenSSH authorized-keys lines) ride the CREATE and surface in show_ticket. Returns {id, alias}.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_ticket","description":"Create a ticket; returns {id, alias} (agents get the alias without a second show()). A non-null description_warning means the description exceeds the plan-review admission cap while the claim gate is on — the ticket was still created, but claiming it needs a review that refuses the description as-is. A non-null duplicate_warning means another ticket with the same normalized title was created insid","write_action":true,"price_micros":0,"input_schema":null},{"name":"declare_no_file_impact","description":"Declare that a ticket has no repository-file impact, with a reason.","write_action":false,"price_micros":0,"input_schema":null},{"name":"edit_ticket","description":"Edit ticket fields (title/priority/assignee/description/ticket_type).","write_action":false,"price_micros":0,"input_schema":null},{"name":"explain_criterion","description":"Explain a plan-review criterion — its authoring-guide section (epic cite-stone-sea / WS10) — OR print an author-facing prose guide when ``criterion_id`` is a guide name (``plan`` = how to write a passing plan; ``review`` = how to pass code review; ``commit-trailer`` = the required ``rebar-ticket:`` commit-trailer format). A pure registry/guide READ (no LLM, so it is NOT gated on REBAR_MCP_ALLOW_LL","write_action":false,"price_micros":0,"input_schema":null},{"name":"fsck","description":"Check ticket-store integrity (JSON validity, CREATE presence, lock cleanup). Set recover=True to run the recovery path.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_file_impact","description":"Get the file-impact array (consumed by next-batch conflict scheduling).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_verify_commands","description":"Get the DD-level verify-commands array for a ticket.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_workflow_result","description":"Read a workflow run's outputs via replay -> {run_id, status, terminal_step, terminal_output, outputs, error}. The terminal step's output is the run result.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_workflow_status","description":"Read a workflow run's current status via replay (no execution) -> {run_id, ticket_id, workflow_name, status, terminal_step, error, steps}.","write_action":false,"price_micros":0,"input_schema":null},{"name":"grounding_info","description":"The STATIC code-grounding oracle integration contract (epic 8f6c): the closed dimension-ID vocabulary + version, the reference kinds, the closed abstain-reason enum (+ outcome/job/tier vocabularies), and the available backends with their detected availability/version. A fast, deterministic, repo-independent discovery surface (no repo is scanned). Takes no args.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_tickets","description":"Link two tickets (one of the seven canonical relations: blocks | depends_on | relates_to | duplicates | supersedes | discovered_from | caused_by).","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_tickets","description":"List tickets as a JSON array, with optional filters.","write_action":false,"price_micros":0,"input_schema":null},{"name":"log_session","description":"Append a verbose entry to the current session_log, creating one on first use (write-gated: refused under REBAR_MCP_READONLY=1). Returns the log's {id, alias}; optional relates_to / discovered_from link it to the work it documents.","write_action":false,"price_micros":0,"input_schema":null},{"name":"next_batch","description":"Next parallel batch of unblocked tickets under an epic's hierarchy.","write_action":false,"price_micros":0,"input_schema":null},{"name":"plan_review_status","description":"Is this ticket's plan-review attestation current RIGHT NOW? Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"quality_check","description":"Check ticket dispatch readiness ({verdict, line_count, keyword_count, ac_items, file_impact, reason, passed}).","write_action":false,"price_micros":0,"input_schema":null},{"name":"ready_tickets","description":"List tickets ready to work (all blockers closed). ``sort`` orders by ``priority|created|updated|id|status`` (prefix ``-`` for descending; unset values sort last).","write_action":false,"price_micros":0,"input_schema":null},{"name":"recent_session_logs","description":"The newest session_log tickets, newest first (by created_at; default limit 5). session_logs are hidden from list_tickets; this is the type-specific read that surfaces them.","write_action":false,"price_micros":0,"input_schema":null},{"name":"reconcile","description":"Run the Jira reconciler. Defaults to a non-mutating dry-run.","write_action":true,"price_micros":0,"input_schema":null},{"name":"render_workflow","description":"Render a workflow (a .rebar/workflows/<name> name or a file path) to a read-only Mermaid flowchart (TEXT; the host renders it to SVG, never committed). Large graphs degrade to a text outline. Read tool, always available.","write_action":false,"price_micros":0,"input_schema":null},{"name":"reopen_ticket","description":"Reopen a closed ticket (closed -> open). Optimistic-concurrency: raises a tool error if the ticket is not currently closed.","write_action":false,"price_micros":0,"input_schema":null},{"name":"review_code","description":"Run a multi-reviewer LLM code review of a git range (base..head) -> an aggregated review_result dict (findings carry agreement + reviewers).","write_action":true,"price_micros":0,"input_schema":null},{"name":"review_plan","description":"Run the plan-review gate on a ticket -> a plan_review_verdict dict {verdict: \"PASS\"|\"BLOCK\"|\"INDETERMINATE\", blocking[], advisory[], coaching[], indeterminate[], coverage, signature?, source, verified_at_sha, ...}. A deterministic Layer-1 floor (P1-P9) plus a four-pass (find -> verify -> decide -> coach) review of the ticket's whole plan — the inverse of verify_completion. On a non-blocking PASS i","write_action":true,"price_micros":0,"input_schema":null},{"name":"run_workflow","description":"Start a workflow run; returns {run_id, ticket_id, status:'running'} IMMEDIATELY (async — the run executes on a background **daemon thread**, so it survives client request timeouts). Poll get_workflow_status / get_workflow_result to read its outcome. DURABILITY IS LIMITED: the daemon thread does NOT survive the MCP process exiting, and there is NO reaper or automatic resume — if the process dies mi","write_action":true,"price_micros":0,"input_schema":null},{"name":"scan_spec","description":"Batch-scan the store's open epics against a specification -> a review_result dict (gaps/conflicts/overlaps), epics evaluated in batches.","write_action":false,"price_micros":0,"input_schema":null},{"name":"search","description":"Search titles/descriptions/comments/tags with bounded discovery results.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_file_impact","description":"Record file impact (list of {path, reason}) for conflict-aware next-batch scheduling.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_verify_commands","description":"Record DD-level verify commands (list of {dd_id, dd_text, command}).","write_action":false,"price_micros":0,"input_schema":null},{"name":"show_ticket","description":"Show compiled ticket state (accepts full id, short id, or alias). Includes the computed ``inbound_deps`` (inbound edges: other tickets linking TO this one, with the source's status) alongside the stored outgoing ``deps``.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sign_manifest","description":"Sign a manifest of verified steps as an asymmetric op-cert.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sign_review","description":"Cheaply (re)persist the plan-review attestation for an already-computed, still-valid PASS verdict from the latest REVIEW_RESULT sidecar -> {ok, signed, ticket_id, verdict, reason, signature?}. WITHOUT re-running the multi-pass LLM review (no LLM, no network).","write_action":false,"price_micros":0,"input_schema":null},{"name":"summary","description":"One-line-per-ticket summary [{ticket_id, alias, status, title, blocking_summary}].","write_action":false,"price_micros":0,"input_schema":null},{"name":"tag_ticket","description":"Add a tag to a ticket.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ticket_deps","description":"Show the dependency graph for a ticket.","write_action":false,"price_micros":0,"input_schema":null},{"name":"transition_ticket","description":"Transition a ticket's status (optimistic concurrency). Returns the engine result {ticket_id, from, to, newly_unblocked}.","write_action":false,"price_micros":0,"input_schema":null},{"name":"unlink_tickets","description":"Remove a link between two tickets, optionally selecting its relation.","write_action":true,"price_micros":0,"input_schema":null},{"name":"untag_ticket","description":"Remove a tag from a ticket.","write_action":true,"price_micros":0,"input_schema":null},{"name":"validate","description":"Repo-wide quality health check (JSON report: score, critical/major/ minor issues, warnings, suggestions). Takes no ticket id.","write_action":false,"price_micros":0,"input_schema":null},{"name":"verify_completion","description":"Verify a ticket's completion requirements are met -> a completion_verdict dict {verdict: \"PASS\"|\"FAIL\", findings[], summary?, target, reviewers, runner, model, trace_id, source, verified_at_sha, signable}. Checks every acceptance/success/close criterion + definition of done (for bugs, that the bug is resolved) against the implementation; on FAIL, each finding carries the failing criterion, an expl","write_action":false,"price_micros":0,"input_schema":null},{"name":"verify_signature","description":"Certify a ticket's verified-steps manifest against its signature.","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":60,"grade":"C","scanned_at":"2026-09-20T20:58:24.931Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-20T20:58:24.906Z","components":{"code":{"score":3,"max":25,"notes":["785 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":9,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"exec.shell-true","severity":"medium","component":"code","title":"subprocess with shell=True","evidence":"nava_rebar-0.13.1/src/rebar/_commands/compact_txn.py: …-out (no such subcommand existed; ``shell=True`` injection smell).\"\"\" from rebar._…"},{"id":"exec.eval","severity":"medium","component":"code","title":"eval / new Function used","evidence":"nava_rebar-0.13.1/src/rebar/grounding/detectors/builtin/security_owasp_cwe.yaml: … message: \"Dynamic code execution via eval()/exec() — code-injection risk (CWE-94).…"},{"id":"exec.shell-concat","severity":"high","component":"code","title":"Shell command built from a string (injection risk)","evidence":"nava_rebar-0.13.1/src/rebar/llm/eval_specs/code-review-base.eval.yaml: …git.py @@ -4,2 +4,3 @@ - subprocess.run(f\"git -C {d} add -A\", shell=True) + …"}],"inputs":{"packages":[{"registryType":"pypi","identifier":"nava-rebar","version":"0.13.1","found":true,"weeklyDownloads":89,"license":"Apache-2.0","dependencyCount":51,"publishedAt":"2026-08-30T03:33:45.057011Z","repositoryUrl":"https://github.com/navapbc/rebar"}],"repo":{"found":true,"owner":"navapbc","repo":"rebar","archived":false,"pushedAt":"2026-09-20T20:45:48Z","stars":4,"forks":1,"openIssues":2,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/11320847?v=4","ownerCreatedAt":"2015-03-04T20:50:41Z","license":"Apache-2.0"},"icon":{"url":"https://avatars.githubusercontent.com/u/11320847?v=4&s=128","source":"github"},"presence":{"stars":4,"forks":1,"downloadsWeek":89,"license":"Apache-2.0","lastPushAt":"2026-09-20T20:45:48.000Z","score":31}}}},"grade_history":[],"reviews":[]}