Let agents drive the flow API over MCP
Playwright Tests / test-playwright (1, 2) (push) Canceled after 0s
Playwright Tests / test-playwright (2, 2) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Test Backend / test-backend (push) Canceled after 0s
Compose Smoke Test / test-compose (push) Canceled after 0s
Playwright Tests / merge-reports (push) Canceled after 0s
Playwright Tests / test-playwright (1, 2) (push) Canceled after 0s
Playwright Tests / test-playwright (2, 2) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Test Backend / test-backend (push) Canceled after 0s
Compose Smoke Test / test-compose (push) Canceled after 0s
Playwright Tests / merge-reports (push) Canceled after 0s
The engine now speaks MCP at /mcp, with a built-in OAuth 2.1 authorization server in front of it: an agent registers itself, sends a human to the browser to approve it, and exchanges the resulting code for a token. PKCE is required, codes are single-use and stored only as hashes, the browser is redirected to the URI that was registered rather than the one asked for, and refresh tokens rotate so that replaying a spent one revokes the whole line. Twenty tools cover reading, building, publishing and running flows, and each one calls the same REST endpoint the dashboard calls, in-process, carrying the caller's own token. That keeps one description of what a flow is and what may be done to it — validation, the draft/publish split, the version check — and means an agent can do nothing a person could not do in the browser. Agent tokens are RS256 with a keypair of their own rather than the secret that signs browser sessions, so deleting the key withdraws every agent without logging anyone out, and deps.decode_token grew the branch that trusting a second issuer will need when the hosted login arrives. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
3724b68f23
commit
8d82d6c4ec
@@ -16,6 +16,7 @@ import { Route as LoginRouteImport } from './routes/login'
|
||||
import { Route as LayoutRouteImport } from './routes/_layout'
|
||||
import { Route as CanvasRouteImport } from './routes/_canvas'
|
||||
import { Route as LayoutIndexRouteImport } from './routes/_layout/index'
|
||||
import { Route as OauthAuthorizeRouteImport } from './routes/oauth.authorize'
|
||||
import { Route as LayoutSettingsRouteImport } from './routes/_layout/settings'
|
||||
import { Route as LayoutAdminRouteImport } from './routes/_layout/admin'
|
||||
import { Route as CanvasFlowsIndexRouteImport } from './routes/_canvas/flows/index'
|
||||
@@ -54,6 +55,11 @@ const LayoutIndexRoute = LayoutIndexRouteImport.update({
|
||||
path: '/',
|
||||
getParentRoute: () => LayoutRoute,
|
||||
} as any)
|
||||
const OauthAuthorizeRoute = OauthAuthorizeRouteImport.update({
|
||||
id: '/oauth/authorize',
|
||||
path: '/oauth/authorize',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const LayoutSettingsRoute = LayoutSettingsRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
@@ -83,6 +89,7 @@ export interface FileRoutesByFullPath {
|
||||
'/signup': typeof SignupRoute
|
||||
'/admin': typeof LayoutAdminRoute
|
||||
'/settings': typeof LayoutSettingsRoute
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/flows/': typeof CanvasFlowsIndexRoute
|
||||
}
|
||||
@@ -94,6 +101,7 @@ export interface FileRoutesByTo {
|
||||
'/signup': typeof SignupRoute
|
||||
'/admin': typeof LayoutAdminRoute
|
||||
'/settings': typeof LayoutSettingsRoute
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/flows': typeof CanvasFlowsIndexRoute
|
||||
}
|
||||
@@ -107,6 +115,7 @@ export interface FileRoutesById {
|
||||
'/signup': typeof SignupRoute
|
||||
'/_layout/admin': typeof LayoutAdminRoute
|
||||
'/_layout/settings': typeof LayoutSettingsRoute
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/_layout/': typeof LayoutIndexRoute
|
||||
'/_canvas/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/_canvas/flows/': typeof CanvasFlowsIndexRoute
|
||||
@@ -121,6 +130,7 @@ export interface FileRouteTypes {
|
||||
| '/signup'
|
||||
| '/admin'
|
||||
| '/settings'
|
||||
| '/oauth/authorize'
|
||||
| '/flows/$flowName'
|
||||
| '/flows/'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
@@ -132,6 +142,7 @@ export interface FileRouteTypes {
|
||||
| '/signup'
|
||||
| '/admin'
|
||||
| '/settings'
|
||||
| '/oauth/authorize'
|
||||
| '/flows/$flowName'
|
||||
| '/flows'
|
||||
id:
|
||||
@@ -144,6 +155,7 @@ export interface FileRouteTypes {
|
||||
| '/signup'
|
||||
| '/_layout/admin'
|
||||
| '/_layout/settings'
|
||||
| '/oauth/authorize'
|
||||
| '/_layout/'
|
||||
| '/_canvas/flows/$flowName'
|
||||
| '/_canvas/flows/'
|
||||
@@ -156,6 +168,7 @@ export interface RootRouteChildren {
|
||||
RecoverPasswordRoute: typeof RecoverPasswordRoute
|
||||
ResetPasswordRoute: typeof ResetPasswordRoute
|
||||
SignupRoute: typeof SignupRoute
|
||||
OauthAuthorizeRoute: typeof OauthAuthorizeRoute
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
@@ -209,6 +222,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof LayoutIndexRouteImport
|
||||
parentRoute: typeof LayoutRoute
|
||||
}
|
||||
'/oauth/authorize': {
|
||||
id: '/oauth/authorize'
|
||||
path: '/oauth/authorize'
|
||||
fullPath: '/oauth/authorize'
|
||||
preLoaderRoute: typeof OauthAuthorizeRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_layout/settings': {
|
||||
id: '/_layout/settings'
|
||||
path: '/settings'
|
||||
@@ -275,6 +295,7 @@ const rootRouteChildren: RootRouteChildren = {
|
||||
RecoverPasswordRoute: RecoverPasswordRoute,
|
||||
ResetPasswordRoute: ResetPasswordRoute,
|
||||
SignupRoute: SignupRoute,
|
||||
OauthAuthorizeRoute: OauthAuthorizeRoute,
|
||||
}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
|
||||
Reference in New Issue
Block a user