Skip to main content
Glama

consult_gemini_with_files

Query Gemini AI with file attachments to integrate file content into prompts. Specify a directory and file paths for context, and receive AI-driven responses.

Instructions

Send a query to Gemini CLI with file attachments. Files are read and concatenated into the prompt. Simple and direct. Args: query: The question or prompt to send to Gemini directory: Working directory (required) files: List of file paths to attach (relative to directory) model: Optional model name (flash, pro, etc.) Returns: Gemini's response with file context

Input Schema

NameRequiredDescriptionDefault
directoryYes
filesNo
modelNo
queryYes

Input Schema (JSON Schema)

{ "properties": { "directory": { "title": "Directory", "type": "string" }, "files": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Files" }, "model": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Model" }, "query": { "title": "Query", "type": "string" } }, "required": [ "query", "directory" ], "title": "consult_gemini_with_filesArguments", "type": "object" }

Implementation Reference

  • The primary handler function for the 'consult_gemini_with_files' tool, decorated with @mcp.tool() for registration. It validates the 'files' parameter and delegates execution to the helper function execute_gemini_with_files.
    @mcp.tool() def consult_gemini_with_files( query: str, directory: str, files: list[str] | None = None, model: str | None = None, timeout_seconds: int | None = None, mode: str = "inline", ) -> str: """Send a query to the Gemini CLI with file context. Args: query: Prompt text forwarded to the CLI. directory: Working directory used for resolving relative file paths. files: Relative or absolute file paths to include alongside the prompt. model: Optional model alias (``flash``, ``pro``) or full Gemini model id. timeout_seconds: Optional per-call timeout override in seconds. mode: ``"inline"`` streams truncated snippets; ``"at_command"`` emits ``@path`` directives so Gemini CLI resolves files itself. Returns: Gemini's response or an explanatory error string with any warnings. """ if not files: return "Error: files parameter is required for consult_gemini_with_files" return execute_gemini_with_files(query, directory, files, model, timeout_seconds, mode)
  • The @mcp.tool() decorator registers the consult_gemini_with_files function as an MCP tool.
    @mcp.tool()
  • Core helper function that implements the logic for executing the Gemini CLI with file attachments, supporting 'inline' (content snippets) and 'at_command' (@path directives) modes. Prepares input payload and runs subprocess.
    def execute_gemini_with_files( query: str, directory: str = ".", files: Optional[List[str]] = None, model: Optional[str] = None, timeout_seconds: Optional[int] = None, mode: str = "inline", ) -> str: """ Execute gemini CLI command with file attachments. Args: query: The prompt to send to Gemini directory: Working directory for the command files: List of file paths to attach (relative to directory) model: Optional model name (flash, pro, etc.) Returns: CLI output or error message """ # Check if gemini CLI is available if not shutil.which("gemini"): return "Error: Gemini CLI not found. Install with: npm install -g @google/gemini-cli" # Validate directory if not os.path.isdir(directory): return f"Error: Directory does not exist: {directory}" # Validate files parameter if not files: return "Error: No files provided for file attachment mode" # Build command - use stdin for input to avoid hanging selected_model = _normalize_model_name(model) cmd = ["gemini", "-m", selected_model] mode_normalized = mode.lower() warnings: List[str] if mode_normalized not in {"inline", "at_command"}: return f"Error: Unsupported files mode '{mode}'. Use 'inline' or 'at_command'." if mode_normalized == "inline": inline_payload, warnings = _prepare_inline_payload(directory, files) stdin_pieces = [piece for piece in [inline_payload, query] if piece] stdin_content = "\n\n".join(stdin_pieces) else: at_prompt, warnings = _prepare_at_command_prompt(directory, files) stdin_pieces = [piece for piece in [at_prompt, query] if piece] stdin_content = "\n\n".join(stdin_pieces) # Execute CLI command - simple timeout, no retries timeout = _coerce_timeout(timeout_seconds) try: result = subprocess.run( cmd, cwd=directory, capture_output=True, text=True, timeout=timeout, input=stdin_content ) if result.returncode == 0: output = result.stdout.strip() if result.stdout.strip() else "No output from Gemini CLI" else: output = f"Gemini CLI Error: {result.stderr.strip()}" if warnings: warning_block = "Warnings:\n" + "\n".join(f"- {w}" for w in warnings) return f"{warning_block}\n\n{output}" return output except subprocess.TimeoutExpired: return f"Error: Gemini CLI command timed out after {timeout} seconds" except Exception as e: return f"Error executing Gemini CLI: {str(e)}"
  • Helper for preparing inline file content payload: reads and truncates files, formats into delimited blocks, tracks byte limits and warnings.
    def _prepare_inline_payload(directory: str, files: List[str]) -> Tuple[str, List[str]]: """Return stdin payload for inline mode and any warnings.""" warnings: List[str] = [] file_blocks: List[str] = [] total_bytes = 0 processed = 0 if MAX_INLINE_FILE_COUNT <= 0: warnings.append("Inline attachments disabled via MAX_INLINE_FILE_COUNT<=0") return "", warnings for original_path in files: abs_path, rel_path = _resolve_path(directory, original_path) display_name = rel_path or os.path.basename(abs_path) if not os.path.exists(abs_path): warnings.append(f"Skipped missing file: {display_name}") continue if processed >= MAX_INLINE_FILE_COUNT: warnings.append( f"Inline file limit reached ({MAX_INLINE_FILE_COUNT}); skipped remaining attachments", ) break try: content, truncated, bytes_used = _read_file_for_inline(abs_path) except Exception as exc: # IOError or decoding issues warnings.append(f"Error reading {display_name}: {exc}") continue if total_bytes + bytes_used > MAX_INLINE_TOTAL_BYTES: warnings.append( f"Inline payload exceeded {MAX_INLINE_TOTAL_BYTES} bytes; skipped {display_name} and remaining attachments", ) break block_header = f"=== {display_name} ===" if truncated: block_header += "\n[gemini-bridge] Content truncated for inline transfer" file_blocks.append(f"{block_header}\n{content}") if truncated: warnings.append( f"Truncated {display_name}; only the first {INLINE_CHUNK_HEAD_BYTES}B and last {INLINE_CHUNK_TAIL_BYTES}B were sent", ) total_bytes += bytes_used processed += 1 payload = "\n\n".join(file_blocks) return payload, warnings
  • Helper for 'at_command' mode: generates @relpath prompt lines for Gemini CLI to resolve files itself.
    def _prepare_at_command_prompt(directory: str, files: List[str]) -> Tuple[str, List[str]]: """Return prompt lines for @-command usage and warnings.""" warnings: List[str] = [] prompt_lines: List[str] = [] for original_path in files: abs_path, rel_path = _resolve_path(directory, original_path) if not os.path.exists(abs_path): warnings.append(f"Skipped missing file: {original_path}") continue if rel_path is None: warnings.append( f"Skipped file outside working directory: {original_path}", ) continue prompt_lines.append(f"@{rel_path}") if not prompt_lines: warnings.append("No readable files resolved for @ command; prompt unchanged") prompt = "\n".join(prompt_lines) return prompt, warnings

Other Tools

Related 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/eLyiN/gemini-bridge'

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