@@ -57,6 +57,7 @@ import {
5757 pluginContractError ,
5858 resolvePluginGenerationSloWindowMs ,
5959 validateExternalPluginContext ,
60+ validatePluginRequestId ,
6061 validatePluginWorkflowId ,
6162} from './mcp-observability.js' ;
6263
@@ -67,7 +68,7 @@ const OPEN_DESIGN_BRIEF_APP_RESOURCE =
6768 'ui://open-design/artifact-card-v6.html' ;
6869
6970export const MCP_SERVER_INSTRUCTIONS = [
70- 'Use only these product names in user-facing replies: Open Design Cloud, Local Codex, and Secure BYOK .' ,
71+ 'Use only these product names in user-facing replies: Open Design Cloud and Local Codex .' ,
7172 'Tool names, runtime ids, endpoints, and correlation values are machine protocol. Never repeat them as product copy.' ,
7273] . join ( '\n' ) ;
7374
@@ -84,7 +85,7 @@ interface ProjectPayload { project?: ProjectSummary; id?: string; name?: string;
8485interface ActiveContext { active ?: boolean ; projectId ?: string ; projectName ?: string | null ; fileName ?: string | null ; ageMs ?: number | null }
8586type ResolvedProject = { id : string ; name : string ; source : 'uuid' | 'id' | 'exact' | 'slug' | 'substring' } ;
8687interface ProjectListCache { baseUrl : string ; t : number ; list : ProjectSummary [ ] }
87- interface McpArgs extends JsonObject { project ?: unknown ; entry ?: unknown ; include ?: unknown ; maxBytes ?: unknown ; path ?: unknown ; offset ?: unknown ; limit ?: unknown ; since ?: unknown ; query ?: unknown ; pattern ?: unknown ; max ?: unknown ; name ?: unknown ; content ?: unknown ; encoding ?: unknown ; artifactManifest ?: unknown ; confirm ?: unknown ; prompt ?: unknown ; plugin ?: unknown ; inputs ?: unknown ; agent ?: unknown ; model ?: unknown ; serviceTier ?: unknown ; byokProfile ?: unknown ; apiKey ?: unknown ; requestId ?: unknown ; resume ?: unknown ; runId ?: unknown ; id ?: unknown ; designSystem ?: unknown ; skill ?: unknown ; includeUnavailable ?: unknown ; artifactType ?: unknown ; projectTitle ?: unknown ; locale ?: unknown ; knownAnswers ?: unknown ; skip ?: unknown ; briefDraftId ?: unknown ; nonce ?: unknown ; answers ?: unknown ; externalPluginContext ?: unknown ; pluginWorkflowId ?: unknown }
88+ interface McpArgs extends JsonObject { project ?: unknown ; entry ?: unknown ; include ?: unknown ; maxBytes ?: unknown ; path ?: unknown ; offset ?: unknown ; limit ?: unknown ; since ?: unknown ; query ?: unknown ; pattern ?: unknown ; max ?: unknown ; name ?: unknown ; content ?: unknown ; encoding ?: unknown ; artifactManifest ?: unknown ; confirm ?: unknown ; prompt ?: unknown ; plugin ?: unknown ; inputs ?: unknown ; agent ?: unknown ; model ?: unknown ; serviceTier ?: unknown ; apiKey ?: unknown ; requestId ?: unknown ; resume ?: unknown ; runId ?: unknown ; id ?: unknown ; designSystem ?: unknown ; skill ?: unknown ; includeUnavailable ?: unknown ; artifactType ?: unknown ; projectTitle ?: unknown ; locale ?: unknown ; knownAnswers ?: unknown ; skip ?: unknown ; briefDraftId ?: unknown ; nonce ?: unknown ; answers ?: unknown ; externalPluginContext ?: unknown ; pluginWorkflowId ?: unknown }
8889interface ProjectFileBundleEntry { name : string ; mime : string ; size : number | null ; content : string | null ; binary : boolean }
8990interface BundleInput { project : ProjectPayload | ProjectSummary ; entry : string ; files : ProjectFileBundleEntry [ ] ; truncated : boolean ; skippedFileCount ?: number ; active : ActiveContext | null ; resolved ?: ResolvedProject | null }
9091interface ErrorWithCode { message ?: string ; code ?: string ; cause ?: { code ?: string } }
@@ -616,17 +617,6 @@ export const TOOL_DEFS = [
616617 } ,
617618 annotations : { ...READ_ANNOTATIONS , title : 'List Open Design plugins' } ,
618619 } ,
619- {
620- name : 'list_byok_profiles' ,
621- description :
622- 'List secure local BYOK profile references available to start_run.byokProfile. Returns only non-secret metadata; API keys never cross MCP.' ,
623- inputSchema : {
624- type : 'object' ,
625- properties : { pluginWorkflowId : PLUGIN_WORKFLOW_ID_ARG } ,
626- additionalProperties : false ,
627- } ,
628- annotations : { ...READ_ANNOTATIONS , title : 'List secure BYOK profiles' } ,
629- } ,
630620 {
631621 name : 'start_vela_login' ,
632622 description :
@@ -695,15 +685,10 @@ export const TOOL_DEFS = [
695685 type : 'string' ,
696686 description : "Service tier override for the selected model, e.g. 'priority' for Codex Fast. Optional." ,
697687 } ,
698- byokProfile : {
699- type : 'string' ,
700- description :
701- 'Secure profile id from list_byok_profiles. Selects the local BYOK OpenCode runtime; raw API keys are never accepted by MCP.' ,
702- } ,
703688 requestId : {
704689 type : 'string' ,
705690 description :
706- 'Stable id for this confirmed generation action. Generate it once before calling start_run and reuse it verbatim if the tool response is lost or retried; a different payload with the same id is rejected.' ,
691+ 'Stable canonical UUID or ULID for this confirmed generation action. Generate it once before calling start_run and reuse it verbatim if the tool response is lost or retried; a different payload with the same id is rejected.' ,
707692 } ,
708693 resume : {
709694 type : 'boolean' ,
@@ -849,7 +834,7 @@ export function localMcpResourceDefinitions() {
849834 name : 'Open Design brief' ,
850835 title : 'Choose the artifact direction' ,
851836 description :
852- 'Interactive local Open Design brief card shared by Open Design Cloud, Local Codex, and Secure BYOK modes.' ,
837+ 'Interactive local Open Design brief card shared by Open Design Cloud and Local Codex modes.' ,
853838 mimeType : 'text/html;profile=mcp-app' ,
854839 _meta : {
855840 ui : {
@@ -1271,7 +1256,7 @@ function mcpFailureFacts(
12711256 const failureStage =
12721257 name === 'collect_brief' || name === 'confirm_brief'
12731258 ? 'brief'
1274- : name . includes ( 'vela_login' ) || name === 'list_byok_profiles'
1259+ : name . includes ( 'vela_login' )
12751260 ? 'auth'
12761261 : name . includes ( 'project' )
12771262 ? 'project'
@@ -1622,12 +1607,9 @@ export async function runMcpStdio({ daemonUrl }: RunMcpOptions): Promise<void> {
16221607 ' - collect_brief first for a new artifact unless the user explicitly' ,
16231608 ' asks to skip questions. Let the user complete the rendered card;' ,
16241609 ' confirm_brief returns the readable brief to reuse with Open Design' ,
1625- ' Cloud, Local Codex, or Secure BYOK . Never print or ask the user to copy' ,
1610+ ' Cloud or Local Codex . Never print or ask the user to copy' ,
16261611 ' briefDraftId, nonce, or any other internal correlation value.' ,
16271612 ' - list_skills / list_plugins to see what you can ask OD to make.' ,
1628- ' - list_byok_profiles returns secure local credential references when' ,
1629- ' the user explicitly chooses Secure BYOK. Never request or pass a' ,
1630- ' raw API key through MCP; pass only start_run.byokProfile.' ,
16311613 ' - for Open Design Cloud, call the Cloud login-status tool first.' ,
16321614 ' If signed out, call the Cloud sign-in tool once, show its activation' ,
16331615 ' URL/code when present, and poll login status until loggedIn:true.' ,
@@ -1639,8 +1621,9 @@ export async function runMcpStdio({ daemonUrl }: RunMcpOptions): Promise<void> {
16391621 ' generate into; start_run requires an existing project.' ,
16401622 ' - start_run(prompt, requestId, [skill], [plugin], [inputs]) kicks off' ,
16411623 ' generation in the active or named project and returns a runId.' ,
1642- ' Generate requestId once per confirmed user action and reuse the' ,
1643- ' exact same value after a timeout/lost response. Do not call' ,
1624+ ' Generate a canonical UUID or ULID requestId once per confirmed' ,
1625+ ' user action and reuse the exact same value after a timeout/lost' ,
1626+ ' response. Do not call' ,
16441627 ' start_run again while get_run reports the original run in flight.' ,
16451628 ' If get_run returns failureAction:"recharge", show rechargeUrl;' ,
16461629 ' after the user confirms top-up, call the exact original start_run' ,
@@ -2037,8 +2020,6 @@ async function handleMcpToolCall(
20372020 return ok ( await getJson < SkillsPayload > ( `${ baseUrl } /api/skills` ) ) ;
20382021 case 'list_plugins' :
20392022 return ok ( await listPlugins ( baseUrl ) ) ;
2040- case 'list_byok_profiles' :
2041- return ok ( await listByokProfiles ( baseUrl ) ) ;
20422023 case 'list_agents' :
20432024 return ok ( await listAgents ( baseUrl , args . includeUnavailable === true ) ) ;
20442025 case 'start_vela_login' : {
@@ -2263,58 +2244,6 @@ async function listAgents(baseUrl: string, includeUnavailable: boolean): Promise
22632244 return { agents } ;
22642245}
22652246
2266- async function listByokProfiles ( baseUrl : string ) : Promise < JsonObject > {
2267- const payload = await getJson < JsonObject > ( `${ baseUrl } /api/byok/profiles` ) ;
2268- const rawProfiles = Array . isArray ( payload . profiles ) ? payload . profiles : [ ] ;
2269- const profiles = rawProfiles . flatMap ( ( value ) => {
2270- if ( ! value || typeof value !== 'object' || Array . isArray ( value ) ) return [ ] ;
2271- const profile = value as JsonObject ;
2272- if (
2273- typeof profile . id !== 'string'
2274- || typeof profile . label !== 'string'
2275- || typeof profile . protocol !== 'string'
2276- || typeof profile . baseUrl !== 'string'
2277- || typeof profile . model !== 'string'
2278- ) {
2279- return [ ] ;
2280- }
2281- try {
2282- const parsed = new URL ( profile . baseUrl ) ;
2283- if (
2284- ! [ 'http:' , 'https:' ] . includes ( parsed . protocol )
2285- || parsed . username . length > 0
2286- || parsed . password . length > 0
2287- || parsed . search . length > 0
2288- || parsed . hash . length > 0
2289- ) {
2290- return [ ] ;
2291- }
2292- } catch {
2293- return [ ] ;
2294- }
2295- return [ {
2296- id : profile . id ,
2297- label : profile . label ,
2298- protocol : profile . protocol ,
2299- baseUrl : profile . baseUrl ,
2300- model : profile . model ,
2301- ...( typeof profile . apiVersion === 'string'
2302- ? { apiVersion : profile . apiVersion }
2303- : { } ) ,
2304- requiresApiKey : profile . requiresApiKey === true ,
2305- configured : profile . configured === true ,
2306- ...( typeof profile . keyTail === 'string' ? { keyTail : profile . keyTail } : { } ) ,
2307- ...( typeof profile . createdAt === 'number' ? { createdAt : profile . createdAt } : { } ) ,
2308- ...( typeof profile . updatedAt === 'number' ? { updatedAt : profile . updatedAt } : { } ) ,
2309- } ] ;
2310- } ) ;
2311- return {
2312- available : payload . available === true ,
2313- backend : typeof payload . backend === 'string' ? payload . backend : 'unknown' ,
2314- profiles,
2315- } ;
2316- }
2317-
23182247// Derive a valid project id ([A-Za-z0-9._-], <=128) from a display name,
23192248// with a short random suffix so repeated creates with the same name
23202249// don't collide on the daemon's primary key.
@@ -2341,7 +2270,7 @@ async function startRun(
23412270 || containsMcpCredentialField ( args . inputs )
23422271 ) {
23432272 throw new Error (
2344- 'raw API keys are not accepted by Open Design MCP. Save the key through the Open Design UI or `od byok save --api-key-stdin`, then pass only byokProfile .' ,
2273+ 'raw API keys are not accepted by Open Design MCP. Configure Local BYOK in the Open Design UI and start that run from the local product instead .' ,
23452274 ) ;
23462275 }
23472276 const { id, resolved, active } = await resolveProjectArg ( baseUrl , args . project ) ;
@@ -2360,7 +2289,7 @@ async function startRun(
23602289 : randomUUID ( ) ;
23612290 const body : JsonObject = { projectId : id , clientRequestId : requestId } ;
23622291 if ( options . pluginAttribution ) {
2363- validatePluginWorkflowId ( requestId ) ;
2292+ validatePluginRequestId ( requestId ) ;
23642293 const logical = logicalPluginRequestDigest ( requestId ) ;
23652294 body . analyticsHints = {
23662295 entrySurface : 'external_mcp' ,
@@ -2397,18 +2326,6 @@ async function startRun(
23972326 if ( typeof args . serviceTier === 'string' && args . serviceTier . length > 0 ) {
23982327 body . serviceTier = args . serviceTier ;
23992328 }
2400- if ( args . byokProfile !== undefined ) {
2401- requireString ( args . byokProfile , 'byokProfile' ) ;
2402- if (
2403- typeof args . agent === 'string'
2404- && args . agent . length > 0
2405- && args . agent !== 'byok-opencode'
2406- ) {
2407- throw new Error ( 'byokProfile can only be used with the byok-opencode agent.' ) ;
2408- }
2409- body . agentId = 'byok-opencode' ;
2410- body . byokProfileId = args . byokProfile ;
2411- }
24122329 if ( args . inputs !== undefined ) {
24132330 if ( args . inputs === null || typeof args . inputs !== 'object' || Array . isArray ( args . inputs ) ) {
24142331 throw new Error ( 'inputs must be an object' ) ;
0 commit comments