Skip to content

Commit 58cbe36

Browse files
committed
chore: quick start quide
1 parent d110b6d commit 58cbe36

1 file changed

Lines changed: 159 additions & 0 deletions

File tree

README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,165 @@
22

33
A collection of Python packages for KeyCard services, organized as a uv workspace.
44

5+
## Quick Start
6+
7+
Get up and running with KeyCard's MCP (Model Context Protocol) integration in minutes:
8+
9+
### 1. Install the Package
10+
11+
```bash
12+
pip install keycardai-mcp```
13+
14+
### 2. Create Your First MCP Server
15+
16+
```python
17+
from mcp.server.fastmcp import FastMCP, Context
18+
from typing import Any
19+
20+
from keycardai.mcp.server.auth import AuthProvider
21+
22+
# Obtain this from Keycard Console UI
23+
zone_id = "5hp9n12kibpg042gwrsvrqiqiv"
24+
25+
access = AuthProvider(
26+
zone_url=f"https://{zone_id}.keycard.cloud",
27+
mcp_server_name="Hello World Mcp",
28+
mcp_server_url="http://127.0.0.1:8000"
29+
)
30+
31+
mcp = FastMCP("Minimal MCP", auth=access.get_auth_settings(), token_verifier=access.get_token_verifier())
32+
33+
@mcp.tool()
34+
async def get_hello_world(request_ctx: Context) -> dict[str, Any]:
35+
return {"message": "Hello, World!"}
36+
37+
app = mcp.streamable_http_app()
38+
```
39+
40+
### 3. Run Your Server
41+
42+
```bash
43+
uvicorn main:app --host 0.0.0.0 --port 8000
44+
```
45+
46+
Your MCP server is now running with KeyCard authentication! 🎉
47+
48+
### 4. Add Access Control (Optional)
49+
50+
Protect your tools with fine-grained access control and automatic token management:
51+
52+
```python
53+
import os
54+
from mcp.server.fastmcp import FastMCP, Context
55+
from typing import Any
56+
57+
from keycardai.mcp.server.auth import AuthProvider, AccessContext, BasicAuth
58+
59+
# Obtain this from Keycard Console UI
60+
zone_id = "5hp9n12kibpg042gwrsvrqiqiv"
61+
62+
access = AuthProvider(
63+
zone_url=f"https://{zone_id}.keycard.cloud",
64+
mcp_server_name="Hello World Mcp",
65+
mcp_server_url="http://127.0.0.1:8000",
66+
auth=BasicAuth(
67+
client_id=os.getenv("KEYCARD_CLIENT_ID"),
68+
client_secret=os.getenv("KEYCARD_CLIENT_SECRET")
69+
)
70+
)
71+
72+
mcp = FastMCP("Minimal MCP", auth=access.get_auth_settings(), token_verifier=access.get_token_verifier())
73+
74+
@mcp.tool()
75+
@access.grant("https://protected-api.com")
76+
async def get_hello_world(ctx: AccessContext, request_ctx: Context) -> dict[str, Any]:
77+
access_token = ctx.access("https://protected-api.com").access_token
78+
return {"message": "Hello, World!", "access_token": access_token}
79+
80+
app = mcp.streamable_http_app()
81+
```
82+
83+
Set your KeyCard credentials as environment variables:
84+
```bash
85+
export KEYCARD_CLIENT_ID="your_client_id"
86+
export KEYCARD_CLIENT_SECRET="your_client_secret"
87+
```
88+
89+
The `@access.grant()` decorator ensures users have proper permissions and automatically provides access tokens for external APIs.
90+
91+
### 5. Multi-Zone Support (Advanced)
92+
93+
For production applications serving multiple organizations, you can configure a single server to handle multiple KeyCard zones:
94+
95+
```python
96+
import contextlib
97+
import os
98+
import json
99+
from typing import Any
100+
from dotenv import load_dotenv
101+
102+
from starlette.applications import Starlette
103+
from starlette.middleware import Middleware
104+
from starlette.middleware.cors import CORSMiddleware
105+
from mcp.server.fastmcp import FastMCP, Context
106+
107+
from keycardai.mcp.server.auth import AuthProvider, AccessContext, MultiZoneBasicAuth
108+
109+
# Load environment variables from .env file
110+
load_dotenv()
111+
112+
# Parse zone configuration from environment variable
113+
zone_config_str = os.getenv("KEYCARD_ZONE_CONFIG", "[]")
114+
zone_configs = json.loads(zone_config_str)
115+
116+
# Create auth credentials map for MultiZoneBasicAuth
117+
auth_map = {}
118+
for config in zone_configs:
119+
zone_id = config["zone_id"]
120+
auth_map[zone_id] = (config["client_id"], config["client_secret"])
121+
122+
access = AuthProvider(
123+
zone_url="https://keycard.cloud",
124+
mcp_server_name="Multi-Zone MCP",
125+
auth=MultiZoneBasicAuth(auth_map),
126+
enable_multi_zone=True,
127+
)
128+
129+
mcp = FastMCP("Multi-Zone MCP")
130+
131+
@mcp.tool()
132+
@access.grant("https://protected-api.com")
133+
async def get_hello_world(ctx: AccessContext, request_ctx: Context) -> dict[str, Any]:
134+
access_token = ctx.access("https://protected-api.com").access_token
135+
return {"message": "Hello, World!", "access_token": access_token}
136+
137+
@contextlib.asynccontextmanager
138+
async def lifespan(app: Starlette):
139+
async with contextlib.AsyncExitStack() as stack:
140+
await stack.enter_async_context(mcp.session_manager.run())
141+
yield
142+
143+
middleware = [
144+
Middleware(CORSMiddleware, allow_origins=['*'])
145+
]
146+
147+
app = Starlette(
148+
routes=access.get_mcp_router(mcp.streamable_http_app()),
149+
middleware=middleware,
150+
lifespan=lifespan
151+
)
152+
```
153+
154+
Set your zone configuration via environment variables:
155+
```bash
156+
export KEYCARD_ZONE_CONFIG='[
157+
{"zone_id": "zone1", "client_id": "client1", "client_secret": "secret1"},
158+
{"zone_id": "zone2", "client_id": "client2", "client_secret": "secret2"}
159+
]'
160+
```
161+
162+
> **Need a KeyCard zone?** Sign up at [keycard.cloud](https://keycard.cloud) to get your zone ID and start building secure MCP applications.
163+
5164
## Overview
6165

7166
This workspace contains multiple Python packages that provide various KeyCard functionality:

0 commit comments

Comments
 (0)