AI2Web Ruby SDK (ai2web)
The Ruby reference implementation of the AI2Web protocol - for Rails, Sinatra, Rack, or plain Ruby. Mirrors @ai2web/core.
gem install ai2web
# or add to your Gemfile:
gem "ai2web"
require "ai2web"
manifest = Ai2Web.ai2web(name: "Example Store", url: "https://example.com", type: "ecommerce")
.capability("content")
.capability("commerce", endpoint: "/ai2w/products", checkout: true)
.transports(mcp: { enabled: true, endpoint: "/ai2w/mcp" }, rest: { enabled: true })
.auth(methods: %w[none oauth2], oauth2: { pkce: true, scopes: ["checkout"] })
.(requires_user_approval_for: ["purchase"])
.contact(support: "help@example.com")
.build
result = Ai2Web.validate(manifest) # { score: 90+, tier: "Standard", ... }
# Serve every AI2Web route from one call (framework-agnostic):
res = Ai2Web.handle({ manifest: manifest }, request.method, request.path, body, origin)
# => { status:, headers:, body: } -- render body as JSON (or text for /llms.txt)
Inputs may use symbol or string keys - the builder normalises to the string-keyed JSON the
spec defines, so validate also works directly on a JSON.parsed manifest.
Modules
| Module | Entry points |
|---|---|
Ai2Web::Manifest |
Ai2Web.ai2web(site) - fluent capability-model builder |
Ai2Web::Validator |
Ai2Web.validate(manifest) + AI Readiness scoring (spec §9/§11) |
Ai2Web::Negotiator |
Ai2Web.negotiate(manifest, agent) capability negotiation (spec §5) |
Ai2Web::Server |
Ai2Web.handle(opts, method, path, body, origin) framework-agnostic router |
Ai2Web::Safety |
Ai2Web.safe_public_url?(url) / .assert_safe_public_url!(url) SSRF guard |
Ai2Web::Schema |
Ai2Web.validate_schema(value, schema) action input validation |
Ai2Web::Export |
Ai2Web.to_llms_txt(m) / .to_agent_json(m) projections (RFC-0015) |
The builder also carries the v0.2 optional modules - .governance(...), .usage_policy(...),
.legal(...), .agent_identity(...), .knowledge(...) - and actions accept intent and
bindings. All are additive: a minimal manifest stays valid without them.
Serving from Rack / Sinatra
res = Ai2Web.handle({ manifest: MANIFEST, actions: { "track_order" => ->(body) { track(body) } } },
env["REQUEST_METHOD"], env["PATH_INFO"], parsed_body, request_origin)
body = res[:body].is_a?(String) ? res[:body] : JSON.generate(res[:body])
[res[:status], res[:headers], [body]]
handle routes /ai2w, /.well-known/ai2w, /llms.txt, /.well-known/agent.json (+ /agent.json),
/ai2w/negotiate, /ai2w/actions/:name and capability modules /ai2w/:name, validating action
input against each action's declared input_schema unless you pass validate_input: false.
Test
ruby test/run.rb # dependency-free; includes the shared conformance contract
Requires Ruby 3.0+. Zero runtime dependencies.
Licence
MIT.