Metadata-Version: 2.4
Name: unified-agent-protocol
Version: 1.1.0
Summary: Unified Agent Protocol — Universal interoperability layer for AI agents and tools
Author-email: "WhoMeta Inc." <opensource@whometa.io>
Maintainer-email: WhoMeta Labs <labs@whometa.io>
License: Apache-2.0
Project-URL: Homepage, https://www.whometa.io
Project-URL: Repository, https://github.com/WhoMeta-Inc/unifiedagentprotocol
Project-URL: Bug Tracker, https://github.com/WhoMeta-Inc/unifiedagentprotocol/issues
Project-URL: Changelog, https://github.com/WhoMeta-Inc/unifiedagentprotocol/blob/main/CHANGELOG.md
Keywords: ai-agents,protocol,interoperability,agent-tools,mcp,a2a,openai,anthropic,gemini,openapi,langchain,openwebui,agent-orchestration,tool-integration
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Classifier: Framework :: Pydantic :: 2
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: pydantic<3.0,>=2.5
Requires-Dist: typer<1.0,>=0.9
Provides-Extra: runtime
Requires-Dist: fastapi<1.0,>=0.110; extra == "runtime"
Requires-Dist: uvicorn<1.0,>=0.27; extra == "runtime"
Provides-Extra: registry
Requires-Dist: redis<6.0,>=5.0; extra == "registry"
Provides-Extra: validate
Requires-Dist: jsonschema<5.0,>=4.21; extra == "validate"
Provides-Extra: yaml
Requires-Dist: pyyaml<7.0,>=6.0; extra == "yaml"
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: jsonschema>=4.21; extra == "dev"
Requires-Dist: pyyaml>=6.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.5; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
Provides-Extra: all
Requires-Dist: unified-agent-protocol[registry,runtime,validate,yaml]; extra == "all"
Dynamic: license-file

# Unified Agent Protocol (UAP) — Core SDK

**Version 1.0** · Apache-2.0 · Python 3.10+

UAP is the **universal interoperability layer** for AI agents and tools.

Define an agent **once** in UAP — then ship it to **MCP**, **A2A**,
**OpenAI Assistants**, **Anthropic Tool Use**, **Google Gemini
Functions**, **OpenAPI 3**, **OpenWebUI**, **LangChain** — without
rewriting a single field. Every adapter is **bidirectional** and
declares its **LossInfo** explicitly. No silent data loss.

## What UAP gives you over MCP / A2A alone

| Concern | MCP | A2A | UAP |
|---------|:---:|:---:|:---:|
| Tool description schema | ✅ | — | ✅ |
| Agent-to-Agent runtime | — | ✅ | ✅ (via bridges) |
| Cross-vendor bridges | — | — | ✅ (9 formats) |
| Bidirectional round-trip | — | — | ✅ |
| Auth modelling (OAuth2/mTLS/SigV4/…) | partial | partial | ✅ |
| RBAC / Capabilities | — | — | ✅ |
| Compliance (GDPR/HIPAA/residency) | — | — | ✅ |
| Cost / latency hints | — | — | ✅ |
| URN identity | — | — | ✅ |
| Versioned wire format | ✅ | ✅ | ✅ |

## Install

```bash
pip install unified-agent-protocol            # core SDK only
pip install unified-agent-protocol[runtime]   # + FastAPI runtime
pip install unified-agent-protocol[all]       # + every optional dep
```

## Quick start

```python
from unifiedagentprotocol import (
    Tool, Agent, Skill, Parameter, ParameterSchema,
    Capabilities, SideEffects, Compliance, DataClassification,
    AuthConfig, AuthType, Endpoint, Transport, Envelope,
)

weather = Tool(
    id="urn:uap:tool:get-weather",
    name="get_weather",
    description="Return current weather for a city.",
    parameters=[Parameter(name="city", schema=ParameterSchema(type="string"))],
    endpoint=Endpoint(transport=Transport.HTTP,
                      url="https://api.example.com/weather", method="POST"),
    auth=AuthConfig(type=AuthType.API_KEY,
                    secret_ref="vault://kv/data/weather#token"),
    capabilities=Capabilities(idempotent=True,
                              side_effects=SideEffects.READ_ONLY,
                              deterministic=False,
                              requires_human_approval=False),
    compliance=Compliance(data_classification=DataClassification.PUBLIC,
                          regulations=["GDPR"], data_residency=["EU"]),
)

agent = Agent(
    id="urn:uap:agent:weather-bot",
    name="WeatherBot",
    description="Provides weather information.",
    tools=[weather],
    skills=[Skill(id="answer-weather", name="answer-weather",
                  description="Answer weather questions.")],
    endpoints=[Endpoint(transport=Transport.HTTP, url="https://bot.example.com")],
)

print(Envelope.of(agent).to_wire())
```

Ship it to every ecosystem:

```python
from unifiedagentprotocol.bridges.mcp        import to_mcp
from unifiedagentprotocol.bridges.a2a        import to_a2a
from unifiedagentprotocol.bridges.openai     import to_openai
from unifiedagentprotocol.bridges.anthropic  import to_anthropic
from unifiedagentprotocol.bridges.gemini     import to_gemini
from unifiedagentprotocol.bridges.openapi    import to_openapi

mcp_payload,    _ = to_mcp(agent)
a2a_card,       _ = to_a2a(agent)
oai_assistant,  _ = to_openai(agent)
claude_tool,    _ = to_anthropic(weather)
gemini_decl,    _ = to_gemini(weather)
openapi_spec,   _ = to_openapi(agent)
```

Every bridge also has an inverse `from_<format>(…)` returning
`(uap_object, LossInfo)`.

## CLI

```bash
uap version
uap schema-export --output-dir schemas/uap/1.0
uap bind  --input my_tool.json --format mcp --show-loss
uap validate --input my_agent.json
uap lint --input my_agent.json
uap serve --registry-path ./registry --port 8000
```

The auto-detect `bind` accepts MCP, A2A, OpenAI, Anthropic, OpenWebUI,
LangChain, OpenAPI 3, Swagger 2 and bare UAP envelopes.

## Architecture

```
┌──────────────────────────────────────────────────────────────┐
│  Runtime  (optional)   FastAPI adapter, /.well-known/agent   │
├──────────────────────────────────────────────────────────────┤
│  Registry (optional)   In-memory / Filesystem / pluggable    │
├──────────────────────────────────────────────────────────────┤
│  Bridges               MCP, A2A, OpenAI, Anthropic, Gemini,  │
│  (bidirectional)       OpenAPI, Swagger, OpenWebUI, LangChain│
├──────────────────────────────────────────────────────────────┤
│  Core IR (Schema)      Tool, Agent, Parameter (JSON-Schema), │
│                        Auth, Capabilities, Compliance, Cost, │
│                        Endpoint, Trigger, Envelope, LossInfo │
├──────────────────────────────────────────────────────────────┤
│  Wire Spec             schemas/uap/1.0/*.schema.json         │
└──────────────────────────────────────────────────────────────┘
```

Layer rules:

- `core/` depends on nothing but Pydantic + stdlib.
- `bridges/<x>/` depends only on `core/`.
- `runtime/` depends on `core/`, `bridges/`, `registry_impl/`.
- `cli/` is the only module allowed to import anywhere.

See [`docs/adr/0001-architecture-overview.md`](docs/adr/0001-architecture-overview.md)
and [`docs/spec/uap-1.0-wire-format.md`](docs/spec/uap-1.0-wire-format.md).

## Examples

- [`examples/01_define_tool_and_agent.py`](examples/01_define_tool_and_agent.py) — full enterprise-marked agent.
- [`examples/02_bridge_to_many_formats.py`](examples/02_bridge_to_many_formats.py) — same agent → six target formats.

## Testing

```bash
pytest -q
```

Bridge round-trip tests live under `tests/bridges/` and assert
`from_x(to_x(obj)) == obj` on the representable subset, with
`LossInfo` covering the rest.

## License

Apache 2.0 — see [LICENSE](LICENSE).
