mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-01 15:35:12 +01:00
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Connections let those agents use external services with explicit access rules. > - Zapier, Arcade, Composio Connect, and Executor already have setup and runtime support. > - Their experimental switch still blocks discovery and setup by default. > - This pull request removes those gates and the Settings toggle. > - Users can connect these providers without enabling an experiment. ## Linked Issues or Issue Description Refs #13755. Refs #13941. **What existing behavior does this improve?** Apps browsing, inline setup, and agent connection search for the four MCP aggregators. **Current behavior** An instance must enable the MCP aggregators experiment before users or agents can start setup. **Proposed behavior** All four providers are available by default on local and managed instances. Old stored and managed values still parse but cannot disable them. ## What Changed - Remove the aggregator gates from Apps, inline setup, server setup, and agent search. - Remove the Settings toggle and its UI hook. - Retain the old setting key only for upgrade compatibility. Normalize it to true and ignore managed overrides, as Apps already does. - Replace opt-in fixtures with default-on coverage. Test old false values, all four setup flows, provider choice, and the removed toggle. - Update current connector guidance and remove the opt-in from the runner acceptance fixture. ## Verification - 306 focused tests passed across eight files: shared remote MCP contracts; server remote MCP lifecycle, aggregator fallback, settings normalization, and managed overlay; UI Apps browsing, setup, and experimental settings. - Server and UI TypeScript checks passed. - UI token gates and `git diff --check` passed. - The full local suite was not run, per the maintainer's instruction. All 54 CI checks passed; two checks were skipped. One unrelated workspace-preview readiness timeout passed on one failed-shard retry. - The setup fixtures use simulated MCP responses. This change does not claim new live provider acceptance. ## Risks - Existing instances now show all four providers, even if the old flag was false. This is intentional. - External provider choice, credentials, company isolation, agent grants, and tool policies still apply. Showing a connector does not authorize an external account. - No data migration is required. The compatibility key keeps old managed configuration documents valid. - Historical Zapier live acceptance remains incomplete in the existing evidence report. The maintainer explicitly requested the default-on rollout for all four existing providers; the report records that scoped exception. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) through Codex, with reasoning, repository tools, and test execution. The context window size is not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
39 lines
2.9 KiB
TypeScript
39 lines
2.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { getConnectableAppDefinition } from "./app-definitions.js";
|
|
import { isRemoteMcpConnectorMethod, REMOTE_MCP_CONNECTOR_METHODS } from "./remote-mcp-connectors.js";
|
|
import { connectToolAppSchema, finishToolAppSchema } from "./validators/tool-access.js";
|
|
import { instanceExperimentalSettingsSchema, patchInstanceExperimentalSettingsSchema } from "./validators/instance.js";
|
|
import { INSTANCE_FEATURE_CATALOG } from "./feature-catalog.js";
|
|
|
|
describe("independent remote MCP connectors", () => {
|
|
it("defaults the retired compatibility setting on and accepts older configs", () => {
|
|
expect(instanceExperimentalSettingsSchema.parse({}).enableMcpAggregators).toBe(true);
|
|
expect(patchInstanceExperimentalSettingsSchema.parse({ enableMcpAggregators: false })).toEqual({ enableMcpAggregators: false });
|
|
expect(patchInstanceExperimentalSettingsSchema.parse({})).not.toHaveProperty("enableMcpAggregators");
|
|
expect(INSTANCE_FEATURE_CATALOG.enableMcpAggregators).toMatchObject({ tier: "managed", cloudDefault: true, selfHostedDefault: true });
|
|
});
|
|
for (const [provider, methodKey] of Object.entries(REMOTE_MCP_CONNECTOR_METHODS)) {
|
|
it(`${provider} has its own catalog and accepts URL plus explicit credentials`, () => {
|
|
const definition = getConnectableAppDefinition(provider)!;
|
|
expect(definition.slug).toBe(provider);
|
|
const method = definition.methods.find((method) => method.key === methodKey)!;
|
|
expect(method.transport).toBe("mcp_remote");
|
|
if (provider !== "zapier") expect(method.ownershipModes).toContain("dcr");
|
|
expect(connectToolAppSchema.safeParse({ galleryKey: provider, connectionMethodKey: methodKey, link: "https://example.com/mcp", authMode: "bearer", credentialValues: { "credentials.authorization": "test-secret", "headers.X-User-ID": "test-user" } }).success).toBe(true);
|
|
});
|
|
}
|
|
it("removes the legacy Composio API-key method", () => {
|
|
expect(isRemoteMcpConnectorMethod("composio", "api-key")).toBe(false);
|
|
expect(getConnectableAppDefinition("composio")?.methods.find((method) => method.key === "api-key")).toBeUndefined();
|
|
expect(connectToolAppSchema.safeParse({ galleryKey: "composio", connectionMethodKey: "api-key", authMode: "bearer" }).success).toBe(false);
|
|
});
|
|
it("allows removing all agent access without changing the tool choices", () => {
|
|
expect(finishToolAppSchema.safeParse({ access: { agentIds: [] } }).success).toBe(true);
|
|
expect(finishToolAppSchema.safeParse({ access: { agentIds: ["not-an-agent-id"] } }).success).toBe(false);
|
|
});
|
|
it("rejects unsafe header overrides and draft saving on unrelated connectors", () => {
|
|
expect(connectToolAppSchema.safeParse({ galleryKey: "arcade", connectionMethodKey: "mcp", credentialValues: { "headers.Host": "evil.example" } }).success).toBe(false);
|
|
expect(connectToolAppSchema.safeParse({ galleryKey: "github", saveDraft: true }).success).toBe(false);
|
|
});
|
|
});
|