Skip to content

Commit 6fffdde

Browse files
authored
Merge pull request #42 from keycardai/larry/agents-package
Crew AI Secure Tools Integration SDK
2 parents b0977a1 + 2044d82 commit 6fffdde

7 files changed

Lines changed: 2609 additions & 145 deletions

File tree

packages/mcp/pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ classifiers = [
3434
]
3535

3636
[project.optional-dependencies]
37+
crewai = [
38+
"crewai>=0.86.0",
39+
"nest-asyncio>=1.6.0",
40+
]
3741
test = [
3842
"pytest>=8.4.1",
3943
"pytest-asyncio>=1.1.0",
@@ -44,6 +48,7 @@ test = [
4448
"openai-agents>=0.5.1",
4549
"langchain>=1.0.5",
4650
"langchain-openai>=1.0.2",
51+
"crewai>=0.86.0",
4752
]
4853

4954
[project.urls]

packages/mcp/src/keycardai/mcp/client/README.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The Keycard MCP Client provides a simple, type-safe way to connect to MCP server
1010
- 🔐 **Automatic OAuth 2.0 flows** (PKCE with dynamic client registration)
1111
- 🏢 **Multi-user support** with isolated contexts
1212
- ☁️ **Serverless-ready** with stateless execution support
13-
- 🤖 **AI agent integrations** (OpenAI Agents, LangChain)
13+
- 🤖 **AI agent integrations** (OpenAI Agents, LangChain, CrewAI)
1414
- 💾 **Flexible storage** (in-memory, SQLite, custom backends)
1515
- 🔒 **Type-safe** with full protocol support
1616

@@ -22,14 +22,21 @@ The Keycard MCP Client provides a simple, type-safe way to connect to MCP server
2222

2323
### Installation
2424

25+
**Base installation** (includes LangChain and OpenAI Agents support):
26+
2527
```bash
2628
uv init --package mcp-cli && cd mcp-cli
29+
uv add keycardai-mcp
2730
```
2831

32+
**With CrewAI support** (requires additional dependencies):
33+
2934
```bash
30-
uv add keycardai-mcp
35+
uv add "keycardai-mcp[crewai]"
3136
```
3237

38+
> **Why the `[crewai]` extra?** CrewAI requires `nest-asyncio` to bridge CrewAI's synchronous tool interface with MCP's asynchronous client. LangChain and OpenAI Agents have native async support and work with the base installation.
39+
3340
### Basic Usage (CLI/Desktop Apps)
3441

3542
For simple command-line tools or desktop applications, create a file `src/mcp_cli/__init__.py`:
@@ -610,6 +617,18 @@ Follow the authorization link, and then refresh the page. It should show the too
610617

611618
## AI Agent Integrations
612619

620+
The MCP client provides integrations for popular AI agent frameworks. Each framework has different async support:
621+
622+
| Framework | Installation | Extra Required? | Why |
623+
|-----------|-------------|-----------------|-----|
624+
| **LangChain** | `uv add keycardai-mcp langchain` | No | Native async support via `coroutine=` parameter |
625+
| **OpenAI Agents** | `uv add keycardai-mcp openai-agents` | No | Native async support |
626+
| **CrewAI** | `uv add "keycardai-mcp[crewai]"` | **Yes** | Requires `nest-asyncio` for sync/async bridge |
627+
628+
> **Technical Note:** CrewAI tools use synchronous methods (`_run()`), while MCP clients are async. The `[crewai]` extra includes `nest-asyncio` to enable nested event loops for seamless integration.
629+
630+
---
631+
613632
### How Authentication Works with AI Agents
614633

615634
The MCP client provides AI framework integrations that automatically handle authentication flows. Here's how it works:
@@ -835,6 +854,91 @@ Run the OpenAI agent:
835854
uv run mcp-openai
836855
```
837856

857+
### CrewAI
858+
859+
Install dependencies:
860+
861+
```bash
862+
uv add "keycardai-mcp[crewai]"
863+
```
864+
865+
Set your OpenAI API key:
866+
867+
```bash
868+
export OPENAI_API_KEY="sk-..."
869+
```
870+
871+
Create `src/mcp_crewai/__init__.py`:
872+
873+
```python
874+
import asyncio
875+
from crewai import Agent, Task, Crew
876+
from langchain_openai import ChatOpenAI
877+
878+
from keycardai.mcp.client import Client
879+
from keycardai.mcp.client.integrations.crewai_agents import CrewAIClient
880+
881+
servers = {
882+
"my-server": {
883+
"url": "http://localhost:7878/mcp",
884+
"transport": "http",
885+
"auth": {"type": "oauth"}
886+
}
887+
}
888+
889+
async def run():
890+
async with Client(servers) as mcp_client:
891+
# Wrap MCP client for CrewAI
892+
async with CrewAIClient(mcp_client) as crewai_client:
893+
# Get tools converted to CrewAI format
894+
tools = await crewai_client.get_tools()
895+
print(f"Available tools: {len(tools)}")
896+
897+
# Get system prompt
898+
system_prompt = crewai_client.get_system_prompt(
899+
"You are a helpful assistant with access to MCP tools."
900+
)
901+
902+
# Create CrewAI agent
903+
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
904+
agent = Agent(
905+
role="MCP Assistant",
906+
goal=system_prompt,
907+
backstory="An AI assistant that can use MCP tools to help users.",
908+
tools=tools,
909+
llm=llm,
910+
verbose=True
911+
)
912+
913+
# Create task
914+
task = Task(
915+
description="List the available tools and use one of them to demonstrate functionality.",
916+
expected_output="A summary of the tools and the result of using one tool.",
917+
agent=agent
918+
)
919+
920+
# Create and run crew
921+
crew = Crew(
922+
agents=[agent],
923+
tasks=[task],
924+
verbose=True
925+
)
926+
927+
print("\nStarting CrewAI crew...")
928+
result = crew.kickoff()
929+
print(f"\nCrew result: {result}")
930+
931+
def main():
932+
"""Entry point for CrewAI agent."""
933+
asyncio.run(run())
934+
```
935+
936+
Run the CrewAI agent:
937+
938+
```bash
939+
uv run mcp-crewai
940+
```
941+
838942
---
839943

840944
## Troubleshooting

packages/mcp/src/keycardai/mcp/client/integrations/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@
3232
except ImportError:
3333
pass
3434

35+
# Try to import CrewAI integration
36+
try:
37+
from . import crewai_agents # noqa: F401
38+
__all__.extend(["crewai_agents"])
39+
except ImportError:
40+
pass
41+

0 commit comments

Comments
 (0)