{"slug": "connecting-every-app-to-every-other-app", "title": "Connecting every app to every other app", "summary": "Val Town, a vibe coding platform, has implemented Dynamic Client Registration (DCR) and Client ID Metadata Documents (CIMD) to enable any app to dynamically authenticate and authorize any other app, solving the n² problem of connecting every app to every other app. The company created std/oauth, a middleware library that adds 'Login with Val Town' OAuth in two lines of code, and its MCP server/plugin supports OAuth from Claude and ChatGPT.", "body_md": "I've long envied Zapier's extensive connectors library. I wish our app –\n[Val Town](https://val.town/), a vibe coding platform – could one-click connect\nto every app.\n\n[zapier.com/apps](https://zapier.com/apps)\n\nThis is a classic n² problem, connecting every app to every other app.\n\nMy dream has always been that there could be some *protocol* by which any app\ncould *dynamically* *authenticate* and *authorize* any other app.\n\nIs OAuth that protocol?\n\nAlmost!\n\n## Registering OAuth Clients\n\nThe core n² problem remains: every app still needs to register as an OAuth client for every other app.\n\nAt best, registering an OAuth client is 5 minutes of clicking around a developer portal. But you never know. It can mean filling out some forms, making a demo video, signing paperwork, or, horror of horrors, getting on a video call. It's a ad-hoc, manual headache. And we all have to do it for every single app our users want to connect to.\n\nBut there's reason for hope! Anthropic and OpenAI saw this problem coming. They\nneed a way to connect to all their customers' apps, but they didn't want to get\nall those OAuth clients. So they put a little-known OAuth extension\n[into the spec for MCP](https://modelcontextprotocol.io/specification/draft/basic/authorization/client-registration):\n[Dynamic Client Registration (DCR)](https://www.rfc-editor.org/info/rfc7591/).\n\n## Dynamic Client Registration (DCR)\n\nDCR automates the client registration problem. Instead of requiring a human to\nmanually get an OAuth client, your app *dynamically* provisions one, and then\nimmediately starts the OAuth flow *to this app it had never heard of before*.\nThis is the dream!\n\nAt my startup [Val Town](https://val.town/), we learned about DCR while building\n[our MCP server / plugin](https://docs.val.town/guides/prompting/plugin), which\nis what enables you to OAuth into Val Town from Claude and ChatGPT.\n\nBut the benefits don't end with just Claude and ChatGPT. *Any app* can\ndynamically register an OAuth client with Val Town, and connect to their users'\nVal Town accounts.\n\n## Login with DCR\n\nFor example, on top of this primitive, we created\n[std/oauth](https://www.val.town/x/std/oauth), a middleware library that adds\n\"Login with Val Town\" OAuth to your Val Town app in 2 lines of code. This is\nliterally a whole app:\n\n``` js\n/** @jsxImportSource https://esm.sh/hono/jsx */\nimport { Hono } from \"https://esm.sh/hono\";\nimport {\n  getOAuthUserData,\n  oauthMiddleware,\n} from \"https://esm.town/v/std/oauth/middleware.ts\";\n\nconst app = new Hono();\n\napp.get(\"/\", async (c) => {\n  const session = await getOAuthUserData(c.req.raw);\n\n  return c.html(\n    <html>\n      <body>\n        {session?.user\n          ? <p>Logged in as {session.user.username}</p>\n          : <a href=\"/auth/login\">Log in</a>}\n      </body>\n    </html>,\n  );\n});\n\nexport default oauthMiddleware(app.fetch);\n```\n\nTry it out below:\n\nThere is no extra set up step. If you hit \"remix\" on Val Town, you'll have a copy of that app, and \"Login with Val Town\" authentication will immediately work. Your app's OAuth client to Val Town will be created behind the scenes when the first user logs in.\n\nTo be clear, there's no magic here because Val Town runs both the authorization server and the app's infrastructure. This library could be adapted to run on any infrastructure, and for any authentication provider that supports DCR.\n\nIt gets better.\n\n## Client ID Metadata Documents (CIMD)\n\nDCR, while solving most of the OAuth client registration problem, can be\n[somewhat painful to implement](https://blog.modelcontextprotocol.io/posts/client_registration/#challenge-1-operational-limitations-of-dynamic-client-registration).\n(Paul Carleton from the MCP team\n[explains more here](https://youtu.be/wvtGlur2SdI?t=715).)\n\nEnter\n[Client ID Metadata Documents (CIMD)](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/).\n\nCIMD means you don't have to pre-register an OAuth client at all. Instead you can self-host your OAuth client data at a URL, and then initiate an OAuth flow right away.\n\nFor example, Notion's CIMD link is\n[ https://mcp.notion.com/.well-known/oauth-authorization-server](https://mcp.notion.com/.well-known/oauth-authorization-server),\nwhich returns:\n\n```\n{\n  \"issuer\": \"https://mcp.notion.com\",\n  \"authorization_endpoint\": \"https://mcp.notion.com/authorize\",\n  \"token_endpoint\": \"https://mcp.notion.com/token\",\n  \"registration_endpoint\": \"https://mcp.notion.com/register\",\n  \"scopes_supported\": [\n    \"default\"\n  ],\n  \"response_types_supported\": [\n    \"code\"\n  ],\n  \"response_modes_supported\": [\n    \"query\"\n  ],\n  \"grant_types_supported\": [\n    \"authorization_code\",\n    \"refresh_token\",\n    \"urn:ietf:params:oauth:grant-type:jwt-bearer\"\n  ],\n  \"authorization_grant_profiles_supported\": [\n    \"urn:ietf:params:oauth:grant-profile:id-jag\"\n  ],\n  \"token_endpoint_auth_methods_supported\": [\n    \"client_secret_basic\",\n    \"client_secret_post\",\n    \"none\"\n  ],\n  \"revocation_endpoint\": \"https://mcp.notion.com/token\",\n  \"code_challenge_methods_supported\": [\n    \"plain\",\n    \"S256\"\n  ],\n  \"client_id_metadata_document_supported\": true,\n  \"introspection_endpoint\": \"https://mcp.notion.com/introspect\",\n  \"introspection_endpoint_auth_methods_supported\": [\n    \"client_secret_basic\",\n    \"client_secret_post\",\n    \"none\"\n  ]\n}\n```\n\nAny app that supports CIMD can start an OAuth flow with Notion immediately – whenever a user requests it – even if that app had never heard of Notion before.\n\n## All together now\n\nThousands of apps now support DCR and hundreds support CIMD. I can't remember a time where a new software protocol spreads this quickly. In our rush to all make MCP servers that play with ChatGPT and Claude, we've inadvertently made our apps connectable to each other as well.\n\nSo I took it to the logical extreme, and built this live demo app with 3,613 connectors:\n\n[oauth-demos.val.run](https://oauth-demos.val.run/)\n\nThe mind-blowing part is that if you deploy a copy of this app yourself – ie by\n[clicking \"remix\" here on Val Town](https://www.val.town/x/stevekrouse/oauth-demos)\n– all the connectors will instantly work. You won't need to get a single OAuth\nclient.\n\n## The dream is closer\n\nAs you may have noticed, we're not yet living the dream. Even us at Val Town haven't shipped connectors to all these apps. There are still problems to be solved, mostly stemming from the fact that these new protocols weren't designed to solve this connect-all-the-apps problem.\n\n### Problem #1: Actually supported dynamic registration\n\nMany of these dynamic client registration endpoints aren't truly dynamic. For\nexample, if you try (in my app above) to connect to Google Ads, you'll get this\nerror message: `redirect host not in platform catalog: oauth-demos.val.run`\n\n. In\nother words, they don't support truly dynamic registration; we still need to be\npre-registered in their catalog.\n\n### Problem #2: MCP vs REST API\n\nDCR/CIMD may only work for MCP. It might not authorize you to make normal REST API calls. This is a potentially tricky problem for us at Val Town as a vibe coding platform.\n\nFor example, say you want to build a Stripe dashboard in Val Town. We can easily use DCR to connect you to Stripe via MCP. However, that will not work for their REST API.\n\nThe problem here is more social convention than technical: while you technically\n*can* write code to build a dashboard by calling Stripe's MCP server instead of\nits API server, that's not how you're supposed to interact with an MCP server. I\nbelieve, this is the single core difference between REST API vs MCP: the promise\nof stability. Stripe [in particular](https://stripe.com/blog/api-versioning)\ngoes to great lengths to ensure your REST API calls will always work. That's\nimportant because code is brittle. If the API changes, the code breaks.\n\nHowever, the convention with MCPs is that there is *inference on both sides of\nthe call*. An LLM can read the MCP toolset before invoking them, and if they get\nan error or changed behavior, the LLM can error-correct and make more MCP calls\nuntil it succeeds. By way of metaphor, an MCP server is the AI equivalent of a\nuser interface (UI), because UIs also don't have any promise of stability, and\nfor the same reason: there's inference (a person) on both sides of any action.\nUnlike code, a person notices when in a UI buttons move, or when buttons\nsuddenly do different things, and can error-correct in real time.\n\nOne solution here is that application could allow DCR/CIMD for their API, or allow the tokens obtained through either means work on either surface – given the requisite resource permissions. That's how it works in Val Town currently. Any token you obtain from DCR works both with our MCP and our REST API.\n\n### Problem #3: OSS & Tooling\n\nThere should probably be some sort of public registry of all these\nconnectors. I scraped my list from [mcpservers.org](https://mcpservers.org/).\n\nWe also need good open-source tooling on how to easily connect to them all. Maybe the OSS library could look like the [Zapier SDK](https://zapier.com/sdk),\n[Pipedream Connect](https://pipedream.com/connect), or\n[Nango](https://nango.dev/).\n\n## No clicks, no keys\n\nAs we've seen above, DCR/CIMD allows you to *authorize* to other apps you have accounts at.\n\nBut there's another category of problem: accessing a pay-per-use API that you don't have an account at. Maybe [x402 solves the other half of this problem](https://stevekrouse.com/x402), the *payment* part, so you don't need an account with your credit card attached to immediately be able to pay for premium APIs.\n\nTogether, DCR/CIMD and x402 point towards a future of apps without API keys as env variables. In the age of vibe coding – where generating the whole app takes mere minutes – not having to have a human get and set an API key is a huge reduction in drudgery, and a huge step forward for malleable software.\n\n**We're hiring!**\n\nAre you an infra engineer who cares about the joy of programming?", "url": "https://wpnews.pro/news/connecting-every-app-to-every-other-app", "canonical_source": "https://blog.val.town/connectors", "published_at": "2026-09-02 17:41:38+00:00", "updated_at": "2026-09-02 17:52:49.210804+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-infrastructure"], "entities": ["Val Town", "Zapier", "Anthropic", "OpenAI", "MCP", "Claude", "ChatGPT"], "alternates": {"html": "https://wpnews.pro/news/connecting-every-app-to-every-other-app", "markdown": "https://wpnews.pro/news/connecting-every-app-to-every-other-app.md", "text": "https://wpnews.pro/news/connecting-every-app-to-every-other-app.txt", "jsonld": "https://wpnews.pro/news/connecting-every-app-to-every-other-app.jsonld"}}