composio
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 19
- Forks
- 7
- Avg merge
- 59m
- Merged PRs (30d)
- 16
Description
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.tsusesauthenticateToolkit()andinitializeComposioMapbox()with the Composio SDK 2 - Manual MCP approach:
lib/agents/tools/geospatial.tsxmanually 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 useinitializeComposioMapbox() - 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.exampleto.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_locationmapbox_calculate_distancemapbox_search_nearby_placesmapbox_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
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read lib/agents/tools/geospatial.tsx alongside mapbox_mcp/composio-mapbox.ts, starting at getConnectedMcpClient() and initializeComposioMapbox(). Use mapbox_mcp/hooks.ts and COMPOSIO_MIGRATION.md to compare connection and error-handling patterns. Done means geospatial uses the Composio SDK, shared validation, and consistent error handling, with redundant configuration addressed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, security
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100