Metadata-Version: 2.4
Name: fidacy-langchain
Version: 0.1.0
Summary: Gate LangChain tool calls behind a Fidacy verdict. Wraps the tool itself, so a denied payment never executes: callbacks can only observe, this can stop.
Project-URL: Homepage, https://fidacy.com
Project-URL: Source, https://github.com/lucaslubi/fidacy-mcp
Author-email: "Fidacy (ZeepCode Group Technology LLC)" <hello@fidacy.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,ai-safety,fidacy,firewall,guardrail,langchain,mandate,payment,tools
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Requires-Python: >=3.9
Requires-Dist: langchain-core>=0.3.0
Description-Content-Type: text/markdown

# @fidacy/langchain for Python

Gate LangChain tool calls behind a Fidacy verdict. Wraps the tool itself, not a
callback: LangChain callbacks fire *around* a call and cannot cancel it, so a
guardrail built on them watches the money leave. This one stops it.

```bash
pip install fidacy-langchain
```

```python
from fidacy_langchain import guard_tools

# No key, no signup: the offline judge decides your first 20 calls.
tools = guard_tools([pay_tool, search_tool])
```

`pay_tool` is judged before every call. `search_tool` is returned untouched, so
tools that do not move money pay no cost at all.

### Two ways it decides

**Offline, out of the box.** With no credential the deterministic local judge
runs: deny-by-default, your own limits, a hash-chained log on your machine. The
first 20 decisions on an install are free and need no account, so you can watch a
payment get blocked before deciding whether you want any of this.

```python
from fidacy_langchain import Mandate, guard_tools

tools = guard_tools([pay_tool], mandate=Mandate(
    payees=["acme-inc"],
    per_tx_max=5_000,
    max_total=50_000,
))
```

A blocked call tells you what was stopped, in money terms, and prints the exact
edit that would allow it:

```
Fidacy stopped send_payment: USD 4,200 to "acme-inc" is over the USD 1,000
per-payment limit. That limit is Fidacy's starting default, not something you
set. To allow a payment this size, set your own:

  guard_tools([send_payment], mandate=Mandate(per_tx_max=4200, payees=["acme-inc"]))

No money moved and the attempt is on this install's audit trail. 19 free
decisions left.
```

It also names impersonation. `pay0neer` against an approved `payoneer` is not
reported as an unknown payee: it is reported as the vendor being spoofed, which
is the signature of a payee swap.

### The judge is the same one the Node packages run

The rules live in one place, `packages/firewall/vectors/judge.json`, and both the
TypeScript and Python implementations run those cases and must return the exact
same rule string. A firewall that decided differently depending on the language
your agent happens to be written in would not be worth trusting.

### Trial state is shared

The free-decision counter lives in `~/.fidacy/config.json`, the same file
`@fidacy/mcp` uses. Adding this package does not hand you a fresh 20, and the
history you build anonymously migrates when you claim an account.

Free key, no card: https://fidacy.com/claim

Apache-2.0 · https://fidacy.com
