mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-31 22:32:28 +00:00
feat: add per-project MCP config overrides (#5406)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
@@ -36,6 +36,18 @@ function getAuthStatusText(status: MCP.AuthStatus): string {
|
||||
}
|
||||
}
|
||||
|
||||
type McpEntry = NonNullable<Config.Info["mcp"]>[string]
|
||||
|
||||
type McpConfigured = Config.Mcp
|
||||
function isMcpConfigured(config: McpEntry): config is McpConfigured {
|
||||
return typeof config === "object" && config !== null && "type" in config
|
||||
}
|
||||
|
||||
type McpRemote = Extract<McpConfigured, { type: "remote" }>
|
||||
function isMcpRemote(config: McpEntry): config is McpRemote {
|
||||
return isMcpConfigured(config) && config.type === "remote"
|
||||
}
|
||||
|
||||
export const McpCommand = cmd({
|
||||
command: "mcp",
|
||||
builder: (yargs) =>
|
||||
@@ -64,15 +76,19 @@ export const McpListCommand = cmd({
|
||||
const mcpServers = config.mcp ?? {}
|
||||
const statuses = await MCP.status()
|
||||
|
||||
if (Object.keys(mcpServers).length === 0) {
|
||||
const servers = Object.entries(mcpServers).filter((entry): entry is [string, McpConfigured] =>
|
||||
isMcpConfigured(entry[1]),
|
||||
)
|
||||
|
||||
if (servers.length === 0) {
|
||||
prompts.log.warn("No MCP servers configured")
|
||||
prompts.outro("Add servers with: opencode mcp add")
|
||||
return
|
||||
}
|
||||
|
||||
for (const [name, serverConfig] of Object.entries(mcpServers)) {
|
||||
for (const [name, serverConfig] of servers) {
|
||||
const status = statuses[name]
|
||||
const hasOAuth = serverConfig.type === "remote" && !!serverConfig.oauth
|
||||
const hasOAuth = isMcpRemote(serverConfig) && !!serverConfig.oauth
|
||||
const hasStoredTokens = await MCP.hasStoredTokens(name)
|
||||
|
||||
let statusIcon: string
|
||||
@@ -110,7 +126,7 @@ export const McpListCommand = cmd({
|
||||
)
|
||||
}
|
||||
|
||||
prompts.outro(`${Object.keys(mcpServers).length} server(s)`)
|
||||
prompts.outro(`${servers.length} server(s)`)
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -138,7 +154,7 @@ export const McpAuthCommand = cmd({
|
||||
|
||||
// Get OAuth-capable servers (remote servers with oauth not explicitly disabled)
|
||||
const oauthServers = Object.entries(mcpServers).filter(
|
||||
([_, cfg]) => cfg.type === "remote" && cfg.oauth !== false,
|
||||
(entry): entry is [string, McpRemote] => isMcpRemote(entry[1]) && entry[1].oauth !== false,
|
||||
)
|
||||
|
||||
if (oauthServers.length === 0) {
|
||||
@@ -163,7 +179,7 @@ export const McpAuthCommand = cmd({
|
||||
const authStatus = await MCP.getAuthStatus(name)
|
||||
const icon = getAuthStatusIcon(authStatus)
|
||||
const statusText = getAuthStatusText(authStatus)
|
||||
const url = cfg.type === "remote" ? cfg.url : ""
|
||||
const url = cfg.url
|
||||
return {
|
||||
label: `${icon} ${name} (${statusText})`,
|
||||
value: name,
|
||||
@@ -187,8 +203,8 @@ export const McpAuthCommand = cmd({
|
||||
return
|
||||
}
|
||||
|
||||
if (serverConfig.type !== "remote" || serverConfig.oauth === false) {
|
||||
prompts.log.error(`MCP server ${serverName} does not support OAuth (oauth is disabled)`)
|
||||
if (!isMcpRemote(serverConfig) || serverConfig.oauth === false) {
|
||||
prompts.log.error(`MCP server ${serverName} is not an OAuth-capable remote server`)
|
||||
prompts.outro("Done")
|
||||
return
|
||||
}
|
||||
@@ -263,7 +279,7 @@ export const McpAuthListCommand = cmd({
|
||||
|
||||
// Get OAuth-capable servers
|
||||
const oauthServers = Object.entries(mcpServers).filter(
|
||||
([_, cfg]) => cfg.type === "remote" && cfg.oauth !== false,
|
||||
(entry): entry is [string, McpRemote] => isMcpRemote(entry[1]) && entry[1].oauth !== false,
|
||||
)
|
||||
|
||||
if (oauthServers.length === 0) {
|
||||
@@ -276,7 +292,7 @@ export const McpAuthListCommand = cmd({
|
||||
const authStatus = await MCP.getAuthStatus(name)
|
||||
const icon = getAuthStatusIcon(authStatus)
|
||||
const statusText = getAuthStatusText(authStatus)
|
||||
const url = serverConfig.type === "remote" ? serverConfig.url : ""
|
||||
const url = serverConfig.url
|
||||
|
||||
prompts.log.info(`${icon} ${name} ${UI.Style.TEXT_DIM}${statusText}\n ${UI.Style.TEXT_DIM}${url}`)
|
||||
}
|
||||
@@ -506,7 +522,7 @@ export const McpDebugCommand = cmd({
|
||||
return
|
||||
}
|
||||
|
||||
if (serverConfig.type !== "remote") {
|
||||
if (!isMcpRemote(serverConfig)) {
|
||||
prompts.log.error(`MCP server ${serverName} is not a remote server`)
|
||||
prompts.outro("Done")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user