Calypso Multimodal RAG MCP Server
Official# Calypso MCP Server
**Hosted multimodal RAG for Claude Desktop, Cursor, and agent workflows — in one `npx` command.**
Ask questions across PDFs, screenshots, charts, and diagrams, and upload new source material, without running a vector store, a Docker stack, or an OCR pipeline. Answers come back with citations you can check.
[](https://smithery.ai/servers/multimodal-rag/calypso-mcp-server)
[](https://archestra.ai/mcp-catalog/calypso-so__calypso-mcp-server)
[](https://www.npmjs.com/package/@calypsohq/multimodal-rag-mcp-server)
[](https://github.com/calypso-so/calypso-mcp-server)
[](https://docs.calypso.so)
[](https://www.npmjs.com/package/@calypsohq/multimodal-rag-mcp-server)
[](./LICENSE)
[](https://github.com/calypso-so/calypso-mcp-server/actions/workflows/ci.yml)
> This server is a **Calypso Context** surface — the same knowledge layer that backs Calypso on WhatsApp, exposed to MCP clients. [How the pieces fit →](https://www.calypso.so/#learn)
- **One-command setup**: `npx -y @calypsohq/multimodal-rag-mcp-server --api-key sk-your-key-here`
- **True multimodal RAG**: handles text and visuals natively through Gemini File Search
- **Upload and query**: dedicated tools for durable knowledge files and batch uploads
- **Multi-turn conversations**: context-aware answers with `/new` reset
- **Discoverable workflows**: resources and prompts for safe RAG, upload, and ingestion flows
[GitHub](https://github.com/calypso-so/calypso-mcp-server) | [Docs](https://docs.calypso.so) | [Smithery](https://smithery.ai/servers/multimodal-rag/calypso-mcp-server) | [Official MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.calypso-so/multimodal-rag-mcp-server)
Tags: `multimodal-rag`, `gemini-rag`, `hosted-rag-mcp`, `mcp-server`
Instead of wiring each agent or workflow to a one-off document search stack, use this MCP as the agent-facing entry point to one reusable answer layer: upload source material once, retrieve across text and visual content, and return answers with evidence users can verify.
## Quick Start
```bash
# One-liner with npx
npx -y @calypsohq/multimodal-rag-mcp-server --api-key "sk-your-key-here"
```
Or with environment variables:
```bash
CALYPSO_API_KEY="sk-..." npx -y @calypsohq/multimodal-rag-mcp-server
```
Then add the same command to Claude Desktop, Cursor, or Smithery using the configuration examples below.
## Why Choose Calypso
No local vector store, no Docker Compose, and no separate OCR or vision pipeline before an agent can ask a grounded question. Point the server at a Calypso API key and it discovers your team's agents and knowledge buckets on connect.
- **Zero infrastructure**: one `npx` command; nothing to host or operate.
- **Multimodal without a second pipeline**: text and visuals are indexed together, so a chart or a screenshot is queryable the same way a paragraph is.
- **Answers carry evidence**: responses include source references and retrieval metadata.
- **Read and write**: query knowledge and add to it — files, batches, and websites — from the same server.
## What you get
- Production multimodal Calypso agent with multi-turn memory
- Built-in upload tools for single files and batch knowledge uploads
- Automatic discovery of your team's RAG variants and knowledge buckets
- Verifiable citations with source references and retrieval metadata
- Read-only resources and reusable prompts for safe workflows
## Why Multimodal-First RAG
Most company knowledge is not only text. The answer often lives across a setup screenshot, a PDF table, a product diagram, a help-center page, or a chart inside a report. Calypso packages that full knowledge surface into a single retrieval layer so agents can ask grounded questions without guessing from generic model memory.
- **Search the formats users actually rely on**: documentation, PDFs, screenshots, charts, diagrams, product images, support articles, manuals, policies, FAQs, and reports.
- **Ground answers before the model writes**: Gemini File Search retrieves relevant text and visual context first, then the Calypso agent answers from that source material.
- **Show the evidence trail**: responses can include source references, page-aware grounding, and retrieval metadata so people can verify before they trust.
- **Scope retrieval with metadata**: use workspace, team, customer, language, file type, status, or other metadata to keep answers relevant without duplicating knowledge bases.
- **Reuse the same knowledge layer everywhere**: connect Cursor, Claude Desktop, AI agents, n8n workflows, product UI, support flows, and website experiences to the same source-backed layer.
In practice, this means your agent can answer questions like:
- "Explain this setup screenshot and the attached policy PDF. What should the support rep do next?"
- "What does this onboarding PDF say about approval rules?"
- "Why is this setup screen failing?"
- "Compare the pricing chart with our plan documentation and recommend the right tier."
- "Summarize the policy that applies to this support ticket."
- "Which product plan fits this customer based on our pricing docs?"
- "Compare the diagrammed ingestion flow with the retrieval flow."
## What this MCP does
With `calypso-agent` you can:
- Ask grounded questions against the configured Calypso knowledge base
- Select any discovered team RAG variant with the optional `model` argument
- Continue a multi-turn conversation via the native `/v1/responses` conversation model
- Reset the conversation context with `/new`
- Use the same OpenAI-compatible Responses endpoint that serves `calypso-agent`
- Discover built-in resources and prompts for the supported Calypso workflows
## Requirements
- Node.js 18+
- The server uses Web Fetch API primitives (`fetch`, `Headers`, `Request`, `Response`, `FormData`, `Blob`, and `File`) for API calls and SDK compatibility. The package bootstraps missing globals at startup for MCP runtimes that expose only part of the Node 18+ Web API surface.
- A Calypso API endpoint that exposes:
- `POST /v1/responses`
- `GET /v1/rag-agent/models`
- `GET /v1/knowledge/buckets`
- `POST /v1/knowledge/files/upload-session`
- `POST /v1/knowledge/files/upload-session/{session_id}/finalize`
- `POST /v1/knowledge/files:batch/upload-session`
- `POST /v1/knowledge/files:batch/upload-session/{batch_id}/finalize`
- `GET /v1/knowledge/batches/{batch_id}`
- A Calypso API key (`sk-...`)
## Configuration
Environment variables:
- `CALYPSO_API_KEY` (required)
- `CALYPSO_API_BASE_URL` (optional, default `https://api.calypso.so/v1`)
CLI flags:
- `--api-key`
- `--api-base-url`
Configuration precedence:
1. CLI flags / Smithery-provided command arguments
2. Environment variables
3. Default base URL (`https://api.calypso.so/v1`)
## Run with npx
```bash
npx -y @calypsohq/multimodal-rag-mcp-server --api-key "sk-..."
```
## Run with environment variables
```bash
env CALYPSO_API_KEY="sk-..." CALYPSO_API_BASE_URL="https://api.calypso.so/v1" npx -y @calypsohq/multimodal-rag-mcp-server
```
## Configure in Cursor
Add a new MCP server (command type) like:
```bash
npx -y @calypsohq/multimodal-rag-mcp-server --api-key sk-... --api-base-url https://api.calypso.so/v1
```
## Configure in Claude Desktop
### 1. Open Claude Desktop MCP config
In Claude Desktop:
`Claude -> Settings -> Developer -> Edit Config`
On macOS, the file is usually:
```bash
~/Library/Application Support/Claude/claude_desktop_config.json
```
Claude Desktop uses `claude_desktop_config.json` for desktop MCP servers. Claude Code uses separate config locations such as `~/.claude.json` or project-level `.mcp.json`.
### 2. Add the Calypso MCP server
Paste this into `claude_desktop_config.json`:
```json
{
"mcpServers": {
"Calypso Multimodal RAG": {
"command": "npx",
"args": [
"-y",
"@calypsohq/multimodal-rag-mcp-server"
],
"env": {
"CALYPSO_API_KEY": "sk-your-calypso-api-key",
"CALYPSO_API_BASE_URL": "https://api.calypso.so/v1"
}
}
}
}
```
Replace:
- `sk-your-calypso-api-key`
with your real Calypso API key.
### 3. Restart Claude Desktop fully
Fully quit Claude Desktop, then reopen it.
Do not only close the window. On macOS:
```bash
Cmd + Q
```
After restart, the MCP should appear in Claude with these tools available:
- `calypso-agent`
- `calypso-list-buckets`
- `calypso-upload-file`
- `calypso-upload-files-batch`
### Optional: Save Claude Artifacts To Your Mac
Calypso provides hosted multimodal RAG tools. It does not write generated reports, summaries, CSVs, JSON files, or web-search artifacts directly to your local computer.
To let Claude Desktop save generated files locally, add the standard filesystem MCP server alongside Calypso and restrict it to a dedicated safe folder.
Create the folder first:
```bash
mkdir -p ~/Claude
```
Then add both servers to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"Calypso Multimodal RAG": {
"command": "npx",
"args": [
"-y",
"@calypsohq/multimodal-rag-mcp-server"
],
"env": {
"CALYPSO_API_KEY": "sk-your-calypso-api-key",
"CALYPSO_API_BASE_URL": "https://api.calypso.so/v1"
}
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/yourname/Claude"
]
}
}
}
```
Fully quit and reopen Claude Desktop after changing the config.
Example prompt:
```text
Use Calypso for the grounded RAG answer, then save the final report as /Users/yourname/Claude/report.md using the filesystem tool.
```
For safety, only grant filesystem access to a dedicated folder such as `~/Claude`, not your whole home directory.
| Concern | Best Owner |
| --- | --- |
| Source-backed RAG answers | Calypso MCP |
| Uploading files into Calypso | Calypso MCP |
| Writing `.md`, `.pdf`, `.json`, `.csv`, etc. to your Mac | filesystem MCP |
| Web search artifacts from Claude | Claude plus filesystem MCP prompt |
## Smithery
The server is available on [Smithery](https://smithery.ai/servers/multimodal-rag/calypso-mcp-server) and launches through the same `npx` package path used by desktop clients.
Smithery user config:
- `calypsoApiKey` (required)
- `calypsoApiBaseUrl` (optional, defaults to `https://api.calypso.so/v1`)
The Smithery launch path is equivalent to:
```bash
npx -y @calypsohq/multimodal-rag-mcp-server --api-key sk-... --api-base-url https://api.calypso.so/v1
```
Use `calypsoApiBaseUrl` only when targeting a self-hosted Calypso-compatible deployment. The cloud default does not need an override.
## Troubleshooting
- **Missing API key**: provide `--api-key` or `CALYPSO_API_KEY`
- **Wrong API host**: make sure `--api-base-url` / `CALYPSO_API_BASE_URL` ends in `/v1`
- **Self-hosted deployment**: only override the base URL if you are not using `https://api.calypso.so/v1`
- **Smithery launch mismatch**: use the packaged `npx -y @calypsohq/multimodal-rag-mcp-server` path instead of running `node dist/index.js` from a fresh clone
- **`FormData is not defined` or `Headers is not defined`**: upgrade to the latest package. The MCP server bootstraps missing Web Fetch API globals before upload tools run.
- **ENOENT for `/mnt/user-data/uploads/...`**: that path belongs to a hosted agent or attachment sandbox, not necessarily to the MCP server. Retry with `contentBase64` instead of `filePath`.
- **Local artifact saving**: Calypso answers can be used with Claude Desktop's filesystem MCP server, but Claude must be explicitly asked to save the final output to an allowed local path.
## Choosing `filePath` vs `contentBase64`
Use `filePath` for local MCP installs, including Claude Desktop and Cursor configs that launch this package with a local command such as:
```bash
npx -y @calypsohq/multimodal-rag-mcp-server
```
In that setup, the MCP server process runs on your machine and can read paths available to the same user account. Pass the local path directly; the server reads raw bytes and uploads them through the Calypso upload-session URL. You do not need to base64-encode local files.
Use `contentBase64` for hosted or remote MCP clients, including Smithery-hosted servers, browser/cloud runtimes, generated in-memory content, and agent containers. In those environments, a path on your Mac or workstation is not readable by the MCP server process.
If a path starts with `/mnt/user-data/uploads`, `/mnt/data`, `/mnt/attachments`, or another hosted sandbox prefix, do not send it as `filePath` unless this MCP server is running in that same sandbox. Use `contentBase64` or another inline byte source instead.
## Available tools
### `calypso-agent`
Direct Calypso agent access.
Notes:
- It does not auto-route to other personas or agents.
- It automatically discovers the API key's available `calypso-agent` variants at startup.
- Use the optional `model` argument to choose a named variant such as `calypso-agent:pricing`.
- Each model variant keeps its own MCP conversation chain, so switching variants does not continue the wrong thread.
- It uses `POST /v1/responses` instead of `POST /v1/chat/completions`.
- First turns create a named conversation, and follow-up turns chain with `previous_response_id`.
- Optional `fileIds` are supported for retrieval-scoped questions. New uploads should use the durable knowledge upload tools and wait for indexing before asking.
- Use `/new` as the prompt to reset the MCP conversation.
### `calypso-search`
Searches your knowledge directly and returns matching passages, without asking an agent to compose an answer.
Use it when you want evidence rather than prose — checking whether something is indexed at all, gathering sources before a decision, or letting a calling agent do its own reasoning over the passages.
Notes:
- Uses `POST /v1/search`.
- `query` is required.
- `agent` scopes the search to one agent variant's knowledge; `buckets` narrows it to specific buckets.
- `maxResults` is clamped to 1–20.
Example:
```json
{
"query": "annual plan refund window",
"buckets": ["support-handbook"],
"maxResults": 5
}
```
### `calypso-list-buckets`
Lists buckets for the team tied to the configured Calypso API key.
Notes:
- Uses `GET /v1/knowledge/buckets`.
- Does not accept `team_id`; Calypso derives team scope from the API key.
- Returns bucket ids, slugs, names, status, member counts, source counts, and bucket-store readiness.
- Defaults to active buckets only. Pass `includeArchived: true` when you need archived buckets for audits or cleanup.
- Use this before `calypso-upload-file` or `calypso-upload-files-batch` when you need to choose a destination bucket.
- `calypso://rag-agent-models` answers which buckets are bound to each RAG variant. `calypso-list-buckets` answers which buckets exist for the API key's team.
Example:
```json
{
"includeArchived": false
}
```
### `calypso-get-file`
Fetches one knowledge file's metadata and indexing status by file id.
Notes:
- Uses `GET /v1/knowledge/files/{file_id}`.
- Resolves the opaque `fileIds` from `calypso-list-buckets` into filename, mime type, size, indexing status, and per-bucket sync state.
- Pass `verify: true` to cross-check against the provider (`?verify=gemini`) — slower, but authoritative when a status looks stale.
Example:
```json
{
"fileId": "file_123",
"verify": true
}
```
### `calypso-add-website`
Ingests a website into a knowledge bucket, so page content becomes queryable alongside uploaded files.
Notes:
- Uses `POST /v1/knowledge/websites`.
- `url` is required, and so is a destination — one of `bucketIds`, `bucketSlugs`, or `bucket`.
- Optional `title`, `tagsHint`, and `preferredLanguage` help classify the source.
- Pass `idempotencyKey` to make a retry safe; it is sent as the `Idempotency-Key` header.
- Like file uploads, acceptance is not the same as being queryable — the page still has to finish indexing.
Example:
```json
{
"url": "https://example.com/pricing",
"bucket": "pricing",
"title": "Public pricing page",
"idempotencyKey": "pricing-page-2026-08"
}
```
### `calypso-create-bucket`
Creates an empty bucket for the create-then-fill workflow.
Notes:
- Uses `POST /v1/knowledge/buckets` (requires a backend with this endpoint deployed and the `knowledge:bucket:create` capability on the API key).
- The server normalizes the slug; collisions return a typed `bucket_slug_exists` error.
- `idempotencyKey` replays return the existing bucket instead of erroring.
- Uploads can still create buckets implicitly via `bucketSlugs` + `createMissingBuckets`; this tool exists for creating the destination first.
Example:
```json
{
"name": "Product docs",
"slug": "product-docs",
"idempotencyKey": "create-product-docs-1"
}
```
### `calypso-create-agent`
Creates a Calypso agent variant bound to one or more buckets.
Notes:
- Uses `POST /v1/rag-agent/agents` (requires a backend with this endpoint deployed and the `rag:agent:create` capability on the API key).
- The success payload leads with `model` — pass it straight to `calypso-agent`.
- Bucket bindings are validated server-side: unknown or archived buckets return `bucket_not_found`; agent id collisions return `agent_id_exists`; the plan's agent cap returns `agent_limit_reached`.
- Creating an agent refreshes the model catalog and emits MCP `tools/list_changed` + `resources/list_changed` notifications, so the new variant is usable without reconnecting.
Example:
```json
{
"agentId": "support",
"name": "Support agent",
"bucketSlugs": ["product-docs"],
"idempotencyKey": "create-support-agent-1"
}
```
### `calypso-upload-file`
Uploads a file into the durable bucket-backed knowledge store and indexing pipeline.
Notes:
- Uses `POST /v1/knowledge/files/upload-session`, uploads bytes directly to storage, then finalizes with `POST /v1/knowledge/files/upload-session/{session_id}/finalize`.
- Uploads use JSON session requests plus signed binary `PUT`s, not multipart form uploads.
- Returns file and task metadata, not a chat attachment `file_id`.
- Requires one bucket destination via `bucketIds`, `bucketSlugs`, or `bucket`.
- Use `filePath` for local Claude Desktop/Cursor MCP installs where the server can read the path. Use `contentBase64` for hosted or remote MCP clients that cannot read local paths.
- If an agent sees a path like `/mnt/user-data/uploads/file.pdf`, it should not send that as `filePath`; it should send the file bytes as `contentBase64`.
- Supports optional `title`, `tags`, `metadata`, and `idempotencyKey`.
- Route uploads into existing buckets with `bucketIds` or `bucketSlugs`, or use `bucket` as a single-slug shortcut.
- Pass `createMissingBuckets: true` with bucket slugs when you want Calypso to create missing destinations during upload.
- Can optionally wait until indexing reaches a ready state before returning.
Example:
```json
{
"filename": "handbook.pdf",
"mimeType": "application/pdf",
"filePath": "/Users/me/Documents/handbook.pdf",
"bucket": "support-handbook",
"createMissingBuckets": true,
"waitForIndexing": true
}
```
### `calypso-upload-files-batch`
Uploads 1 to 100 files into the durable knowledge store in one request.
Notes:
- Uses `POST /v1/knowledge/files:batch/upload-session`, uploads each accepted item directly to storage, then finalizes with `POST /v1/knowledge/files:batch/upload-session/{batch_id}/finalize`.
- Uploads use JSON session requests plus signed binary `PUT`s, not multipart form uploads.
- Requires `batchIdempotencyKey`; Calypso uses it to derive the durable batch id for retries.
- Requires a shared bucket destination via `bucketIds`, `bucketSlugs`, or `bucket`, unless every item provides its own bucket destination.
- Supports shared `bucketIds`, `bucketSlugs`, `bucket`, and `createMissingBuckets` defaults, plus per-item overrides.
- Use per-item `filePath` for local Claude Desktop/Cursor MCP installs where the server can read each path. Use per-item `contentBase64` for hosted or remote MCP clients that cannot read local paths.
- Generates Firestore-safe `client_file_id` values when `clientFileId` is omitted.
- `accepted` or `queued` means the upload is durable, not necessarily query-ready. Use `waitForBatchReady: true` to poll `GET /v1/knowledge/batches/{batch_id}?include_items=true`.
- Inspect per-item status, `bucketSyncStatus`, and `bucketSync` to distinguish indexed content from bucket-ready retrieval.
Example:
```json
{
"batchIdempotencyKey": "kb-seed-2026-06-04",
"bucket": "support-handbook",
"createMissingBuckets": true,
"items": [
{
"filename": "faq.txt",
"mimeType": "text/plain",
"filePath": "/Users/me/Documents/faq.txt"
}
],
"waitForBatchReady": true
}
```
## Available resources
### `calypso://server-info`
Read-only server metadata, including package version, API base URL, transport, authentication model, and exposed capabilities.
### `calypso://rag-agent-models`
Read-only runtime catalog of team-scoped `calypso-agent` model variants discovered from the configured API key, including each variant's active `buckets`, `bucket_ids`, and `missing_bucket_ids`. If discovery is unavailable, this resource falls back to the base `calypso-agent`.
### `calypso://buckets`
Read-only runtime list of knowledge buckets for the team tied to the configured API key. Use it to inspect bucket ids/slugs and bucket-store readiness before uploads.
### `calypso://workflows`
A compact guide to the supported RAG and file-upload workflows.
### `calypso://security`
Operational security notes for API keys, local file reads, uploads, and logging.
## Available prompts
- **`calypso-question`**: draft a grounded knowledge-base question for `calypso-agent`
- **`calypso-ingestion`**: prepare a durable knowledge-store upload and follow-up query
- **`calypso-reset-conversation`**: start a clean RAG thread with `/new`
## Common workflows (copy/paste)
### Knowledge retrieval
- **Summarize a topic**:
- `Summarize the knowledge base guidance for campaign approvals`
- **Ask for a specific answer**:
- `What does our documentation say about indexing retries?`
- **Compare two concepts**:
- `Compare file indexing with retrieval execution in the current architecture`
- **Start a fresh thread**:
- `/new`
### Multi-turn follow-up
- **Refine a previous answer**:
- `Focus only on the ingestion path and ignore retrieval`
- **Ask for sources or justification**:
- `Explain which documented components are involved and why`
### Knowledge-store file flow
- **Discover buckets**:
- Call `calypso-list-buckets` or read `calypso://buckets` before choosing a destination
- **Upload durable knowledge**:
- Call `calypso-upload-file` with the file payload and optional `title`, `tags`, or `metadata`
- Prefer `filePath` for local Claude Desktop/Cursor MCP installs; use `contentBase64` for hosted or remote MCP clients that cannot read local paths
- **Route knowledge into buckets**:
- Use `bucket: "support-handbook"` for one destination, `bucketSlugs` for multiple slug-based destinations, or `bucketIds` when you already have stable bucket ids
- **Create bucket destinations on demand**:
- Add `createMissingBuckets: true` when using slug-based bucket assignment and the destination may not exist yet
- **Wait for indexing**:
- Pass `waitForIndexing: true` if you want the tool to block until the knowledge file is indexed
### Knowledge-store batch flow
- **Upload many durable files**:
- Call `calypso-upload-files-batch` with `items`, `batchIdempotencyKey`, and `filePath` per item for local MCP installs; use `contentBase64` per item for hosted or remote MCP clients
- **Route the batch into buckets**:
- Put shared `bucket`, `bucketSlugs`, `bucketIds`, or `createMissingBuckets` on the tool call, then override per item only when needed
- **Wait for query readiness**:
- Use `waitForBatchReady: true` and inspect returned item status plus bucket sync fields before querying fresh content
## Tips
- **Start over**: use `/new` to reset the MCP conversation (new `conversation_id` + cleared response chain).
## Version history
| Version | Notes |
| --- | --- |
| **3.0.0** | **Breaking.** Removed legacy `calypso-rag-agent` model-id support — an unrecognized id is now an error rather than being rewritten to the canonical family. Documented `calypso-search` and `calypso-add-website`, and fixed `calypso://server-info`, which had been omitting `calypso-add-website`. |
| **2.4.0** | Renamed the ask tool `calypso-rag-agent` → `calypso-agent`. The model catalog now takes its default from discovery instead of a hardcoded constant. |
| **2.3.x** | Search release and follow-up fixes. |
See [CHANGELOG.md](CHANGELOG.md) for detail.
### Upgrading to 3.0.0
Two renames landed across 2.4.0 and 3.0.0, and neither is aliased.
- **The ask tool is `calypso-agent`** (was `calypso-rag-agent`). MCP clients pick this up on their next `tools/list`, but any saved prompt, agent instruction, or documentation that names the tool as a string needs updating.
- **Model ids must be canonical.** `calypso-rag-agent` and `calypso-rag-agent:{id}` are no longer rewritten to `calypso-agent[:{id}]`. Passing one now fails with `Unknown Calypso agent model`, which names `calypso://rag-agent-models` as the place to find valid ids. Read that resource, or omit `model` to use the discovered default.
The `calypso://rag-agent-models` resource URI is deliberately unchanged. It is a published address, not a compatibility shim.
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: listing buckets, uploading a single file, uploading a batch of files, and querying the RAG agent. The two upload tools are well-separated by single vs. batch semantics, and the descriptions reinforce the boundaries.
Most tools follow a consistent `calypso-<verb>-<object>` pattern (list-knowledge-buckets, upload-knowledge-file, upload-knowledge-files-batch). The `calypso-rag-agent` tool deviates as it names a service rather than an action, but the prefix and hyphenation maintain a readable, predictable style.
Four tools is well-scoped for a focused multimodal RAG server. Each tool addresses a core need (bucket discovery, ingestion, bulk ingestion, and retrieval/chat), and none feel redundant or unnecessary.
The core workflow is covered: list buckets to find destinations, upload files (single or batch), and query via the RAG agent. Minor gaps exist (no explicit file deletion/update or bucket creation), but they are likely outside the intended scope and do not block the primary use case.