searchport
searchport is one doorway to five kinds of Brave search. A single question can be asked against the general web index, local business listings, current news, images, or videos, and every answer comes back in the same shape: a title, the address it lives at, a short excerpt, and one extra line of detail that fits the kind — how long ago a story ran, how long a video plays, where a shop is and how it is rated. It runs from the command line or as an MCP server for agents.
A Brave Search API subscription key is required. Put it in the
BRAVE_API_KEY environment variable; the key is sent to the API as the
X-Subscription-Token header and never appears in output. When the
variable is missing, every search fails with an error that names it.
Install
npx @reneturcios/searchport web "trail running shoes"
Or run the container image:
docker run -i -e BRAVE_API_KEY ghcr.io/cloudcorprecords/searchport
The container defaults to the MCP server (see below). Pass CLI arguments to use it as a CLI instead.
CLI
export BRAVE_API_KEY="your subscription key"
# General web search; --count is results per page (max 20),
# --offset pages forward (max 9)
searchport web "composting basics"
searchport web "composting basics" --count 5 --offset 1
# The other four kinds take the same query and --count
searchport local "bakery near the mission" --count 5
searchport news "trail network vote"
searchport images "ridge sunrise"
searchport videos "trail running form"
# Machine-readable output for any kind
searchport web "composting basics" --json
searchport --version
Exit codes: 0 on success, 1 when a search fails (including a
missing BRAVE_API_KEY or an API error), 2 for usage errors.
MCP server
One bin serves both faces. The mcp subcommand starts a stdio MCP
server:
npx -y @reneturcios/searchport mcp
MCP client configuration:
{
"mcpServers": {
"searchport": {
"command": "npx",
"args": ["-y", "@reneturcios/searchport", "mcp"],
"env": { "BRAVE_API_KEY": "your subscription key" }
}
}
}
Tools
| Tool | Input | What it returns |
|---|---|---|
brave_web_search |
query (string, required), count (number, optional), offset (number, optional) |
Web results as a numbered text block: title, URL, and excerpt per result. |
brave_local_search |
query (string, required), count (number, optional) |
Local listings: name, URL, and a detail line with address, phone, and rating when the API provides them. |
brave_news_search |
query (string, required), count (number, optional) |
News stories: headline, URL, summary, and the story's age. |
brave_image_search |
query (string, required), count (number, optional) |
Image results: title, source page URL, and the direct image URL. |
brave_video_search |
query (string, required), count (number, optional) |
Video results: title, URL, description, and duration. |
Counts are clamped to the API's per-page limit of 20 and offsets to its maximum of 9. An empty result set is reported as such, not as an error; a missing key or a failed API call is reported as a tool error.
Development
npm install
npm run build # tsc -> dist/
npm test # node test runner over test/*.test.ts, no network (fake fetch fixtures)
npm run dev # run the CLI from source via tsx
License
MIT — see LICENSE.