Multi-service integrations
These guides show how to combine products into something you can run end to end. Each example uses a realistic flow and names the exact handoff between services.
What works together
| Pattern | What you get |
|---|---|
| Agent + Functions | Tool-calling workflows with clean separation of model and compute |
| Agent + Weather MCP | Real-time lookups through a shared MCP tool server |
| Functions + Pub/Sub | Event-driven processing with retries and dead-lettering |
| Functions + Object Storage | File intake and processing pipelines — the file itself is the request body |
| Agent + Vectors + Secrets | Private knowledge retrieval, reached through an MCP server, with controlled credential use |
Agent + Functions: tool chain
Use an Agent when the workflow needs reasoning, and expose deterministic work as Functions. The agent calls the function as a tool, so the model handles the decision and the function handles the execution.
Flow
- The user asks for something that needs computation, transformation, or validation.
- The agent selects a function tool and sends the minimal payload.
- The function returns a small result that the model can summarize.
Example
- Agent: a support assistant that routes requests.
- Function: a
ticket-triagehandler that normalizes the incoming payload and computes routing hints. - Result: the agent answers with a triaged recommendation instead of guessing.
Build the function first and test it directly, then let the agent call it. That keeps debugging simple: if the function works in isolation, the agent only has to choose it correctly.
Agent + Weather MCP: real-time info
An Agent can call a weather MCP tool that fetches live conditions. This is the cleanest way to give a model current facts without letting it loose on free-form browsing.
Flow
- Publish a weather tool to an MCP server.
- Attach the MCP server to the agent or call it from the agent’s toolset.
- Ask a question that depends on the weather.
- Verify that the model chooses the MCP path instead of inventing an answer.
Example payload
{"city": "Reykjavik"}
The MCP response is a small structured result. That makes it ideal for agent tools because the model receives data in the shape your tool contract promises.
Functions + Pub/Sub: event-driven pipeline
A Pub/Sub subscription can invoke a Function whenever a message lands on a topic. This is the event-driven pattern you already used for order work.
Flow
- Create a topic for the event stream.
- Create a push subscription that targets the function.
- Publish a message.
- Watch the function log the event.
Failure handling
The same pattern also gives you retries and, when you configure one, a dead-letter topic. Any non-2xx from the function is a failed attempt, and the platform redelivers with exponential backoff. If redelivery keeps failing, the platform republishes the message to the dead-letter topic for inspection — and with no dead-letter topic named, the message is dropped once it exhausts max_deliver (5 by default).
That is the important difference from calling a function manually: the system handles transport and recovery, not just the request payload.
Functions + Vectors: search/sonnet
Pair a Function with Vectors when you need retrieval plus a user-facing answer. The function fetches relevant documents, then the agent or the app layer uses those results to produce the final response.
Flow
- Ingest your documents into Vectors.
- The function receives a search request and queries the index.
- The function returns the top matches.
- A writer service, agent, or front end turns those matches into a user-visible answer.
This is the pattern behind a retrieval-augmented app. The function keeps the vector query small and controlled; the model or writer handles the language.
Functions + Object Storage: trigger by polling
Use Object Storage as the intake point for files and a Function as the processor. The trigger is a poller, not a notification listener: bucket notifications are not something the store is relied on to provide, so the platform lists the bucket on an interval instead.
Flow
- Upload a file to object storage.
- The poller lists the bucket — every
poll_seconds, 60 by default — and finds it. A drop is never instant. - It POSTs the object's bytes as the request body to the function. There is no
bucketfield and nokeyfield, and the function needs no S3 client: it transforms what it was handed and writes the result somewhere durable. after_readdecides what happens to the object next — moved, deleted, or left to be delivered again on the next poll. It is required and has no default.
The recovery story is thinner than Pub/Sub's, and it is worth knowing before you rely on it: this source has no dead-letter path, and a trigger's retry settings do not reach it. Prefer after_read: move over delete for anything you cannot regenerate — every consumed object lands in the destination prefix you name, so a file whose processing went wrong is still there to look at and reprocess.
This pattern is the right fit for batch imports, document processing, and any workflow where the file itself is the source of truth — as long as each file is under the shim's 8 MiB body cap. See Functions + Object Storage for the handler shape and the fact that the object's key is not delivered.
Agent + Vectors + Secrets: private knowledge base
This is the classic private-knowledge pattern. Vectors hold the embeddings for your private documents. Secrets hold the credentials for external systems you must call. The Agent uses both.
Flow
- Load the document embeddings into Vectors.
- Store the retrieval credential — a service-account key — in Secrets.
- Publish the retrieval tool on an MCP server: it declares the secret in
credential_keysand fetches it withcrusoe.secret()at call time. Retrieval cannot live in an agent tool, because tool code is customer code and runs in a sandbox with no network egress — it would reach neither the embedding endpoint nor the index. - Attach that server to the agent (
mcp_toolsets()for ADK,crusoe_langchain.mcp_tools()orcrusoe_crewai.mcp_tools()elsewhere) and let the model call the tool. - Return an answer grounded in the indexed documents.
This is the safest end-state when you need an agent to reason over company material without pasting raw documents into prompts. Agent + Vectors + Secrets has the working version.
The whole loop: bucket to published agent
Everything above, chained. Documents land in Object storage and index themselves through three Functions joined by Pub/Sub; retrieval lives on an MCP server that does a two-stage Embeddings + Reranking lookup against a VectorDB index; the Agent is published through the Gateway behind an API key; and its Sessions can be cloned and rewound when an answer needs explaining.
Flow
- A file appears in a bucket. The object-store trigger fires the ingest function.
- Ingest publishes the document to an uploads topic.
- A Pub/Sub trigger fires the chunker, which publishes one message per chunk.
- A second trigger fires the embedder, which upserts vectors into the index.
- The agent asks its MCP server; the server searches wide and reranks.
- The gateway endpoint puts the agent at an address, with a key and a rate limit.
- A bad answer is reproduced on a clone of the reported session, rewound to the turn that went wrong.
Nothing in steps 1-4 is invoked by hand, and every stage scales to zero between documents.
A support agent that re-indexes itself is the long-form version, with the decisions and the traps.
How to choose
- Choose Agent + Functions when the model needs to decide and the code needs to be exact.
- Choose Agent + MCP when the model needs a stable tool contract for real-time data.
- Choose Functions + Pub/Sub when work arrives asynchronously and needs retries.
- Choose Functions + Vectors when the app is retrieval-heavy.
- Choose Functions + Object Storage when files arrive and must be processed automatically, and a minute of polling latency is acceptable.
- Choose Agent + Vectors + Secrets — with the retrieval tool on an MCP server — when the answer depends on private documents and controlled credentials.
- Choose the whole loop when the corpus changes without you: documents are edited by other people, and the index has to keep up on its own.