Integrating with Agentic Fabriq MCP using Keycloak Authentication
This guide shows how to integrate any application with Agentic Fabriq MCP servers using the keycloak authentication method. This method is for applications that authenticate users directly through Agentic Fabriq's Keycloak instance.
When to use this method:
- Your app authenticates users directly via Agentic Fabriq's Keycloak
- You have a Keycloak access token from AF's identity service
- You want single sign-on with AF's user directory
Part 1: Agentic Fabriq Setup
Step 1: Create an Application
- Log in to Agentic Fabriq Dashboard
- Navigate to the admin console, and find the tab: Applications → Create Application
- Fill in: Application Name: Your app name
- Add scopes that you want the application to have
- Click Create
- Save the activation key
- Select which users will have access to this application
Step 2: Activate and Get Credentials
- After creation, click Activate
- Fill in:
- Application ID: Application ID from Step 1
- IdP Client ID: Leave blank (not using an external IdP)
- IdP Client Secret: Leave blank (not using an external IdP)
- Save these credentials securely:
- App ID:
org-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_my-app - App Secret:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- App ID:
Step 3: Configure Tool Access
- Go to your application → Tools tab
- Enable the MCP servers/tools your users should access
- Configure permissions for each tool as needed
Step 4: Get Keycloak Configuration
From step 2: Save the App ID and App Secret.
Part 2: Application Integration
Step 1: Install the SDK
pip install agentic-fabriq-sdkStep 2: Configure OIDC Authentication
Set up your application to authenticate users via AF's Keycloak. Example environment variables:
# Agentic Fabriq Application Credentials
AF_APP_ID="your-keycloak-client-id"
AF_APP_SECRET="your-keycloak-client-secret"
# Keycloak OIDC Configuration (from Agentic Fabriq)
OAUTH_CLIENT_ID="your-keycloak-client-id"
OAUTH_CLIENT_SECRET="your-keycloak-client-secret"
OPENID_PROVIDER_URL="https://auth.agenticfabriq.com/realms/your-realm/.well-known/openid-configuration"
OAUTH_REDIRECT_URI="http://localhost:8080/callback"
OAUTH_SCOPES="openid profile email"Step 3: Implement the OAuth Flow
Your application needs to:
- Redirect users to Keycloak for login (ideally with a front end of some sort)
- Handle the callback and extract the access token
- Use the token with the AF SDK
Example OAuth callback handling (Python/FastAPI):
from authlib.integrations.starlette_client import OAuth
oauth = OAuth()
oauth.register(
name='keycloak',
client_id=OAUTH_CLIENT_ID,
client_secret=OAUTH_CLIENT_SECRET,
server_metadata_url=OPENID_PROVIDER_URL,
client_kwargs={'scope': 'openid profile email'}
)
@app.get("/login")
async def login(request: Request):
redirect_uri = OAUTH_REDIRECT_URI
return await oauth.keycloak.authorize_redirect(request, redirect_uri)
@app.get("/callback")
async def callback(request: Request):
token = await oauth.keycloak.authorize_access_token(request)
access_token = token.get("access_token")
# Store the access_token for MCP calls
return {"status": "logged in"}Step 4: Connect to MCP Servers
Use the af_sdk.MCPClient with the keycloak method:
from af_sdk import MCPClient
# Get the Keycloak access token from your OAuth session
keycloak_token = get_user_access_token() # Your session management
# Create the MCP client
async with MCPClient(
method="keycloak",
app_id="org-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_my-app",
app_secret="your-app-secret",
keycloak_token=keycloak_token,
) as client:
# List available tools
tools = await client.list_tools()
print(f"Available tools: {[t['name'] for t in tools]}")
# Call a tool
result = await client.call_tool("tool-name", {"param": "value"})
print(result)Part 3: SDK Reference
MCPClient Parameters (Keycloak Method)
| Parameter | Required | Description |
|---|---|---|
method | Yes | Must be "keycloak" |
app_id | Yes | Your Agentic Fabriq Application ID |
app_secret | Yes | Your Agentic Fabriq Application Secret |
keycloak_token | Yes | The Keycloak access token from user login |
Available Methods
# List all available tools
tools = await client.list_tools()
# Call a specific tool
result = await client.call_tool(name="tool-name", arguments={"key": "value"})
# Check if a tool exists
exists = client.has_tool("tool-name")
# Get tool names
names = client.tool_names
# Get a specific tool definition
tool = client.get_tool("tool-name")Synchronous Usage
from af_sdk import MCPClient
with MCPClient(
method="keycloak",
app_id=APP_ID,
app_secret=APP_SECRET,
keycloak_token=token,
) as client:
tools = client.list_tools_sync()
result = client.call_tool_sync("tool-name", {"param": "value"})Part 4: Token Lifecycle
Token Expiration
- Keycloak tokens typically expire in 5-30 minutes
- The SDK handles token exchange on
connect() - For long-running sessions, refresh the Keycloak token and create a new client
# When Keycloak token is refreshed
new_keycloak_token = await refresh_keycloak_token()
# Create new MCP client with fresh token
client = MCPClient(
method="keycloak",
app_id=APP_ID,
app_secret=APP_SECRET,
keycloak_token=new_keycloak_token,
)
await client.connect()Part 5: Error Handling
Common Errors
from af_sdk.auth.applications import AuthenticationError
try:
async with MCPClient(...) as client:
tools = await client.list_tools()
except AuthenticationError as e:
if "401" in str(e):
# Token expired or invalid
print("Please log in again")
elif "AUTHENTICATION_FAILED" in str(e):
# Credentials incorrect
print("Check your app_id and app_secret")Troubleshooting
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Expired or invalid Keycloak token | Refresh OAuth token and retry |
AUTHENTICATION_FAILED | Wrong app credentials | Verify app_id and app_secret |
Token exchange failed | Keycloak token invalid | Ensure token is from AF's Keycloak |
Connection failed | Network or server issue | Check connectivity to AF servers |
Part 6: Best Practices
Security
- Never expose secrets - Keep
app_secretserver-side only - Use HTTPS - Always use TLS in production
- Validate tokens - Verify Keycloak tokens before using them
- Short token lifetime - Configure appropriate expiration
- Secure storage - Store tokens encrypted at rest
Performance
- Reuse clients - Keep
MCPClientinstances for multiple calls - Handle disconnects - Implement reconnection logic
- Cache tool lists - Don't call
list_tools()on every request
Example: Production Pattern
class MCPManager:
def __init__(self, app_id: str, app_secret: str):
self.app_id = app_id
self.app_secret = app_secret
self._clients: dict[str, MCPClient] = {}
async def get_client(self, user_id: str, keycloak_token: str) -> MCPClient:
# Check if we have a valid client
if user_id in self._clients:
return self._clients[user_id]
# Create new client
client = MCPClient(
method="keycloak",
app_id=self.app_id,
app_secret=self.app_secret,
keycloak_token=keycloak_token,
)
await client.connect()
self._clients[user_id] = client
return client
async def cleanup(self, user_id: str):
if user_id in self._clients:
await self._clients[user_id].disconnect()
del self._clients[user_id]Quick Start Checklist
- ☐ Created application in Agentic Fabriq Dashboard
- ☐ Activated application and saved credentials
- ☐ Configured tool access permissions
- ☐ Installed
agentic-fabriq-sdk - ☐ Implemented Keycloak OAuth flow in your app
- ☐ Integrated
MCPClientwithmethod="keycloak" - ☐ Tested tool listing and calling
- ☐ Implemented token refresh logic
Need help?
Our team is here to help you get started.