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';
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but is minimal. It states the tool sets up a remote repository but doesn't disclose behavioral traits like whether it requires GitHub authentication, modifies local git config, handles errors, or what happens on success/failure. For a setup tool with zero annotation coverage, this leaves significant gaps in understanding its behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose ('Set up a GitHub remote repository') and adds necessary context ('for an existing local TOYBOX', 'one-time setup'). Every word earns its place with no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a setup tool with 3 parameters, no annotations, and no output schema, the description is incomplete. It lacks details on authentication needs, what 'set up' entails (e.g., creates repo, adds remote, configures branches), error handling, or return values. For this complexity, it should provide more behavioral context to compensate for missing structured data.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents parameters (repoName, isPrivate, enablePages). The description adds no parameter-specific information beyond implying the tool is for TOYBOX setup. Baseline 3 is appropriate as the schema does the heavy lifting, but the description doesn't enhance parameter understanding (e.g., explaining TOYBOX context for repoName).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Set up') and target resource ('GitHub remote repository'), specifying it's for an existing local TOYBOX and a one-time setup. It distinguishes from sibling tools like 'initialize_toybox' (which likely creates local) and 'publish_artifact' (which might push content). However, it doesn't explicitly differentiate from all siblings (e.g., 'update_config' could be related).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context ('for an existing local TOYBOX', 'one-time setup'), suggesting this tool is for initial remote configuration rather than ongoing operations. However, it lacks explicit guidance on when to use alternatives (e.g., vs. 'initialize_toybox' for local setup) or prerequisites (e.g., GitHub authentication, existing local repo).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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