Skip to content

v0.4.2

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 31 Aug 08:18
· 9 commits to main since this release

Added

  • The scope grid says which tools reach the internet. weather, fx_rate, geo and
    url_check carry a network pill with a title that says the call's input goes to a
    third-party service, sit under a "Reaches the internet" heading, and a No network button
    beside All / None / Expand all unticks the four and leaves everything else as it was. The
    same partial serves the create-key form, the key's scope editor and both consent pages, so
    a key that arrives with all four ticked - every key with no scope, including one minted by
    approving a consent screen - is never decided on a page that does not mention the internet.
    The fact lives with the data: scopes.NETWORK_TOOLS is the external half of the catalogue,
    and a test holds it equal to the tool reference's network flag. (#103)

Changed

  • Docs. The Claude Code client page says what "Disabled for this project" means and how
    to clear it; the quickstart's paste-in prompt tells the agent the same. (#104)
  • One endpoint. /external/mcp is retired; the network tools are on /mcp. Adding
    leftbrain was two mcp add commands and, since OAuth, two sign-ins, for what every other
    layer - one key, one quota, one dashboard, one scope grid, one /docs/tools - already treated
    as one product. weather, fx_rate, geo and url_check are now published by the same
    server as the fourteen core tools, and the stdio leftbrain command carries them too.
    LEFTBRAIN_SERVE_EXTERNAL=0 (or --no-network) leaves the four out of a process; per-key
    control over the same four is the scope grid, which marks them (#103). A request to
    /external/mcp answers 410 with moved_to: "/mcp" and a message saying what happened,
    with no key required, so a client still configured with it is told rather than shown a bare
    404. The root document lists one endpoint and a network_tools flag. leftbrain-external
    remains for a process that should carry only the four. This flips the default from
    opt-in to opt-out for network access
    ; that was decided deliberately (#100).
  • Every parameter of fx_rate and url_check now carries its description on the wire.
    The pass that copies the reference's parameter docs onto the published schema only handled
    tools with modes; the two mode-less tools were never on the described server before. (#100)

Fixed

  • OAuth on /external/mcp. The 401 challenge named /mcp's protected-resource document
    whichever endpoint was asked for, and there was no document for the other mounts at all. A
    client that checks the document's resource against the URL it is connecting to - Claude
    Code does, as RFC 9728 requires - refused /external/mcp with "does not match expected"
    before any tool call. Every mounted endpoint now has its own document at
    /.well-known/oauth-protected-resource<endpoint>, and the challenge and the 401 body's
    how_to_authorize point at the one for the endpoint that was requested. A protected path
    that is not an MCP endpoint (/keys/me) is pointed at the core document. Static-key auth
    never read the challenge and is unchanged. (#101)
  • The 401 no longer sends an agent to a closed door. Its message said "get one at
    POST /keys/signup" whenever a key store existed; that route answers 404 unless
    LEFTBRAIN_OPEN_SIGNUP is on, which it is not on the hosted server. The clause now names
    signup only when it is open and says "sign in at /login to create one" otherwise. (#104)
  • A headless agent is told to register before the device grant. The 401's
    if_you_have_no_browser named /oauth/device_authorization alone, and calling it without a
    registered client answered a bare invalid_client. The 401 now names POST /register first,
    and the device endpoint's invalid_client carries an error_description that says the
    same and points at the agent guide. (#104)
  • A key minted through the device grant reads · device, not the approver's OS. The
    device flow exists so the approval can happen on a different machine from the agent, so the
    approving browser's operating system says nothing about where the agent runs - the same
    reasoning that already names a cloud client · web. (#104)
  • The site links to its repository again, and "feedback is off" says where else to go.
    feedback.py, the README and the report page all said the repository was private and that
    the feedback endpoint was therefore the only place to report a wrong answer. It is public, and
    on the hosted server the endpoint was not configured, so there was no route at all. The
    footer now links Source and Issues; the report page links the tracker whether or not filing
    is on; POST /feedback when off answers unsupported with the tracker in message and a
    tracker field; and the reason the endpoint exists is stated correctly - an agent mid-call
    holds a key, not a GitHub login. One source of truth: leftbrain.__repo__ (and
    Repository / Issues in pyproject.toml), overridden by LEFTBRAIN_FEEDBACK_REPO when a
    self-hoster files reports into their own fork. The Northflank guide names the two feedback
    variables. (#102)