Improve Composio Integration
The current Composio integration has a hybrid implementation where lib/agents/tools/geospatial.tsx uses a direct MCP client approach instead of the proper Composio SDK methods defined in mapbox_mcp/composio-mapbox.ts. 1
Current Issues
Mixed Implementation Approaches
The codebase uses two different methods to connect to Composio:
- Proper SDK approach:
mapbox_mcp/composio-mapbox.ts uses authenticateToolkit() and initializeComposioMapbox() with the Composio SDK 2
- Manual MCP approach:
lib/agents/tools/geospatial.tsx manually constructs URLs and uses MCP client transport 3
Security and Maintainability Concerns
The manual URL construction in geospatial.tsx bypasses the proper Composio SDK authentication flow, which is acknowledged as needing migration 1 .
Recommended Improvements
1. Migrate geospatial.tsx to Use Composio SDK
Replace the getConnectedMcpClient() function in lib/agents/tools/geospatial.tsx with calls to the proper Composio SDK methods:
// Replace getConnectedMcpClient() with:
import { initializeComposioMapbox, getComposioClient } from '@/mapbox_mcp/composio-mapbox';
async function getComposioConnection() {
const { connectionId, composio } = await initializeComposioMapbox();
return { connectionId, composio };
}
2. Update Tool Execution Logic
Replace the MCP client tool calls with Composio SDK executeAction calls:
// Current approach (lines 361-377):
const result = await client.callTool(toolName, args);
// New approach:
const result = await composio.executeAction({
action: toolName, // e.g., 'mapbox_geocode_location'
params: args,
connectedAccountId: connectionId,
});
3. Standardize Environment Variable Usage
Ensure consistent environment variable validation by using the validateEnvironmentVariables() function from composio-mapbox.ts 4 instead of the manual checks in geospatial.tsx 5 .
4. Remove Redundant Configuration
The mapbox_mcp_config.json file is loaded but not fully utilized in the current implementation 6 . After migrating to the SDK, this file can be removed or simplified since the SDK handles configuration internally.
5. Improve Error Handling
Implement consistent error handling using the patterns from composio-mapbox.ts 7 and the hooks file 8 .
Implementation Priority
- High Priority: Migrate
getConnectedMcpClient() to use initializeComposioMapbox()
- High Priority: Replace MCP client calls with Composio SDK
executeAction()
- Medium Priority: Standardize environment variable validation
- Low Priority: Clean up redundant configuration files
Notes
The migration guide in COMPOSIO_MIGRATION.md 9 provides additional context for the migration from Smithery to Composio, but the current issue is about completing the migration within the Composio implementation itself. The security warnings in mapbox_mcp/README.md 10 highlight the importance of proper server-side authentication, which the SDK approach provides.
Wiki pages you might want to explore:
Citations
File: lib/agents/tools/geospatial.tsx (L40-53)
const composioApiKey = process.env.COMPOSIO_API_KEY;
const mapboxAccessToken = process.env.MAPBOX_ACCESS_TOKEN;
const composioUserId = process.env.COMPOSIO_USER_ID;
console.log('[GeospatialTool] Environment check:', {
composioApiKey: composioApiKey ? `${composioApiKey.substring(0, 8)}...` : 'MISSING',
mapboxAccessToken: mapboxAccessToken ? `${mapboxAccessToken.substring(0, 8)}...` : 'MISSING',
composioUserId: composioUserId ? `${composioUserId.substring(0, 8)}...` : 'MISSING',
});
if (!composioApiKey || !mapboxAccessToken || !composioUserId || !composioApiKey.trim() || !mapboxAccessToken.trim() || !composioUserId.trim()) {
console.error('[GeospatialTool] Missing or empty required environment variables');
return null;
}
File: lib/agents/tools/geospatial.tsx (L55-71)
// Load config from file or fallback
let config;
try {
// Use static import for config
let mapboxMcpConfig;
try {
mapboxMcpConfig = require('../../../mapbox_mcp_config.json');
config = { ...mapboxMcpConfig, mapboxAccessToken };
console.log('[GeospatialTool] Config loaded successfully');
} catch (configError: any) {
throw configError;
}
} catch (configError: any) {
console.error('[GeospatialTool] Failed to load mapbox config:', configError.message);
config = { mapboxAccessToken, version: '1.0.0', name: 'mapbox-mcp-server' };
console.log('[GeospatialTool] Using fallback config');
}
File: lib/agents/tools/geospatial.tsx (L73-103)
// Build Composio MCP server URL
// Note: This should be migrated to use Composio SDK directly instead of MCP client
// For now, constructing URL directly without Smithery SDK
let serverUrlToUse: URL;
try {
// Construct URL with Composio credentials
const baseUrl = 'https://api.composio.dev/v1/mcp/mapbox';
serverUrlToUse = new URL(baseUrl);
serverUrlToUse.searchParams.set('api_key', composioApiKey);
serverUrlToUse.searchParams.set('user_id', composioUserId);
const urlDisplay = serverUrlToUse.toString().split('?')[0];
console.log('[GeospatialTool] Composio MCP Server URL created:', urlDisplay);
if (!serverUrlToUse.href || !serverUrlToUse.href.startsWith('https://')) {
throw new Error('Invalid server URL generated');
}
} catch (urlError: any) {
console.error('[GeospatialTool] Error creating Composio URL:', urlError.message);
return null;
}
// Create transport
let transport;
try {
transport = new StreamableHTTPClientTransport(serverUrlToUse);
console.log('[GeospatialTool] Transport created successfully');
} catch (transportError: any) {
console.error('[GeospatialTool] Failed to create transport:', transportError.message);
return null;
}
File: mapbox_mcp/composio-mapbox.ts (L8-48)
function validateEnvironmentVariables(): {
authConfigId: string;
userId: string;
mapboxToken: string;
apiKey: string;
} {
const authConfigId = process.env.COMPOSIO_MAPBOX_AUTH_CONFIG_ID;
const userId = process.env.COMPOSIO_USER_ID;
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
const apiKey = process.env.COMPOSIO_API_KEY;
if (!authConfigId) {
throw new Error(
'COMPOSIO_MAPBOX_AUTH_CONFIG_ID environment variable is required. ' +
'Please set it in your .env.local file.'
);
}
if (!userId) {
throw new Error(
'COMPOSIO_USER_ID environment variable is required. ' +
'Please set it in your .env.local file.'
);
}
if (!mapboxToken) {
throw new Error(
'MAPBOX_ACCESS_TOKEN environment variable is required. ' +
'Please set it in your .env.local file.'
);
}
if (!apiKey) {
throw new Error(
'COMPOSIO_API_KEY environment variable is required. ' +
'Please set it in your .env.local file.'
);
}
return { authConfigId, userId, mapboxToken, apiKey };
}
File: mapbox_mcp/composio-mapbox.ts (L59-115)
export async function authenticateToolkit(
userId: string,
authConfigId: string,
mapboxApiKey: string,
composioApiKey: string
): Promise<string> {
if (!userId || !authConfigId || !mapboxApiKey || !composioApiKey) {
throw new Error(
'userId, authConfigId, mapboxApiKey, and composioApiKey are required for authentication'
);
}
// Initialize Composio with API key
const composio = new Composio({ apiKey: composioApiKey });
const connectionRequest = await composio.connectedAccounts.initiate(
userId,
authConfigId,
{
config: AuthScheme.APIKey({
api_key: mapboxApiKey
})
}
);
// API Key authentication is immediate - no redirect needed
console.log(`Successfully connected Mapbox for user ${userId}`);
console.log(`Connection status: ${connectionRequest.status}`);
return connectionRequest.id;
}
/**
* Initialize Composio connection for Mapbox
* This should only be called server-side to avoid exposing API keys
* @throws Error if environment variables are missing or connection fails
*/
export async function initializeComposioMapbox() {
const { authConfigId, userId, mapboxToken, apiKey } = validateEnvironmentVariables();
try {
// Authenticate the toolkit
const connectionId = await authenticateToolkit(userId, authConfigId, mapboxToken, apiKey);
// Initialize Composio client with API key for subsequent operations
const composio = new Composio({ apiKey });
// Verify the connection
const connectedAccount = await composio.connectedAccounts.get(connectionId);
console.log("Connected account:", connectedAccount);
return { connectionId, connectedAccount, composio };
} catch (error) {
console.error("Failed to initialize Composio Mapbox connection:", error);
throw error;
}
}
File: mapbox_mcp/hooks.ts (L96-100)
} catch (err) {
const errorMessage = `Failed to connect to Composio Mapbox: ${err}`;
setError(errorMessage);
console.error('❌ Composio connection error:', err);
throw new Error(errorMessage);
File: COMPOSIO_MIGRATION.md (L1-253)
# Migration Guide: Smithery to Composio
This document outlines the migration from Smithery to Composio for the Mapbox integration in QCX.
## Overview
The QCX project has migrated from using Smithery's MCP server hosting to Composio's integration platform for Mapbox functionality. This change provides better scalability, more robust authentication, and improved tool management.
## What Changed
### 1. Dependencies
**Removed:**
- `@smithery/cli` (^1.2.5)
- `@smithery/sdk` (^1.0.4)
- `smithery` (^0.5.2)
**Added:**
- `@composio/core` (^0.5.0)
### 2. Environment Variables
**Old (Smithery):**
```bash
SMITHERY_PROFILE_ID="your_smithery_profile_id_here"
SMITHERY_API_KEY="your_smithery_api_key_here"
NEXT_PUBLIC_SMITHERY_PROFILE_ID="your_smithery_profile_id_here"
NEXT_PUBLIC_SMITHERY_API_KEY="your_smithery_api_key_here"
New (Composio):
COMPOSIO_MAPBOX_AUTH_CONFIG_ID="ac_YOUR_MAPBOX_CONFIG_ID"
COMPOSIO_USER_ID="user@example.com"
MAPBOX_ACCESS_TOKEN="your_mapbox_api_key"
NEXT_PUBLIC_COMPOSIO_MAPBOX_AUTH_CONFIG_ID="ac_YOUR_MAPBOX_CONFIG_ID"
NEXT_PUBLIC_COMPOSIO_USER_ID="user@example.com"
3. Configuration Files
mapbox_mcp_config.json
Old:
{
"mcpServers": {
"mapbox-mcp-server": {
"command": "npx",
"args": [
"-y",
"@smithery/cli@latest",
"run",
"@ngoiyaeric/mapbox-mcp-server",
"--key",
"705b0222-a657-4cd2-b180-80c406cf6179",
"--profile",
"smooth-lemur-vfUbUE"
]
}
}
}
New:
{
"composio": {
"mapbox": {
"authConfigId": "ac_YOUR_MAPBOX_CONFIG_ID",
"userId": "user@example.com",
"description": "Composio configuration for Mapbox integration"
}
}
}
4. Code Changes
mapbox_mcp/hooks.ts
Old Connection Method:
const mcp = useMcp({
url: `https://server.smithery.ai/@Waldzell-Agentics/mcp-server/mcp?profile=${process.env.NEXT_PUBLIC_SMITHERY_PROFILE_ID}&api_key=${process.env.NEXT_PUBLIC_SMITHERY_API_KEY}`,
debug: process.env.NODE_ENV === 'development',
autoReconnect: true,
autoRetry: 5000,
});
New Connection Method:
const composioClient = getComposioClient();
const { connectionId, connectedAccount } = await initializeComposioMapbox();
Tool Execution
Old:
const result = await mcp.callTool('geocode_location', {
query: address,
includeMapPreview: true,
});
New:
const result = await composioClient.executeAction({
action: 'mapbox_geocode_location',
params: {
query: address,
includeMapPreview: true,
},
connectedAccountId: connectionId,
});
Migration Steps
Step 1: Install Composio
bun install @composio/core
Step 2: Remove Smithery Dependencies
bun remove @smithery/cli @smithery/sdk smithery
Step 3: Set Up Composio Account
- Sign up at https://composio.dev
- Create a new auth config for Mapbox
- Select "API Key" as the authentication method
- Note your auth config ID (starts with
ac_)
Step 4: Update Environment Variables
- Copy
.env.local.example to .env.local (if not already done)
- Replace Smithery variables with Composio variables:
COMPOSIO_MAPBOX_AUTH_CONFIG_ID="ac_YOUR_ACTUAL_CONFIG_ID"
COMPOSIO_USER_ID="your_email@example.com"
MAPBOX_ACCESS_TOKEN="your_mapbox_token"
Step 5: Update Code References
The following files have been updated automatically:
mapbox_mcp/composio-mapbox.ts (new file)
mapbox_mcp/hooks.ts (updated)
mapbox_mcp/index.ts (updated)
mapbox_mcp_config.json (updated)
package.json (updated)
.env.local.example (updated)
Step 6: Test the Integration
# Test the connection
bun run mapbox_mcp/index.ts
# Run the development server
bun run dev
API Compatibility
The useMCPMapClient hook maintains the same interface, so existing components using it should continue to work without changes:
const {
isConnected,
isLoading,
error,
connect,
disconnect,
processLocationQuery,
geocodeLocation,
calculateDistance,
searchNearbyPlaces,
} = useMCPMapClient();
Troubleshooting
Issue: "Composio client not connected"
Solution: Ensure you've called connect() before using any tool functions:
useEffect(() => {
connect();
}, [connect]);
Issue: "Invalid auth config ID"
Solution: Verify your COMPOSIO_MAPBOX_AUTH_CONFIG_ID starts with ac_ and is copied correctly from the Composio dashboard.
Issue: "Mapbox API key invalid"
Solution: Check that your MAPBOX_ACCESS_TOKEN is valid and has the necessary scopes enabled in your Mapbox account.
Issue: Tool execution fails
Solution: Verify the action names match Composio's Mapbox integration. Common actions:
mapbox_geocode_location
mapbox_calculate_distance
mapbox_search_nearby_places
mapbox_generate_map_link
Benefits of Composio
- Better Authentication Management: Centralized auth config management
- Improved Security: API keys stored securely in Composio
- Scalability: Better handling of multiple integrations
- Monitoring: Built-in logging and monitoring in Composio dashboard
- Flexibility: Easier to add new tools and integrations
Resources
Support
If you encounter issues during migration:
- Check the Composio dashboard for connection status
- Review the logs in your development console
- Consult the mapbox_mcp/README.md file
- Open an issue in the QCX repository
Rollback
If you need to rollback to Smithery:
# Reinstall Smithery packages
bun install @smithery/cli@^1.2.5 @smithery/sdk@^1.0.4 smithery@^0.5.2
# Restore old environment variables in .env.local
# Restore old code from git history
git checkout HEAD~1 -- mapbox_mcp/
However, we recommend staying with Composio for the improved features and maintainability.
**File:** mapbox_mcp/README.md (L9-16)
```markdown
## ⚠️ Security Warning
**IMPORTANT**: The Composio integration requires server-side environment variables (`MAPBOX_ACCESS_TOKEN`) that should **NEVER** be exposed to the client.
- The `useMCPMapClient` hook should **NOT** be used directly in client components
- Instead, create server-side API routes that handle Composio authentication and tool execution
- Only expose necessary data to the client through your API routes
Improve Composio Integration
The current Composio integration has a hybrid implementation where
lib/agents/tools/geospatial.tsxuses a direct MCP client approach instead of the proper Composio SDK methods defined inmapbox_mcp/composio-mapbox.ts. 1Current Issues
Mixed Implementation Approaches
The codebase uses two different methods to connect to Composio:
mapbox_mcp/composio-mapbox.tsusesauthenticateToolkit()andinitializeComposioMapbox()with the Composio SDK 2lib/agents/tools/geospatial.tsxmanually constructs URLs and uses MCP client transport 3Security and Maintainability Concerns
The manual URL construction in
geospatial.tsxbypasses the proper Composio SDK authentication flow, which is acknowledged as needing migration 1 .Recommended Improvements
1. Migrate geospatial.tsx to Use Composio SDK
Replace the
getConnectedMcpClient()function inlib/agents/tools/geospatial.tsxwith calls to the proper Composio SDK methods:2. Update Tool Execution Logic
Replace the MCP client tool calls with Composio SDK
executeActioncalls:3. Standardize Environment Variable Usage
Ensure consistent environment variable validation by using the
validateEnvironmentVariables()function fromcomposio-mapbox.ts4 instead of the manual checks ingeospatial.tsx5 .4. Remove Redundant Configuration
The
mapbox_mcp_config.jsonfile is loaded but not fully utilized in the current implementation 6 . After migrating to the SDK, this file can be removed or simplified since the SDK handles configuration internally.5. Improve Error Handling
Implement consistent error handling using the patterns from
composio-mapbox.ts7 and the hooks file 8 .Implementation Priority
getConnectedMcpClient()to useinitializeComposioMapbox()executeAction()Notes
The migration guide in
COMPOSIO_MIGRATION.md9 provides additional context for the migration from Smithery to Composio, but the current issue is about completing the migration within the Composio implementation itself. The security warnings inmapbox_mcp/README.md10 highlight the importance of proper server-side authentication, which the SDK approach provides.Wiki pages you might want to explore:
Citations
File: lib/agents/tools/geospatial.tsx (L40-53)
File: lib/agents/tools/geospatial.tsx (L55-71)
File: lib/agents/tools/geospatial.tsx (L73-103)
File: mapbox_mcp/composio-mapbox.ts (L8-48)
File: mapbox_mcp/composio-mapbox.ts (L59-115)
File: mapbox_mcp/hooks.ts (L96-100)
File: COMPOSIO_MIGRATION.md (L1-253)
New (Composio):
3. Configuration Files
mapbox_mcp_config.json
Old:
{ "mcpServers": { "mapbox-mcp-server": { "command": "npx", "args": [ "-y", "@smithery/cli@latest", "run", "@ngoiyaeric/mapbox-mcp-server", "--key", "705b0222-a657-4cd2-b180-80c406cf6179", "--profile", "smooth-lemur-vfUbUE" ] } } }New:
{ "composio": { "mapbox": { "authConfigId": "ac_YOUR_MAPBOX_CONFIG_ID", "userId": "user@example.com", "description": "Composio configuration for Mapbox integration" } } }4. Code Changes
mapbox_mcp/hooks.ts
Old Connection Method:
New Connection Method:
Tool Execution
Old:
New:
Migration Steps
Step 1: Install Composio
Step 2: Remove Smithery Dependencies
Step 3: Set Up Composio Account
ac_)Step 4: Update Environment Variables
.env.local.exampleto.env.local(if not already done)Step 5: Update Code References
The following files have been updated automatically:
mapbox_mcp/composio-mapbox.ts(new file)mapbox_mcp/hooks.ts(updated)mapbox_mcp/index.ts(updated)mapbox_mcp_config.json(updated)package.json(updated).env.local.example(updated)Step 6: Test the Integration
API Compatibility
The
useMCPMapClienthook maintains the same interface, so existing components using it should continue to work without changes:Troubleshooting
Issue: "Composio client not connected"
Solution: Ensure you've called
connect()before using any tool functions:Issue: "Invalid auth config ID"
Solution: Verify your
COMPOSIO_MAPBOX_AUTH_CONFIG_IDstarts withac_and is copied correctly from the Composio dashboard.Issue: "Mapbox API key invalid"
Solution: Check that your
MAPBOX_ACCESS_TOKENis valid and has the necessary scopes enabled in your Mapbox account.Issue: Tool execution fails
Solution: Verify the action names match Composio's Mapbox integration. Common actions:
mapbox_geocode_locationmapbox_calculate_distancemapbox_search_nearby_placesmapbox_generate_map_linkBenefits of Composio
Resources
Support
If you encounter issues during migration:
Rollback
If you need to rollback to Smithery:
However, we recommend staying with Composio for the improved features and maintainability.