Observed since 20 Oct, 16:57 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
aa-kit
The Universal AI Agent Framework for the MCP Era
The Universal AI Agent Framework for the MCP Era
AA Kit is a Python framework designed to build AI agents that naturally compose into ecosystems. Every agent is simultaneously a standalone agent, an MCP server, and an MCP client - creating true interoperability across the entire AI landscape.
"Make simple things simple, complex things possible, and everything interoperable"
AA Kit fills the gap left by existing frameworks by being:
from aakit import Agent
# Create an agent in 3 lines
agent = Agent(
name="assistant",
instruction="You are a helpful assistant",
model="gpt-4o"
)
# Chat synchronously - no async/await needed!
response = agent.chat("Hello! What can you help me with?")
print(response)
# Stream responses
for chunk in agent.stream_chat("Tell me a story"):
print(chunk, end='', flush=True)
# Have a conversation with context
with agent.conversation() as chat:
response1 = chat.send("Hello!")
response2 = chat.send("Tell me more") # Remembers context!
# Interactive mode
agent.interactive() # Start a REPL-like chat
# Deploy as MCP server
agent.serve_mcp(port=8080) # Now accessible to any MCP client
No more async/await complexity for basic use cases! AA Kit now provides both sync and async APIs:
# Synchronous (NEW!) - Perfect for scripts and simple use cases
response = agent.chat("Hello") # Just works!
# Asynchronous - When you need it for advanced use cases
response = await agent.achat("Hello") # Async version with 'a' prefix
pip install aa-kit
Requirements:
from aakit import Agent
agent = Agent(
name="my_agent", # Unique identifier
instruction="Your role description", # System prompt
model="gpt-4", # LLM to use
tools=[], # Optional tools
memory=None, # Optional memory backend
reasoning="simple" # Reasoning pattern
)
# Use it immediately - no setup needed!
response = agent.chat("Hello!") # Synchronous
response = await agent.achat("Hello!") # Async when needed
# Use conversation context manager
with agent.conversation() as chat:
chat.send("Start a topic")
chat.send("Continue discussing") # Maintains context
chat.save("conversation.json") # Save for later
# Define tools as regular Python functions
def search_database(query: str) -> str:
return f"Results for: {query}"
def create_ticket(issue: str) -> str:
return f"Ticket #{random.randint(1000, 9999)} created"
# Agent automatically converts them to MCP
agent = Agent(
name="support",
instruction="You help customers",
model="gpt-4",
tools=[search_database, create_ticket]
)
# Your agent is automatically an MCP server
agent.serve_mcp(port=8080)
# Other agents can now use it as a tool
other_agent = Agent(
name="manager",
instruction="You coordinate support",
model="gpt-4",
tools=["http://localhost:8080"] # Use the support agent
)
# Choose how your agent thinks
simple_agent = Agent("You chat", model="gpt-4", reasoning="simple")
react_agent = Agent("You solve problems", model="gpt-4", reasoning="react")
cot_agent = Agent("You analyze", model="gpt-4", reasoning="chain_of_thought")
# Memory is injected, not built-in
agent = Agent(
name="assistant",
instruction="You remember conversations",
model="gpt-4",
memory="redis://localhost" # Any storage backend
)
# Automatic model selection and fallbacks
agent = Agent("assistant", "You help", model="auto") # OpenAI → Anthropic → Local
agent = Agent("assistant", "You help", model=["gpt-4", "claude-3"]) # Fallback chain
# AA Kit agents work in any framework
my_agent = Agent("Helper", model="gpt-4")
# Use in LangChain
langchain_tool = Tool.from_mcp(my_agent.mcp_endpoint)
# Use in CrewAI
crewai_tool = MCPTool(my_agent.mcp_endpoint)
# Minimal agent
agent = Agent(
name="math_helper",
instruction="You help with math",
model="gpt-4"
)
# With tools
calculator = Agent(
name="calculator",
instruction="You solve math problems",
model="gpt-4",
tools=[add, multiply, divide]
)
# With memory
personal_assistant = Agent(
name="assistant",
instruction="You are my personal assistant",
model="gpt-4",
memory="sqlite://assistant.db"
)
# Agents use other agents naturally
researcher = Agent("You research topics", model="gpt-4", tools=[web_search])
writer = Agent("You write articles", model="claude-3")
def create_content(topic):
research = researcher.chat(f"Research {topic}")
article = writer.chat(f"Write an article about: {research}")
return article
# Local development
agent.serve() # localhost:8000
# Production
agent.deploy(mode="serverless") # Auto-scaling cloud deployment
┌─────────────────┐
│ Agent │
├─────────────────┤
│ • Name │
│ • Instruction │
│ • Model │
│ • Tools (MCP) │
│ • Memory │
│ • Reasoning │
└─────────────────┘
│
▼
┌─────────────────┐
│ MCP Server │
├─────────────────┤
│ • Auto-generated│
│ • Standard API │
│ • Tool calls │
│ • Responses │
└─────────────────┘
from aakit import Agent
def search_orders(customer_id: str) -> str:
return f"Orders for {customer_id}: [Order #1, Order #2]"
def create_ticket(issue: str) -> str:
return f"Support ticket created: {issue}"
support_agent = Agent(
name="support",
instruction="""You are a helpful customer support agent.
Help customers with orders and issues. Be empathetic and solution-focused.""",
model="gpt-4",
tools=[search_orders, create_ticket],
reasoning="react"
)
# Use the agent
response = support_agent.chat("I can't find my order #12345")
print(response)
from aakit import Agent
# Define specialized agents
researcher = Agent(
name="researcher",
instruction="You research topics thoroughly using web search",
model="gpt-4",
tools=[web_search]
)
writer = Agent(
name="writer",
instruction="You write engaging, well-structured articles",
model="claude-3"
)
editor = Agent(
name="editor",
instruction="You review and improve written content",
model="gpt-4"
)
# Expose team as MCP services
from aakit import serve_mcp
serve_mcp({
"researcher": researcher,
"writer": writer,
"editor": editor
}, port=8080)
# Now other agents can use the entire team
coordinator = Agent(
name="coordinator",
instruction="You coordinate content creation using the research, writing, and editing team",
model="gpt-4",
tools=["http://localhost:8080/researcher",
"http://localhost:8080/writer",
"http://localhost:8080/editor"]
)
def analyze_code(code: str) -> str:
"""Analyze code for potential issues"""
return f"Analysis of {len(code)} characters of code..."
def suggest_improvements(analysis: str) -> str:
"""Suggest code improvements"""
return f"Improvements based on: {analysis[:50]}..."
code_agent = Agent(
name="code_reviewer",
instruction="""You are a senior code reviewer.
Analyze code for bugs, security issues, and best practices.""",
model="gpt-4",
tools=[analyze_code, suggest_improvements],
reasoning="chain_of_thought"
)
# Use with different models for cost optimization
quick_review = Agent(
name="quick_reviewer",
instruction="You do quick code reviews",
model="gpt-3.5-turbo",
tools=[analyze_code]
)
class Agent:
def __init__(
self,
name: str,
instruction: str,
model: str | List[str] = "auto",
tools: List[Callable | str] = None,
memory: str | MemoryBackend = None,
reasoning: str = "simple",
temperature: float = 0.7,
max_tokens: int = None,
rate_limit: int = None
)
def chat(self, message: str) -> str:
"""Send a message to the agent"""
def conversation(self) -> Conversation:
"""Start a conversation with context management"""
def interactive(self) -> None:
"""Start interactive terminal chat"""
def serve(self, port: int = 8000) -> None:
"""Start REST API + WebSocket server"""
def serve_mcp(self, port: int = 8080) -> None:
"""Start MCP server"""
def deploy(self, mode: str = "serverless") -> str:
"""Deploy to cloud"""
@property
def mcp_endpoint(self) -> str:
"""Get MCP endpoint URL"""
from aakit import serve_mcp, discover_mcp_tools
# Serve multiple agents as MCP
serve_mcp({
"agent1": agent1,
"agent2": agent2
}, port=8080)
# Discover available MCP tools
tools = discover_mcp_tools("http://localhost:8080")
# Start agent with web UI
agent.serve() # http://localhost:8000
# MCP endpoint available at
# http://localhost:8000/mcp
# Serverless deployment (auto-scaling)
agent.deploy(mode="serverless")
# Container deployment
agent.deploy(mode="container")
# Kubernetes deployment
agent.deploy(mode="kubernetes")
# LLM Configuration
OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key
# Memory Configuration
REDIS_URL=redis://localhost:6379
DATABASE_URL=postgresql://user:pass@localhost/db
# AA Kit Configuration
AAKIT_DEFAULT_MODEL=gpt-4
AAKIT_DEBUG=true
We welcome contributions! See CONTRIBUTING.md for guidelines.
git clone https://github.com/josharsh/aa-kit
cd aa-kit
pip install -e ".[dev]"
pytest
MIT License - see LICENSE for details.
AA Kit - Building the future of AI agent interoperability 🚀
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
openaiEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | openai>=1.0.0 | runtime |
anthropicEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | anthropic>=0.8.0 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.0.0 | runtime |
aiohttpEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | aiohttp>=3.8.0 | runtime |
uvicornEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | uvicorn>=0.20.0 | runtime |
fastapiEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.95.0 | runtime |
websocketsEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | websockets>=11.0.0 | runtime |
redisEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | redis>=4.5.0 | runtime |
aiosqliteEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | aiosqlite>=0.19.0 | runtime |
asyncpgEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | asyncpg>=0.28.0 | runtime |
richEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | rich>=13.0.0 | runtime |
typerEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | typer>=0.9.0 | runtime |
python-dotenvEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | python-dotenv>=1.0.0 | runtime |
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.24.0 | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.0.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.21.0; extra == "dev" | runtime |
pytest-mockEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest-mock>=3.10.0; extra == "dev" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | black>=23.0.0; extra == "dev" | runtime |
isortEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | isort>=5.12.0; extra == "dev" | runtime |
mypyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | mypy>=1.0.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.0.260; extra == "dev" | runtime |
pre-commitEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pre-commit>=3.0.0; extra == "dev" | runtime |
mkdocsEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | mkdocs>=1.4.0; extra == "docs" | runtime |
mkdocs-materialEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | mkdocs-material>=9.0.0; extra == "docs" | runtime |
mkdocs-mermaid2-pluginEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | mkdocs-mermaid2-plugin>=0.6.0; extra == "docs" | runtime |
aa-kitEnvironment{
"extras": "dev,docs",
"marker": "extra == \"all\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | aa-kit[dev,docs]; extra == "all" | runtime |
bdist_wheel · 105.24 KB · Python py3
sdist · 88.71 KB · Python source
Observed since 20 Oct, 16:57 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:dbf581c8538e23de7b2ed433e8062c807ccbd25c1dfd93d8e5a06be4d8943d19