Action Gateway is in public preview.
Build a Web Research Assistantpublic
Last verified 16 Oct 2026
Action Gateway connects applications and AI agents to tools through a managed MCP endpoint or SDK, with the accounts and permissions you choose. See What You Can Build for standalone agent examples.
Use Action Gateway to give a coding agent two web research tools: exa_web_search to find sources and exa_web_fetch to read them. Create a session that permits only those catalog tools, preload their definitions, and connect your agent to its MCP URL. The agent runs in your client, not in Harness Runtime.
Prerequisites
- An MCP client, such as Claude Code or Codex, with its model access configured. See Connect an External MCP Client.
- Python or Go, and a DigitalOcean personal access token authorized for Action Gateway, available privately as
DIGITALOCEAN_TOKENin your local environment. Do not paste it into an agent conversation or commit it to source control. - A positive prepaid balance for Exa web search and web fetch. These tools have additional charges beyond standard tool invocation pricing.
Configure the Research Session
Replace <actor-id> with a stable identifier you assign to the user running this workflow, as described in Actors.
Install PyDo in your local Python environment:
pip install pydoCreate research_session.py with the following content:
import os
from pydo.action_gateway import ActionGatewayClient
gateway = ActionGatewayClient(token=os.environ["DIGITALOCEAN_TOKEN"])
session = gateway.session.create(
actor_id="<actor-id>",
name="web-research",
tools=["exa_web_search", "exa_web_fetch"],
permissions={
"default_action": "deny",
"rules": [
{"tool": "action_search", "action": "allow"},
{"tool": "action_invoke", "action": "allow"},
{"tool": "exa_web_search", "action": "allow"},
{"tool": "exa_web_fetch", "action": "allow"},
],
},
config={"preloadTools": ["exa_web_search", "exa_web_fetch"]},
)
print(session.url)Run the script locally to create the session and print its MCP endpoint:
python research_session.pyInstall Godo:
go get github.com/digitalocean/godoCreate research_session.go with the following content:
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"github.com/digitalocean/godo"
)
func main() {
client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN"))
ctx := context.Background()
session, _, err := client.ActionGateway.Sessions.CreateRuntime(ctx, &godo.ActionGatewaySessionCreateRequest{
Name: "web-research",
ActorID: "<actor-id>",
Tools: []string{"exa_web_search", "exa_web_fetch"},
Policy: &godo.ActionGatewaySessionPolicy{
DefaultAction: "deny",
Rules: []godo.ActionGatewaySessionPolicyRule{
{Tool: "action_search", Action: "allow"},
{Tool: "action_invoke", Action: "allow"},
{Tool: "exa_web_search", Action: "allow"},
{Tool: "exa_web_fetch", Action: "allow"},
},
},
Config: json.RawMessage(`{"preloadTools":["exa_web_search","exa_web_fetch"]}`),
})
if err != nil {
panic(err)
}
fmt.Println(session.MCPURL)
}Run the program locally to create the session and print its MCP endpoint:
go run research_session.goThe tools list restricts catalog access to the two Exa operations. preloadTools exposes their definitions immediately, while the search and invocation meta tools provide another route to the same permitted tools. The deny default leaves action_code disabled. This example does not need code execution.
The allow rules let Exa calls run without gateway approval and incur charges. They do not set a spending limit. To review each call first, change the two Exa rules to ask and use a client that supports gateway approvals.
Each run creates a session. Reuse the returned endpoint for subsequent research tasks rather than creating a session for every prompt.
Connect the Agent and Research a Topic
Register the printed URL as a Streamable HTTP MCP server named research-tools in your client, using the MCP client setup instructions. Use research-tools instead of action-gateway in those commands. Complete DigitalOcean sign-in as the session’s owner, in the same team, and start a new agent conversation.
Send the following prompt to your agent:
Use the research-tools MCP server to research strategies for reducing cold-start latency in serverless applications. Find three relevant sources, fetch their pages, and write a brief comparing the approaches. Cite the source URLs and distinguish evidence from your own recommendations. Do not publish the brief or use other tool servers.The agent can call the preloaded Exa tools directly or use the meta tools to discover and invoke them. Expect a brief with links to the pages it retrieved. If a page cannot be fetched, the agent should identify the missing source rather than treat it as verified. Check the citations before using the brief.
The policy governs calls through this Action Gateway session, not other tools your client exposes. Treat text from retrieved pages as source material, not as instructions that authorize new actions.
Reduce Search Output with a View
The script uses full tool output. To return smaller search results, create a view for exa_web_search named research_sources, keeping results.title and results.url. The agent can fetch the selected URLs when it needs their content.
After creating the view, replace the config argument in your session script with this configuration:
config={
"preloadTools": ["exa_web_search", "exa_web_fetch"],
"outputViews": {"exa_web_search": "research_sources"},
},Config: json.RawMessage(`{"preloadTools":["exa_web_search","exa_web_fetch"],"outputViews":{"exa_web_search":"research_sources"}}`),Run the script to create a replacement session and update the client’s MCP URL. Search results now contain the selected fields; fetch results remain unchanged. Confirm that the agent still receives the source titles and URLs it needs. Output views reduce returned data, not tool invocation charges.
For recurring workflows, review the production configuration guide. Put known tool calls in application code when you need fixed steps rather than model-selected actions.