Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
e288aba
cleaner example git push
Hendler May 8, 2025
a595f3f
npm scaffold
Hendler May 8, 2025
98546b1
rough
Hendler May 8, 2025
009ecdd
wrapped
Hendler May 9, 2025
df5319a
progress
Hendler May 9, 2025
ef49dbd
npm untested
Hendler May 9, 2025
adca098
add default replay attack time out
Hendler May 9, 2025
402c104
use refactored libs in npm
Hendler May 9, 2025
6efb204
use refactored libs in npm
Hendler May 9, 2025
a8552ab
fmt
Hendler May 9, 2025
fa4bc5b
hybrid python and rust module
Hendler May 10, 2025
3e8df0a
testing inclunding mcp in the jacs python
Hendler May 10, 2025
2e2d12c
cleanup
Hendler May 10, 2025
482025b
cleanup
Hendler May 10, 2025
5777097
fix test
Hendler May 10, 2025
1fae57e
lint
Hendler May 12, 2025
13e4861
ratatui
Hendler May 12, 2025
37f84bf
try for cli install
Hendler May 12, 2025
b691fae
change
Hendler May 13, 2025
c957af9
cargo
Hendler May 13, 2025
bc838b8
makefile
Hendler May 13, 2025
b69dc8e
migrate more to reusable cli
Hendler May 13, 2025
d766954
finishing refactor
Hendler May 13, 2025
3288252
fix refactor
Hendler May 13, 2025
edf535e
integrate cli with jacspy
Hendler May 14, 2025
625e200
npm
Hendler May 14, 2025
4f220c6
packaging node
Hendler May 14, 2025
0baebc9
starting to add mcp
Hendler May 14, 2025
86f362a
mcp client and server
Hendler May 14, 2025
307d694
use proper functions for request response
Hendler May 14, 2025
fd8dc3d
npm builds
Hendler May 15, 2025
8fae2aa
broken again
Hendler May 15, 2025
ac6841a
load agent error
Hendler May 15, 2025
573a1b0
example setups
Hendler May 15, 2025
6a85eca
new error
Hendler May 15, 2025
c3b113d
nope
Hendler May 16, 2025
2351f5e
better request response example
Hendler May 16, 2025
4f4d305
better request response example
Hendler May 16, 2025
67e1522
update language
Hendler May 17, 2025
c414cdc
pass npm test
Hendler May 17, 2025
0ff3b43
fixed bug
Hendler May 17, 2025
c471d03
change example
Hendler May 17, 2025
060d0d7
more npm examples
Hendler May 17, 2025
2978eeb
setting up http client server
Hendler May 17, 2025
558de59
koa and express middleware
Hendler May 17, 2025
b4d18d8
express and koa middleware
Hendler May 17, 2025
bfe23d3
readme
Hendler May 17, 2025
40ce8e8
mcp refactoring
Hendler May 18, 2025
6e05f6c
not working npm mpc, starting over
Hendler May 18, 2025
35e24e8
switch to typescript
Hendler May 18, 2025
c2beda7
mcp ts
Hendler May 19, 2025
1c545e1
server responds
Hendler May 19, 2025
0ef3d1d
s
Hendler May 19, 2025
3a348fb
debug
Hendler May 19, 2025
0017254
debug
Hendler May 19, 2025
a72c844
stuck
Hendler May 21, 2025
3ee03c5
mcp
Hendler May 22, 2025
29a1601
mcp
Hendler May 22, 2025
bda9d81
mcp
Hendler May 23, 2025
7e5f9a5
mcp
Hendler May 23, 2025
b0dffaf
transport only
Hendler May 24, 2025
8be2207
transport only
Hendler May 24, 2025
310ac20
ok
Hendler May 24, 2025
306ce5e
server client not working yet
Hendler May 24, 2025
0083832
server client not working yet
Hendler May 24, 2025
4f16db4
mcp working
Hendler May 24, 2025
a3df04b
explain a bit more
Hendler May 24, 2025
f03df0c
stdio IO in node
Hendler May 24, 2025
302f8d6
changelog
Hendler May 24, 2025
b7f19cf
observability module
Hendler May 25, 2025
3512258
tests almost passing
Hendler May 25, 2025
dcf70f4
tests pass
Hendler May 25, 2025
d3a245f
test
Hendler May 25, 2025
7336a69
refactor
Hendler May 25, 2025
898c9cd
consider wasm
Hendler May 25, 2025
b6f7928
refactor, simplification
Hendler May 25, 2025
470ce72
fixed
Hendler May 25, 2025
f0a9b15
more accurate test output
Hendler May 25, 2025
911f9eb
starting using tracing
Hendler May 28, 2025
ce53190
update documentatino
Hendler May 28, 2025
7c57531
tracing
Hendler May 28, 2025
0eea4b2
get rid of printlns
Hendler May 28, 2025
cb45c47
changelog
Hendler May 28, 2025
8d71515
push reqs
Hendler May 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ jobs:
cd /workspace/jacspy && \
/opt/python/cp311-cp311/bin/python3.11 -m venv .venv && \
source .venv/bin/activate && \
pip install pytest && \
pip install maturin pytest && \
pip install fastmcp mcp starlette && \
make test-python"

# Job to build wheels, runs ONLY on push to main
Expand Down
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Welcome.

You may use the top level Cargo.toml to understand the repo.
jacs/ is the directory with the core library.
./jacspy is the python wrapper with functionality for integrations
./jacsnpm is the npm/node wrapper with functionality for integrations

Look for examples in tests for how to use the library.
README.md and CHANGELOG.md may be useful to understand some future goals and what has been done.

92 changes: 64 additions & 28 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# PLANNED
- machine fingerprinting v2
- passkey-client integration
- encrypt files at rest
- refine schema usage
- more getters and setters for documents recognized by schemas
Expand All @@ -8,6 +9,8 @@
- use rcgen to sign certs, and register with ACME
https://opentelemetry.io/docs/languages/rust/
. ai.pydantic.dev
- secure storage of private key for shared server envs https://crates.io/crates/tss-esapi, https://docs.rs/cryptoki/latest/cryptoki/


## 0.4.0
- Domain integration
Expand All @@ -18,6 +21,7 @@
- pass document string or document id - with optional version instead of string
- load document whatever storage config is
- function test output metadata about current config and current agent

## jacs-mcp 0.1.0

- [] use rmcp
Expand All @@ -26,47 +30,79 @@
- [] https://github.com/modelcontextprotocol/specification/discussions



--------------------

## 0.3.5
## 0.3.6

### Register agent
### jacsnpm

- [] register agent
- [] remove requirement to store public key type
- [] BUG with STDIO in general
fix issues with Stdio mcp client and server log noise - relates to open telemetry being used at rust layer.
- [] github actions builder for linux varieties
- [] npm install jacs (cli and available to plugin)
- [] a2a integration
- [] integrate cli

### jacspy
- [] publish jacspy to pypi
- [] mcp make sure "list" request is signed?
- [] some integration tests
- [] fastapi, django, flask, guvicorn specific pre-built middleware
- [] auto generate agent doc from MCP server list, auto versions (important for A2A as well)
- [] fastmcp client and server websocket
- [] BUG? demo fastmcp client and server stdio
- [] a2a integration
- [] have jacs cli installed along with wheel
- [] python based instructions for how to create - cli create agent
1. cli create agent
2. config jacspy to load each agent
- [] github actions builder for linux varieties

### JACS core
- [] ensure if a user wants standard logging they can use that
- [] cli install instructions. a .sh command?
- [] expose logging function to jacspy and jacsnpm
- [] create centralized logging output without file output
- [] CA for cert
- [] register public key in d option
- [] register agent
- [] remove requirement to store public key type
- [] upgrade pqcrypto https://github.com/rustpq/pqcrypto/issues/79
- [] RBAC integration with header
- [] diff versions
- [] bucket integration
- [] don't store "jacs_private_key_password": in config, don't display
- [] register public key
- [] CA for cert
- [] add timestamp to prevent timing attacks to request/response features
- [] no_save = false should save document and still return json string instead of message on create document
-
- [] RBAC integration with header
- [] clean io prepping for config of io
- [] don't store "jacs_private_key_password": in config, don't display
- [] minor feature - no_save = false should save document and still return json string instead of message on create document

## jacspy
- [] install jacs cli with the python wheel
- [] python based instructions for how to create - cli create agent
1. cli create agent
2. config jacspy to load each agent
--------------------

- [] auto generate agent doc from MCP server list, auto versions
- [] traceable, verifiable request logs
- [] fastmcp client and server stdio
- [] fastmcp client and server websocket
- [] publish jacspy to pypi
- [] github actions builder for linux
- [] mcp make decorator for @resource
- [] mcp make sure "list" request is signed
## 0.3.5

- [x] Update documentation.

### JACS core

- [x] add timestamp to prevent replay attacks to request/response features
- [x] make cli utils available to other libs
- [x] *** start effort to channel all logging to jacs -> open telemetry -> fs or elsewhere that doesn't write to stdio on
1. the main traffic for sign and verify
2. all logs generated

### jacspy

- [x] install python mcp libs with the python wheel, use python loader to extend/export jacs.so

## jacsnpm

proof of concept

- [] typescript mcp client and server
- [] npm install jacs (cli and available to plugin)
- [x] scaffold
- [x] use refactored agent trait instead of replicating
- [x] typescript mcp client and server tests
- [x] test sse mcp client and server
- [x] node express middleware


--------------------

Expand All @@ -86,7 +122,7 @@ proof of concept

- [x] make decorator for easy use in @tools
- [x] new local builder
- [] fastmcp client and server sse
- [x] fastmcp client and server sse
- [x] jacspy test - sign(content) -> (signature, agentid, agentversion, documentid, documentversion)
- [x] jacspy test - verify(content, signature, agentid, agentversion) -> bool, error

Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[workspace]
members = [
"jacs",
"jacs",
"jacsnpm",
# "mcp-server",
"jacspy"
]
resolver = "3"
rust-version = "1.85"


readme = "README.md"
authors = ["HAI.AI <engineering@hai.io>"]
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@


build-jacs:
cd jacs && cargo install --path . --force
cd jacs && cargo install --path . --force --features cli
~/.cargo/bin/jacs --help
~/.cargo/bin/jacs version

test-jacs:
cd jacs && RUST_BACKTRACE=1 cargo test -- --nocapture
cd jacs && RUST_BACKTRACE=1 cargo test --features cli -- --nocapture

test-jacs-cli:
cd jacs && RUST_BACKTRACE=1 cargo test --test cli_tests -- --nocapture
cd jacs && RUST_BACKTRACE=1 cargo test --features cli --test cli_tests -- --nocapture



publish-jacs:
cargo publish --dry-run -p jacs
cargo publish --features cli --dry-run -p jacs


test: test-jacs test-jacspy
Expand Down
76 changes: 64 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,74 @@
# JACS

Welcome to JACS (JSON Agent Communication Standard). JACS library provides
Welcome to JACS (JSON Agent Communication Standard).

1. a way to identify, trust and verify AI agents
2. authorize Agents
3. create, update, and verify documents
JACS is used by agents to validate the source and identity of data. The data may be ephemeral, changing, or idempotent such as files, identities, logs, http requests.

This repo and general usage consists of
Example uses:

1. A document is sitting on a server. Where did it come from? Who has access to it?
2. An MCP server gets a request from an unknown agent, the oauth flow doesn't guarantee the identity of the client or the server after the initial handshake.
3. a document is modified by multiple human and AI collaborators. Which one is latest, correct version?

This repo includes JACS available in several languages:

1. a cli tool to bootstrap an agent or documents
2. Rust Library for general integrations
3. Rust MCP server for LLM usage
4. Python MCP server and client integrations for AUTH
5. MORE PLANNED
1. the main [rust jacs lib](./jacs/) and cli to bootstrap an agent or documents
2. [Python library](./jacspy/) for use as middleware in any http and with MCP
3. [Node JS library](./jacsnpm) cli, middleware, and use with MCP

## Python quickstart

Install with `pip install jacs` with example using [fastmcp](https://github.com/jlowin/fastmcp)

```python
# server
import jacs
from jacs.mcp import JACSMCPServer, JACSMCPClient
from mcp.server.fastmcp import FastMCP

# client
# client = JACSMCPClient(server_url)

# setup
jacs_config_path = "jacs.server.config.json"
# set the secret
# os.environ["JACS_PRIVATE_KEY_PASSWORD"] = "hello"
jacs.load(str(jacs_config_path))

mcp = JACSMCPServer(FastMCP("Authenticated Echo Server"))

@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b

if __name__ == "__main__":
mcp.run()

```

## Node JS

```js



```


## Rust

The core library is used in all other implementations.

`cargo install jacs` is useful for it's cli, but to develop `cargo add jacs` is all that's needed.



## License

For more details see [jacs/README.md](jacs/README.md)
Please note that the [license][./LICENSE] isa *modified* Apache 2.0, with the [Common Clause](https://commonsclause.com/) preamble. In simple terms, unless you are competing with HAI.AI, you can create commercial products with JACS.
The [license][./LICENSE] is a *modified* Apache 2.0, with the [Common Clause](https://commonsclause.com/) preamble.
In simple terms, unless you are directly competing with HAI.AI, you can create commercial products with JACS.
This licensing doesn't work, please reach out to hello@hai.io.

------
2024, 2025 https://hai.ai
5 changes: 4 additions & 1 deletion jacs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ debug/
target/
.idea



# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
Expand All @@ -17,4 +19,5 @@ Cargo.lock
jacs.config.json
.DS_Store
tests/fixtures/documents/*
tests/scratch/*
tests/scratch/*
opentelemetry-rust
36 changes: 28 additions & 8 deletions jacs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jacs"
version = "0.3.4"
version = "0.3.5"
edition = "2024"
rust-version = "1.85"
resolver = "3"
Expand Down Expand Up @@ -63,7 +63,6 @@ strum = "0.27.1"
strum_macros = "0.27.0"
secrecy = "0.10.3"
aes-gcm = "0.10.3"
clap = { version = "4.5.4", features = ["derive", "cargo"] }
regex = "1.11.1"
mime_guess = "2.0.5"
flate2 = "1.1.1"
Expand All @@ -74,10 +73,26 @@ validator = "0.20.0"
uuid = { version = "1.16.0", features = ["v4", "v7", "js"] }
env_logger = "0.11.8"
futures-util = "0.3.31"
referencing = "0.29.1"
referencing = "0.30.0"
futures-executor = "0.3.31"
update = "0.0.0"
getset = "0.1.5"
clap = { version = "4.5.4", features = ["derive", "cargo"], optional = true }
ratatui = { version = "0.29.0", optional = true }


tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
tracing-appender = "0.2"
tracing-opentelemetry = "0.30.0"
opentelemetry = { version = "0.30.0", features = [] }
opentelemetry-otlp = { version = "0.30.0", features = ["http-proto", "reqwest-client"] }
opentelemetry_sdk = { version = "0.30.0", features = ["rt-tokio"] }
metrics = "0.24.2"
metrics-exporter-prometheus = "0.17"

# opentelemetry-prometheus = "0.29.1"


# libp2p = "0.55.0"
# [target.'cfg(target_os = "macos")'.dependencies]
Expand All @@ -89,12 +104,12 @@ getset = "0.1.5"

[dev-dependencies]
color-eyre = "0.6"
criterion = "0.5.1"
criterion = "0.6.0"
mdbook = "0.4.48"
assert_cmd = "2.0"
predicates = "3.1"
tempfile = "3.19.1"
serial_test = "0.6.0"
serial_test = "3.2.0"
futures = "0.3"

[lib]
Expand All @@ -109,17 +124,22 @@ reqwest = { version ="0.12.12", features = ["blocking", "json"] }
walkdir = "2.5.0"
object_store = { version ="0.12.0", features = ["serde","serde_json", "aws", "http"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.100"
web-sys = { version = "0.3", features = ["Storage", "Window"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.100"
web-sys = { version = "0.3", features = ["Storage", "Window"] }

[[bin]]
name = "jacs"
path = "src/bin/cli.rs"
required-features = ["cli"]

[features]
cli = ["dep:clap", "dep:ratatui"]

[[bench]]
name = "sign_and_check_sig"
harness = false

[package.metadata.cargo-install]
bin = ["jacs"]

Loading