Skip to main content
Glama

setup_remote

Configure a GitHub remote repository for local TOYBOX projects to enable publishing to GitHub Pages with one-time setup.

Instructions

Set up a GitHub remote repository for an existing local TOYBOX (one-time setup)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
repoNameYesName for the GitHub repository
isPrivateNoCreate repository as private (default: false)
enablePagesNoEnable GitHub Pages for the repository (default: true)

Implementation Reference

  • The core handler function implementing the setup_remote tool logic: checks GitHub auth, validates repo existence, creates GitHub repo, adds remote to local git, pushes code, enables GitHub Pages, and updates config.
    export async function setupRemote(params: SetupRemoteParams): Promise<SetupRemoteResult> {
      const { repoName, isPrivate = false, enablePages = true } = params;
      const githubService = new GitHubService();
      const configService = new ConfigService();
    
      try {
        // Step 1: Check GitHub CLI authentication
        log.info('Checking GitHub CLI authentication');
        const authStatus = await githubService.checkAuthStatus();
        
        if (!authStatus.authenticated) {
          return {
            success: false,
            error: 'Not authenticated with GitHub CLI. Please run: gh auth login',
          };
        }
    
        log.info('Authenticated as user', { user: authStatus.user });
        const currentUser = authStatus.user || 'unknown';
    
        // Step 2: Check if repository already exists
        const repoExists = await githubService.repositoryExists(repoName);
        if (repoExists) {
          return {
            success: false,
            error: `Repository '${repoName}' already exists. Choose a different name or use the existing repository.`,
          };
        }
    
        // Step 3: Get active repository path
        const activeRepo = await configService.getActiveRepository();
        if (!activeRepo) {
          return {
            success: false,
            error: 'No active TOYBOX repository found. Please initialize a TOYBOX first.',
          };
        }
    
        const gitService = new GitService(activeRepo.localPath);
    
        // Step 4: Ensure local repository exists and is initialized
        if (!await gitService.repositoryExists()) {
          return {
            success: false,
            error: 'Local repository not found. Please ensure you have an initialized TOYBOX.',
          };
        }
    
        // Step 5: Create GitHub repository
        log.info('Creating GitHub repository', { repoName });
        const repoUrl = await githubService.createEmptyRepository(repoName, isPrivate);
        
        // Step 6: Get clone URL for the repository
        const cloneUrl = await githubService.getCloneUrl(repoName, true); // Use SSH by default
    
        // Step 7: Add remote to local repository
        log.info('Adding remote to local repository');
        await gitService.addRemote('origin', cloneUrl);
    
        // Step 8: Push existing commits to remote
        log.info('Pushing local commits to remote');
        await gitService.push('origin', 'main', true); // Push with --set-upstream
    
        // Step 9: Enable GitHub Pages if requested
        let pagesUrl = '';
        if (enablePages) {
          log.info('Enabling GitHub Pages');
          try {
            pagesUrl = await githubService.enableGitHubPages(repoName);
          } catch (error) {
            // Pages might need time to activate
            pagesUrl = `https://${currentUser}.github.io/${repoName}/`;
            log.info('GitHub Pages setup initiated, may take a few minutes to activate');
          }
    
          // Step 10: Trigger initial deployment
          log.info('Triggering initial deployment');
          try {
            await githubService.triggerWorkflow(repoName);
          } catch (error) {
            log.warn('Could not trigger workflow, but Pages should auto-deploy');
          }
        }
    
        // Step 11: Update repository configuration
        await configService.updateRepository(activeRepo.name, {
          remoteUrl: repoUrl,
          publishedUrl: pagesUrl,
          lastUsedAt: new Date().toISOString(),
        });
    
        return {
          success: true,
          repositoryUrl: repoUrl,
          cloneUrl,
          pagesUrl: pagesUrl || undefined,
          message: `✅ GitHub remote repository setup successfully!\n\n` +
            `Repository: ${repoUrl}\n` +
            `Local path: ${activeRepo.localPath}\n` +
            `Clone URL: ${cloneUrl}\n` +
            (pagesUrl ? `Published URL: ${pagesUrl}\n\n` : '\n') +
            `Your local TOYBOX is now connected to GitHub! You can continue publishing artifacts.`,
        };
    
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        
        return {
          success: false,
          error: `Failed to setup GitHub remote: ${errorMessage}`,
        };
      }
    }
  • Zod input schema (SetupRemoteParamsSchema), TypeScript input type (SetupRemoteParams), and output interface (SetupRemoteResult) for the setup_remote tool.
    export const SetupRemoteParamsSchema = z.object({
      repoName: z.string(),
      isPrivate: z.boolean().default(false),
      enablePages: z.boolean().default(true),
    });
    
    export type SetupRemoteParams = z.infer<typeof SetupRemoteParamsSchema>;
    
    // Internal types
    export interface GitHubAuthStatus {
      authenticated: boolean;
      user?: string;
      scopes?: string[];
    }
    
    export interface ToyboxRepository {
      name: string;
      localPath: string;
      remoteUrl: string;
      publishedUrl: string;
    }
    
    export interface PublishResult {
      success: boolean;
      artifactId: string;
      artifactUrl: string;
      message?: string;
      error?: string;
    }
    
    export interface InitResult {
      success: boolean;
      repository: ToyboxRepository;
      message?: string;
      error?: string;
    }
    
    export interface SetupRemoteResult {
      success: boolean;
      repositoryUrl?: string;
      cloneUrl?: string;
      pagesUrl?: string;
      message?: string;
      error?: string;
    }
  • src/index.ts:187-210 (registration)
    MCP tool registration in listTools response: defines the 'setup_remote' tool name, description, and input schema.
    {
      name: 'setup_remote',
      description: 'Set up a GitHub remote repository for an existing local TOYBOX (one-time setup)',
      inputSchema: {
        type: 'object',
        properties: {
          repoName: {
            type: 'string',
            description: 'Name for the GitHub repository',
          },
          isPrivate: {
            type: 'boolean',
            description: 'Create repository as private (default: false)',
            default: false,
          },
          enablePages: {
            type: 'boolean',
            description: 'Enable GitHub Pages for the repository (default: true)',
            default: true,
          },
        },
        required: ['repoName'],
      },
    },
  • src/index.ts:280-292 (registration)
    Dispatch handler in callToolRequest that parses input with schema, calls the setupRemote handler function, and returns result.
    case 'setup_remote': {
      const params = SetupRemoteParamsSchema.parse(args);
      log.info('Executing setup_remote', { repoName: params.repoName });
      const result = await setupRemote(params);
      log.info('setup_remote completed', { result });
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
  • src/index.ts:19-19 (registration)
    Import of the setupRemote handler function from its implementation file.
    import { setupRemote } from './handlers/setup-remote.js';

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/isnbh0/toybox-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server