diff --git a/packages/shared/src/app-definitions.generated.ts b/packages/shared/src/app-definitions.generated.ts index 60690545b5a..90aabc87757 100644 --- a/packages/shared/src/app-definitions.generated.ts +++ b/packages/shared/src/app-definitions.generated.ts @@ -57,17 +57,18 @@ import a55 from "./app-definitions/mem0.json" with { type: "json" }; import a56 from "./app-definitions/pagerduty.json" with { type: "json" }; import a57 from "./app-definitions/similarweb.json" with { type: "json" }; import a58 from "./app-definitions/xero.json" with { type: "json" }; -import a59 from "./app-definitions/gmail.json" with { type: "json" }; -import a60 from "./app-definitions/google-drive.json" with { type: "json" }; -import a61 from "./app-definitions/google-docs.json" with { type: "json" }; -import a62 from "./app-definitions/google-sheets.json" with { type: "json" }; -import a63 from "./app-definitions/google-slides.json" with { type: "json" }; -import a64 from "./app-definitions/google-calendar.json" with { type: "json" }; -import a65 from "./app-definitions/google-chat.json" with { type: "json" }; -import a66 from "./app-definitions/google-people.json" with { type: "json" }; -import a67 from "./app-definitions/google-workspace-search.json" with { type: "json" }; -import a68 from "./app-definitions/openai.json" with { type: "json" }; -import a69 from "./app-definitions/openrouter.json" with { type: "json" }; -import a70 from "./app-definitions/xai.json" with { type: "json" }; +import a59 from "./app-definitions/youcom.json" with { type: "json" }; +import a60 from "./app-definitions/gmail.json" with { type: "json" }; +import a61 from "./app-definitions/google-drive.json" with { type: "json" }; +import a62 from "./app-definitions/google-docs.json" with { type: "json" }; +import a63 from "./app-definitions/google-sheets.json" with { type: "json" }; +import a64 from "./app-definitions/google-slides.json" with { type: "json" }; +import a65 from "./app-definitions/google-calendar.json" with { type: "json" }; +import a66 from "./app-definitions/google-chat.json" with { type: "json" }; +import a67 from "./app-definitions/google-people.json" with { type: "json" }; +import a68 from "./app-definitions/google-workspace-search.json" with { type: "json" }; +import a69 from "./app-definitions/openai.json" with { type: "json" }; +import a70 from "./app-definitions/openrouter.json" with { type: "json" }; +import a71 from "./app-definitions/xai.json" with { type: "json" }; import type { AppDefinition } from "./types/app-definition.js"; -export const APP_DEFINITIONS=[a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70] as AppDefinition[]; +export const APP_DEFINITIONS=[a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71] as AppDefinition[]; diff --git a/packages/shared/src/app-definitions.test.ts b/packages/shared/src/app-definitions.test.ts index 7fd5e456308..e1ae262d548 100644 --- a/packages/shared/src/app-definitions.test.ts +++ b/packages/shared/src/app-definitions.test.ts @@ -278,7 +278,7 @@ describe("AppDefinition catalog", () => { "google-workspace-search", ]), ); - expect(SELF_SERVE_MCP_CANDIDATES).toHaveLength(43); + expect(SELF_SERVE_MCP_CANDIDATES).toHaveLength(44); expect(BLOCKED_MCP_PROVIDERS.map((entry) => entry.slug)).toEqual([ "g2", "vercel", @@ -431,12 +431,15 @@ describe("AppDefinition catalog", () => { expect(channel("slack")?.guidanceMd).toContain("reactions"); expect(channel("slack")?.guidanceMd).toContain("direct messages"); }); - it("keeps a complete, unique, dated evidence ledger for all 46 researched MCP providers", () => { + it("keeps a complete, unique, dated evidence ledger for all 47 researched MCP providers", () => { + // Ledger-wide date reflects the last full re-verification (2026-08-26); + // the You.com entry added here carries its own research evidence, but + // bumping the shared date would overstate freshness for the other providers. expect(SELF_SERVE_MCP_RESEARCH.verifiedAt).toBe("2026-08-26"); - expect(SELF_SERVE_MCP_RESEARCH.entries).toHaveLength(46); + expect(SELF_SERVE_MCP_RESEARCH.entries).toHaveLength(47); expect( new Set(SELF_SERVE_MCP_RESEARCH.entries.map((entry) => entry.slug)), - ).toHaveProperty("size", 46); + ).toHaveProperty("size", 47); for (const entry of SELF_SERVE_MCP_RESEARCH.entries) { expect(new URL(entry.docsUrl).protocol).toBe("https:"); expect(new URL(entry.serverUrl).protocol).toBe("https:"); @@ -566,6 +569,25 @@ describe("AppDefinition catalog", () => { defaults: {}, }); expect(method("zapier")?.credentialFields).toBeUndefined(); + expect( + APP_DEFINITIONS.find((app) => app.slug === "youcom")?.methods.map( + (candidate) => candidate.key, + ), + ).toEqual(["mcp-oauth", "mcp-api-key", "mcp-free"]); + expect(method("youcom")?.defaults?.serverUrl).toBe("https://api.you.com/mcp"); + expect(method("youcom", "mcp-api-key")).toMatchObject({ + auth: "api_key", + keyPlacement: { + location: "header", + name: "Authorization", + prefix: "Bearer ", + }, + }); + expect(method("youcom", "mcp-free")).toMatchObject({ + auth: "none", + defaults: { serverUrl: "https://api.you.com/mcp?profile=free" }, + }); + expect(method("youcom", "mcp-free")?.credentialFields).toBeUndefined(); }); it("uses discovery-first Notion MCP OAuth metadata", () => { const notion = APP_DEFINITIONS.find((app) => app.slug === "notion"); @@ -687,7 +709,7 @@ describe("AppDefinition catalog", () => { "ticktick", "xero", ]); - expect(APP_STORE_DEFINITIONS).toHaveLength(47); + expect(APP_STORE_DEFINITIONS).toHaveLength(48); const connectableSlugs = new Set( CONNECTABLE_APP_DEFINITIONS.map((entry) => entry.slug), ); diff --git a/packages/shared/src/app-definitions/youcom.json b/packages/shared/src/app-definitions/youcom.json new file mode 100644 index 00000000000..dc9479cc19f --- /dev/null +++ b/packages/shared/src/app-definitions/youcom.json @@ -0,0 +1,100 @@ +{ + "schemaVersion": 1, + "slug": "youcom", + "name": "You.com", + "description": "Connect You.com's provider-hosted MCP server.", + "categories": [ + "ai" + ], + "featured": false, + "branding": { + "logoUrl": "/brands/apps/youcom.svg", + "darkLogoUrl": "/brands/apps/youcom-dark.svg" + }, + "urlPatterns": [ + "https://api.you.com/*" + ], + "docsUrl": "https://you.com/docs/build-with-agents/mcp-server", + "redirectConstraints": "https-or-loopback-http", + "methods": [ + { + "key": "mcp-oauth", + "transport": "mcp_remote", + "auth": "oauth", + "ownershipModes": [ + "dcr" + ], + "whenToUse": "Use browser sign-in for the provider-hosted MCP server.", + "defaults": { + "serverUrl": "https://api.you.com/mcp" + }, + "guidanceMd": "Connect You.com in the browser. A You.com account for browser sign-in, or a You.com API key from you.com/platform for higher rate limits; a keyless free profile is also available.", + "riskTier": "S2", + "label": "Sign in with You.com", + "consoleLinks": { + "docs": "https://you.com/docs/build-with-agents/mcp-server" + }, + "warnings": [ + "A You.com account for browser sign-in, or a You.com API key from you.com/platform for higher rate limits; a keyless free profile is also available." + ] + }, + { + "key": "mcp-api-key", + "transport": "mcp_remote", + "auth": "api_key", + "ownershipModes": [ + "customer" + ], + "whenToUse": "Use a restricted customer-owned key when browser sign-in is not suitable.", + "defaults": { + "serverUrl": "https://api.you.com/mcp" + }, + "guidanceMd": "Use a customer-created You.com key. A You.com account for browser sign-in, or a You.com API key from you.com/platform for higher rate limits; a keyless free profile is also available.", + "riskTier": "S2", + "label": "Use an API key", + "credentialFields": [ + { + "key": "authorization", + "label": "You.com API key", + "type": "password", + "required": true, + "placeholder": "Paste your You.com API key", + "secret": true + } + ], + "keyPlacement": { + "location": "header", + "name": "Authorization", + "prefix": "Bearer " + }, + "consoleLinks": { + "keys": "https://you.com/docs/build-with-agents/mcp-server", + "docs": "https://you.com/docs/build-with-agents/mcp-server" + }, + "warnings": [ + "A You.com account for browser sign-in, or a You.com API key from you.com/platform for higher rate limits; a keyless free profile is also available." + ] + }, + { + "key": "mcp-free", + "transport": "mcp_remote", + "auth": "none", + "ownershipModes": [ + "customer" + ], + "whenToUse": "Connect without an account for limited, rate-capped web search.", + "defaults": { + "serverUrl": "https://api.you.com/mcp?profile=free" + }, + "guidanceMd": "Use the keyless free profile. You.com limits the free profile to a reduced read-only tool set.", + "riskTier": "S2", + "label": "Use the free profile", + "consoleLinks": { + "docs": "https://you.com/docs/build-with-agents/mcp-server" + }, + "warnings": [ + "The free profile is keyless and exposes a reduced read-only tool set with You.com rate limits." + ] + } + ] +} diff --git a/packages/shared/src/self-serve-mcp-research.json b/packages/shared/src/self-serve-mcp-research.json index 32374b802c8..61aed3e33eb 100644 --- a/packages/shared/src/self-serve-mcp-research.json +++ b/packages/shared/src/self-serve-mcp-research.json @@ -48,6 +48,8 @@ { "slug": "xero", "name": "Xero", "wave": 3, "status": "self_serve", "docsUrl": "https://developer.xero.com/ai", "serverUrl": "https://mcp.xero.com/mcp", "authMode": "customer_oauth", "prerequisite": "Create a Xero OAuth app and confirm the applicable AI and data-use terms before connecting.", "riskTier": "S4" }, { "slug": "zapier", "name": "Zapier", "wave": 3, "status": "self_serve", "docsUrl": "https://docs.zapier.com/mcp/quickstart", "serverUrl": "https://mcp.zapier.com/", "authMode": "generated_url", "prerequisite": "Create a Zapier MCP server, choose the actions it exposes, and paste its generated connection URL.", "riskTier": "S3" }, + { "slug": "youcom", "name": "You.com", "wave": 4, "status": "self_serve", "docsUrl": "https://you.com/docs/build-with-agents/mcp-server", "serverUrl": "https://api.you.com/mcp", "authMode": "dcr_or_api_key", "prerequisite": "A You.com account for browser sign-in, or a You.com API key from you.com/platform for higher rate limits; a keyless free profile is also available.", "riskTier": "S2" }, + { "slug": "g2", "name": "G2", "wave": "blocked", "status": "blocked", "docsUrl": "https://documentation.g2.com/docs/g2-mcp-server", "serverUrl": "https://mcp.g2.com/mcp", "authMode": "provider_approval", "prerequisite": "G2 must enable cross-application token introspection before an independently registered client can work.", "riskTier": "S3" }, { "slug": "vercel", "name": "Vercel", "wave": "blocked", "status": "blocked", "docsUrl": "https://vercel.com/docs/agent-resources/vercel-mcp", "serverUrl": "https://mcp.vercel.com", "authMode": "provider_approval", "prerequisite": "Vercel currently reviews and approves MCP clients.", "riskTier": "S3" }, { "slug": "zomato", "name": "Zomato", "wave": "blocked", "status": "blocked", "docsUrl": "https://github.com/Zomato/mcp-server-manifest", "serverUrl": "https://mcp-server.zomato.com/mcp", "authMode": "provider_approval", "prerequisite": "Zomato currently limits third-party clients and requires redirect-URI allowlisting.", "riskTier": "S3" } diff --git a/scripts/ingest-app-definitions.mjs b/scripts/ingest-app-definitions.mjs index 719a04d38ca..1e33b374e07 100644 --- a/scripts/ingest-app-definitions.mjs +++ b/scripts/ingest-app-definitions.mjs @@ -955,6 +955,7 @@ const categoryBySlug = { webflow: "content", wix: "content", xero: "commerce", + youcom: "ai", zapier: "productivity", }; const oauthMethodFor = ( @@ -1042,6 +1043,11 @@ const apiKeySpec = { prefix: "Bearer ", placeholder: "sbp_...", }, + youcom: { + name: "Authorization", + prefix: "Bearer ", + placeholder: "Paste your You.com API key", + }, }; const apiKeyMethodFor = ( entry, @@ -1342,6 +1348,32 @@ const specialMethodsFor = (entry) => { }), ]; } + if (entry.slug === "youcom") { + // You.com also serves a documented keyless profile at ?profile=free with a + // reduced read-only tool set. That is a real user choice: try web search + // with no account, or connect the full authenticated server. + return [ + oauthMethodFor(entry), + apiKeyMethodFor(entry), + method( + "mcp-free", + "mcp_remote", + "none", + { serverUrl: "https://api.you.com/mcp?profile=free" }, + entry.riskTier, + "Use the keyless free profile. You.com limits the free profile to a reduced read-only tool set.", + { + label: "Use the free profile", + whenToUse: + "Connect without an account for limited, rate-capped web search.", + consoleLinks: { docs: entry.docsUrl }, + warnings: [ + "The free profile is keyless and exposes a reduced read-only tool set with You.com rate limits.", + ], + }, + ), + ]; + } return null; }; diff --git a/server/src/__tests__/tool-access-service.test.ts b/server/src/__tests__/tool-access-service.test.ts index 6aa801701aa..4831c866e80 100644 --- a/server/src/__tests__/tool-access-service.test.ts +++ b/server/src/__tests__/tool-access-service.test.ts @@ -5098,9 +5098,10 @@ describeEmbeddedPostgres("tool access service", () => { "google-people", "google-workspace-search", "github", + "youcom", ]), ); - expect(res.body.apps).toHaveLength(47); + expect(res.body.apps).toHaveLength(48); expect( res.body.apps.find((app: { slug: string }) => app.slug === "gmail") .ownershipAvailability, diff --git a/ui/public/brands/apps/manifest.json b/ui/public/brands/apps/manifest.json index afe72336f75..502752b825e 100644 --- a/ui/public/brands/apps/manifest.json +++ b/ui/public/brands/apps/manifest.json @@ -417,6 +417,13 @@ "catalogVisible": false, "localAsset": "/brands/apps/xero.svg" }, + { + "slug": "youcom", + "provider": "You.com", + "catalogVisible": true, + "localAsset": "/brands/apps/youcom.svg", + "darkAsset": "/brands/apps/youcom-dark.svg" + }, { "slug": "zapier", "provider": "Zapier", diff --git a/ui/public/brands/apps/youcom-dark.svg b/ui/public/brands/apps/youcom-dark.svg new file mode 100644 index 00000000000..d6ba2a8085e --- /dev/null +++ b/ui/public/brands/apps/youcom-dark.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/ui/public/brands/apps/youcom.svg b/ui/public/brands/apps/youcom.svg new file mode 100644 index 00000000000..308e73d5e25 --- /dev/null +++ b/ui/public/brands/apps/youcom.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + +