import { apiRequest, isApiError, needsAuthentication, needsAuthError } from '../lib/api-client';
import { ensureAuthenticated } from '../lib/device-flow';
/**
* Tenant/Project information returned from the API
* GET /api/tenants returns tenant data with role and site info
*/
interface TenantWithRole {
id: string;
name: string;
subdomain: string;
customDomain?: string | null;
role: string;
site?: {
id: string;
status: string;
} | null;
}
/**
* List all FastMode projects the authenticated user has access to
*/
export async function listProjects(): Promise<string> {
// Check if we need to authenticate
if (await needsAuthentication()) {
const authResult = await ensureAuthenticated();
if (!authResult.authenticated) {
return authResult.message;
}
}
// Fetch user's tenants/projects
const response = await apiRequest<TenantWithRole[]>('/api/tenants');
if (isApiError(response)) {
// If auth error, try to re-authenticate
if (needsAuthError(response)) {
const authResult = await ensureAuthenticated();
if (!authResult.authenticated) {
return authResult.message;
}
// Retry the request
const retryResponse = await apiRequest<TenantWithRole[]>('/api/tenants');
if (isApiError(retryResponse)) {
return `# API Error
Failed to fetch projects: ${retryResponse.error}
**Status:** ${retryResponse.statusCode}
Please try authenticating again.
`;
}
return formatProjectList(retryResponse.data);
}
return `# API Error
Failed to fetch projects: ${response.error}
**Status:** ${response.statusCode}
Please check:
1. Your authentication is valid
2. The API URL is correct
3. You have network connectivity
`;
}
return formatProjectList(response.data);
}
/**
* Format the project list for display
*/
function formatProjectList(projects: TenantWithRole[]): string {
if (!projects || projects.length === 0) {
return `# No Projects Found
You don't have access to any FastMode projects.
**To create a project:**
1. Go to app.fastmode.ai
2. Click "Create New Project"
3. Run \`list_projects\` again to see it here
`;
}
// Format the project list
let output = `# Your FastMode Projects
Found ${projects.length} project${projects.length > 1 ? 's' : ''}:
`;
projects.forEach((project, index) => {
const siteStatus = project.site?.status || 'pending';
output += `## ${index + 1}. ${project.name}
- **Project ID:** \`${project.id}\`
- **Subdomain:** ${project.subdomain}.fastmode.ai
${project.customDomain ? `- **Custom Domain:** ${project.customDomain}\n` : ''}- **Your Role:** ${project.role}
- **Site Status:** ${siteStatus}
`;
});
output += `---
## How to Use
To get the schema for a project, use:
\`\`\`
get_tenant_schema(projectId: "${projects[0]?.id || 'project-id-here'}")
\`\`\`
Or use the project name:
\`\`\`
get_tenant_schema(projectId: "${projects[0]?.name || 'Project Name'}")
\`\`\`
`;
return output;
}