Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,26 @@ from contacts that are not on this allowlist. The
connector without them permits outbound token access but does not forward
incoming messages to OpenInstinct.

## Public web search

The root agent can search the web and read public pages through
[Parallel Search MCP](https://docs.parallel.ai/integrations/mcp/search-mcp).
The native Eve connection in `agent/connections/parallel.ts` is discovered
automatically. No Parallel account, API key, OAuth setup, or extra package is
required. Free anonymous access has lower rate limits and is intended for
exploration and light use.

The agent discovers the connection with `connection_search`, then calls
`parallel__web_search` or `parallel__web_fetch`. Only those two tools are
allowed. Existing gateway search remains available. Interactive browsing,
sign-in, forms, and purchases still belong to the browser worker.

Search terms and requested URLs are sent to Parallel. Use this connection only
for public information, never private messages, account data, vault contents,
credentials, or authenticated or signed URLs. Retrieved pages remain
untrusted content. Restart development or rebuild the application after
changing connection files.

## Google Workspace connection

OpenInstinct can use a user's Gmail, Calendar, and read-only Contacts through a
Expand Down
8 changes: 8 additions & 0 deletions agent/connections/parallel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineMcpClientConnection } from "eve/connections";

export default defineMcpClientConnection({
url: "https://search.parallel.ai/mcp",
description:
"Search the public web and extract content from public URLs with Parallel. Find current facts and sources without an API key. Send only public information, never private account data or secrets.",
tools: { allow: ["web_search", "web_fetch"] },
});
2 changes: 2 additions & 0 deletions agent/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The main conversation is the control plane. Coordinate the user's work there, de
- Recover from a browser failure with at most two materially different tactics. If neither works, stop promptly and report the last verified state and exact blocker instead of leaving the task running.
- Prefer the narrowest capable integration: root vault setup for non-secret coordination, connected tools for their supported services, `web_search` for public discovery and current facts, `web_fetch` for reading a known public page, and `worker` only for work that requires browser interaction or browser state.
- Perform public research, source discovery, comparisons, and current-information lookups directly with `web_search`. Never delegate a search-only task or use a browser to visit a search engine or browse search-result pages. When a known public URL only needs to be read, try `web_fetch` before browser automation.
- The `parallel` connection offers public web search and public page extraction. Discover `parallel__web_search` and `parallel__web_fetch` with `connection_search` when those capabilities fit the task. Keep source links in factual answers, and report search failures or rate limits instead of inventing results.
- Send only public search terms and public URLs to `parallel`. Never send credentials, vault data, private messages, private account content, or authenticated or signed URLs to public search or extraction tools.
- Prefer `google_workspace_read` and `google_workspace_write` over browser automation for connected Gmail, Calendar, and Contacts work. Never ask for Google tokens or credentials in chat. If authorization is required, let the connection surface its sign-in challenge.
- Use exact Gmail message IDs for reversible inbox updates. Before sending email or creating a calendar event, make the recipients, content, timing, attendees, and other material fields explicit in the approval request.
- Keep the user's constraints intact while delegating, comparing alternatives, recovering from failures, and synthesizing results.
Expand Down
1 change: 1 addition & 0 deletions knip.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { KnipConfig } from "knip";
export default {
entry: [
"agent/channels/**/*.ts",
"agent/connections/**/*.ts",
"agent/hooks/**/*.ts",
"agent/instructions/**/*.ts",
"agent/memory/**/*.ts",
Expand Down
24 changes: 24 additions & 0 deletions tests/parallel-connection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from "vitest";
import parallel from "../agent/connections/parallel";

describe("Parallel public web connection", () => {
it("uses the free MCP endpoint", () => {
expect(parallel.url).toBe("https://search.parallel.ai/mcp");
});

it("exposes only public search and page extraction", () => {
expect(parallel.tools).toEqual({
allow: ["web_search", "web_fetch"],
});
});

it("does not attach credentials or session-derived arguments", () => {
expect(parallel.auth).toBeUndefined();
expect(parallel.headers).toBeUndefined();
expect(parallel.toolCall).toBeUndefined();
});

it("describes the public-only data boundary during discovery", () => {
expect(parallel.description).toContain("Send only public information");
});
});