Skip to content

Commit bc7e020

Browse files
Merge pull request #36 from keycardai/feat/mcp-client
feat(keycardai-mcp): client implementation
2 parents ee4dfb4 + 2053798 commit bc7e020

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+18246
-40
lines changed

packages/mcp-fastmcp/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependencies = [
1010
"pydantic>=2.11.7",
1111
"pydantic-settings>=2.7.1",
1212
"httpx>=0.27.2",
13-
"keycardai-oauth>=0.5.0",
13+
"keycardai-oauth>=0.6.0",
1414
"fastmcp==2.13.0",
1515
"keycardai-mcp>=0.15.0",
1616
]

packages/mcp/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,45 @@ uvicorn server:app
101101
-**Token Exchange**: Automatic delegated token exchange for accessing external APIs
102102
-**Production Ready**: Battle-tested security patterns and error handling
103103

104+
## MCP Client
105+
106+
The Keycard MCP SDK also includes **MCP Client** for connecting to MCP servers with built-in authentication support.
107+
108+
### Key Features
109+
110+
-**OAuth 2.0 Support**: Automatic OAuth flow handling for protected MCP servers
111+
-**AI Agent Integrations**: Pre-built integrations with LangChain and OpenAI Agents SDK
112+
113+
### Quick Start
114+
115+
```python
116+
import asyncio
117+
from keycardai.mcp.client import Client
118+
119+
servers = {
120+
"my-server": {
121+
"url": "http://localhost:7878/mcp",
122+
"transport": "http",
123+
"auth": {"type": "oauth"} # OAuth configured via server config
124+
}
125+
}
126+
127+
async def main():
128+
async with Client(servers) as client:
129+
# List available tools
130+
tools = await client.list_tools()
131+
132+
# Call a tool
133+
result = await client.call_tool("my-tool", {"arg": "value"})
134+
print(result)
135+
136+
asyncio.run(main())
137+
```
138+
139+
### Learn More
140+
141+
For comprehensive documentation including use cases, configuration examples, and advanced patterns, see the [MCP Client README](src/keycardai/mcp/client/README.md).
142+
104143
### Delegated Access
105144

106145
Keycard allows MCP servers to access other resources on behalf of users with automatic consent and secure token exchange.

packages/mcp/pyproject.toml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ requires-python = ">=3.10"
77
license = { text = "MIT" }
88
authors = [{ name = "Keycard", email = "[email protected]" }]
99
dependencies = [
10-
"keycardai-oauth>=0.5.0",
10+
"keycardai-oauth>=0.6.0",
1111
"mcp>=1.13.1",
1212
"pydantic>=2.11.7",
1313
"httpx>=0.27.2",
1414
"starlette>=0.47.3",
1515
"nanoid>=2.0.0",
16+
"aiohttp>=3.11.11",
17+
"aiosqlite>=0.20.0",
1618
]
1719
keywords = ["mcp", "model-context-protocol", "authentication", "authorization", "ai", "llm"]
1820
classifiers = [
@@ -36,6 +38,12 @@ test = [
3638
"pytest>=8.4.1",
3739
"pytest-asyncio>=1.1.0",
3840
"pytest-cov>=6.2.1",
41+
"pytest-timeout>=2.3.1",
42+
"fastmcp>=2.13.0", # For integration tests
43+
"keycardai-mcp-fastmcp", # For integration tests
44+
"openai-agents>=0.5.1",
45+
"langchain>=1.0.5",
46+
"langchain-openai>=1.0.2",
3947
]
4048

4149
[project.urls]
@@ -64,6 +72,7 @@ explicit = true
6472

6573
[tool.uv.sources]
6674
keycardai-oauth = { workspace = true }
75+
keycardai-mcp-fastmcp = { workspace = true }
6776

6877
[tool.hatch.build.targets.wheel]
6978
packages = ["src/keycardai"]
@@ -115,6 +124,11 @@ exclude_also = [
115124
[tool.pytest.ini_options]
116125
testpaths = ["tests"]
117126
addopts = "-ra -q"
127+
filterwarnings = [
128+
# Ignore deprecation warnings from uvicorn/websockets (not our code)
129+
"ignore::DeprecationWarning:websockets.*",
130+
"ignore::DeprecationWarning:uvicorn.*",
131+
]
118132

119133
[tool.commitizen]
120134
name = "cz_customize"

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

Lines changed: 1440 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)