一键导入
iblai-vibe-agent-tool
Add the agent Tools tab (enable/disable agent tools) to your Next.js app
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Add the agent Tools tab (enable/disable agent tools) to your Next.js app
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Build and run your ibl.ai app on desktop and mobile (iOS, Android, macOS, Surface)
Add the agent Sandbox tab (OpenClaw instance management, agent prompt configuration, and agent skills) to your Next.js app
Add the agent Access tab (role-based access control for editor and chat roles) to your Next.js app
Add the agent Audit tab (audit log of who changed what and when, with user/date/action filters) to your Next.js app
Wrap the Chat surface with the SDK's AppSidebar — projects dropdown, pinned/recent messages, and host-supplied content/footer menu items
Add the in-process Chat SDK component (full agent surface — message stream, canvas, file attach, voice, prompts) to a Next.js app
| name | iblai-vibe-agent-tool |
| description | Add the agent Tools tab (enable/disable agent tools) to your Next.js app |
| globs | null |
| alwaysApply | false |
Add the agent Tools tab -- a toggleable list of agent tools with
display names, descriptions in tooltips, and switches for enabling or
disabling each tool. This is one tab in the wider agent-settings family.
All tabs share the same AgentSettingsProvider wrapper.

Do NOT add custom styles, colors, or CSS overrides to ibl.ai SDK components. They ship with their own styling. Keep the components as-is. Do NOT implement dark mode unless the user explicitly asks for it.
When building custom UI around SDK components, use the ibl.ai brand:
#0058cc, Gradient: linear-gradient(135deg, #00b0ef, #0058cc)bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white@iblai/iblai-js) first, then shadcn/ui for everything else
(npx shadcn@latest add <component>). Do NOT write custom components
when an ibl.ai or shadcn equivalent exists. Both share the same
Tailwind theme and render in ibl.ai brand colors automatically.You MUST run /iblai-vibe-ops-test before telling the user the work is ready.
After all work is complete, start a dev server (pnpm dev) so the user
can see the result at http://localhost:3000.
iblai.env is NOT a .env.local replacement — it only holds the 3
shorthand variables (DOMAIN, PLATFORM, TOKEN). Next.js still reads
its runtime env vars from .env.local.
Use pnpm as the default package manager. Fall back to npm if pnpm
is not installed.
Common setup (brand, conventions, env files, verification): see docs/skill-setup.md.
/iblai-vibe-auth)@iblai/mcp in .mcp.json)AgentSettingsProvider must wrap the route (see /iblai-vibe-agent-setting
Step 2 if not already set up)mentorId (agent UUID). Do NOT invent one.Before proceeding, check for an iblai.env in the project root. Look for
PLATFORM, DOMAIN, and TOKEN variables. If the file does not exist or
is missing these variables, tell the user:
"You need an iblai.env with your platform configuration. Download the
template and fill in your values:
curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env"
AgentToolsTab// app/(app)/agents/[mentorId]/tools/page.tsx
"use client";
import { AgentToolsTab } from "@iblai/iblai-js/web-containers/next";
export default function AgentToolsPage() {
return (
<div className="flex h-full flex-col bg-white">
<AgentToolsTab />
</div>
);
}
import { AgentToolsTab } from "@iblai/iblai-js/web-containers/next";
<AgentToolsTab
labels={{
header: { title: "Mentor tools" },
}}
/>;
get_component_info("AgentToolsTab")
get_component_info("AgentSettingsProvider")
<AgentToolsTab> PropsImport from @iblai/iblai-js/web-containers/next.
| Prop | Type | Required | Description |
|---|---|---|---|
labels | DeepPartial<ToolsTabLabels> | No | Override user-visible strings |
From @iblai/iblai-js/web-containers/next:
AGENT_TOOLS_TAB_LABELS -- the default agent-facing label bundle.ToolsTabLabels -- type for the full label bundle.Run /iblai-vibe-ops-test before telling the user the work is ready:
pnpm build -- must pass with zero errorspnpm test -- vitest must passpnpm dev &
npx playwright screenshot http://localhost:3000/agents/<id>/tool /tmp/agent-tool.png
mentorReducer and mentorMiddlewareinitializeDataLayer(): 5 args (v1.2+)@reduxjs/toolkit: Deduplicated via webpack aliases in next.config.tssonner and @iblai/iblai-web-mentor must be installed
(pnpm add sonner @iblai/iblai-web-mentor)AgentSettingsProvider must wrap the route at a
layout level. See /iblai-vibe-agent-setting Step 2 for the full snippet.For custom UI beyond <AgentToolsTab> — register external MCP servers and
bind them to agents. All endpoints are prefixed with
${dmUrl}/api/ai-mentor/orgs/{org}/users/{user_id}/ where dmUrl is
NEXT_PUBLIC_API_BASE_URL. Tenant admins only.
platform, user,
or mentor).| Method | Path | Body |
|---|---|---|
| PUT | mentors/{mentor_id}/settings/ | { "tools": ["mcp-tool", ...] } |
The tools array replaces the existing list. Pass null to leave
unchanged; [] clears all tools.
| Method | Path | Purpose |
|---|---|---|
| GET | mcp-servers/ | List tenant servers |
| POST | mcp-servers/ | Register a new server |
| PATCH/PUT | mcp-servers/{id}/ | Update |
| DELETE | mcp-servers/{id}/ | Delete |
| GET | mcp-servers/oauth-find/ | Find a server by OAuth provider/service |
Create body:
{
"name": "Google Drive MCP",
"description": "Search and index Drive documents",
"url": "https://drive-mcp.example.com",
"transport": "sse",
"auth_type": "oauth2",
"is_featured": false,
"is_enabled": true
}
transport: sse | websocket | streamable_httpauth_type: none | token | oauth2 — how credentials are presentedauth_scope: platform (default) | mentor | user — whose
credentials are used. auth_type=oauth2 + auth_scope=user triggers
the in-chat OAuth handshake (see In-Chat MCP Events below).auth_type=token, set credentials to the full header value
(e.g. "Bearer abc123").| Method | Path | Purpose |
|---|---|---|
| GET | mcp-server-connections/ | List connections |
| POST | mcp-server-connections/ | Create a connection |
| PATCH/PUT | mcp-server-connections/{id}/ | Update / toggle is_active |
| DELETE | mcp-server-connections/{id}/ | Delete |
Token (platform scope):
{
"server": 9,
"scope": "platform",
"auth_type": "token",
"credentials": "Token super-secret",
"authorization_scheme": "Token",
"extra_headers": { "x-mcp-client": "mentor-ui" }
}
OAuth (user scope) — requires an existing ConnectedService (see the
OAuth connectors flow):
{
"server": 9,
"scope": "user",
"auth_type": "oauth2",
"user": "alice",
"connected_service": 77
}
Agent scope — bind credentials to a single agent while keeping the server reusable:
{
"server": 9,
"scope": "mentor",
"auth_type": "token",
"mentor": 123,
"credentials": "Token scoped-to-mentor",
"authorization_scheme": "Token"
}
Returned credentials are masked (e.g. "******90"); only send a new
value when the user intentionally rotates the secret.
| Method | Path | Body |
|---|---|---|
| PUT | mentors/{mentor}/settings/ | { "mcp_servers": [1, 2] } |
The mcp_servers array replaces the agent's current list. Pass null to
leave unchanged; [] clears all servers.
is_featured=true global platform)400 Selected MCP server is not available to the current tenant. — the
server belongs to another tenant and is not is_featured=true.400 OAuth2 connections require a connected service. — create the OAuth
connector first and pass connected_service.auth_typenone: informational only.token: inputs for credentials, authorization_scheme, optional
header key–value pairs.oauth2: ConnectedService picker filtered by provider/service. Hide
the Connect action until OAuth is completed, otherwise the API returns
400.For OAuth-backed MCP servers (auth_type=oauth2), each user must grant
permission once per provider/service before a connection can reference a
ConnectedService. All endpoints are under ${dmUrl}/api/accounts/. Auth:
Authorization: Token {token}.
| Method | Path | Purpose |
|---|---|---|
| GET | orgs/{org}/oauth-services/ | List enabled services across all providers |
| GET | orgs/{org}/oauth-services/{service_name}/scopes/ | Per-service scope breakdown |
| GET | connected-services/orgs/{org}/users/{user_id}/{provider}/{service}/ | Start flow — returns { auth_url } |
| GET | connected-services/callback/?code=...&state=... | Handle vendor redirect; persists ConnectedService |
| GET | connected-services/orgs/{org}/users/{user_id}/ | List the user's connected services |
| DELETE | connected-services/orgs/{org}/users/{user_id}/{id}/ | Revoke a connection |
auth_url in a new window/tab.redirect_uri; relay
code + state to the callback endpoint without modification.ConnectedService (id, provider, service,
expires_at, scope). Tokens auto-refresh server-side.Tenant admin must store auth_{provider} credentials with client_id,
client_secret, and redirect_uri in the credential store. A start
endpoint returning 400 "No credentials found" means this is missing.
400 "No credentials found" — admin must configure auth_{provider}.Invalid state — start and callback ran in different browser contexts
or state expired (>60 min).Could not exchange auth token — provider rejected the code; verify
redirect_uri matches.When auth_type=oauth2 + auth_scope=user and no user-scoped
MCPServerConnection exists, the chat consumer pauses the active session
and emits events on the existing chat socket. Parse JSON, switch on
type.
oauth_requiredBackend is about to call an MCP server with no user connection. Show
auth_url to the user; the backend now polls every 10s.
{
"type": "oauth_required",
"server_name": "Google Drive MCP",
"server_id": 42,
"auth_url": "https://accounts.google.com/o/oauth2/v2/auth?...",
"message": "Authentication required for MCP server '...'."
}
UI: open auth_url in a popup/new tab (providers block framing). Show a
"waiting" indicator. Do NOT close the chat socket — resolution arrives on
the same connection.
oauth_connection_resolvedPolling detected the new connection; chat resumes automatically.
{ "type": "oauth_connection_resolved", "server_name": "...", "server_id": 42, "message": "..." }
UI: dismiss the prompt. Optionally toast success.
mcp_tools_retrievedA tool fetch failed but a retry succeeded (up to 3 retries with 1s/2s/4s backoff). Informational only.
{ "type": "mcp_tools_retrieved", "session_id": "...", "mentor_id": "..." }
warningNon-OAuth MCP failure (server unreachable, bad config, retries exhausted). Chat continues without MCP tools.
{ "type": "warning", "message": "...", "developer_error": "...", "code": 503 }
UI: non-blocking banner using message. Log developer_error (do NOT
show to end users).
error (ChatValidationError)Terminates the turn. Three MCP-related cases:
MCP_OAUTH_MAX_WAIT_SECONDS =
300s).ConnectedService).{ "error": "Timed out waiting for OAuth authentication...", "status_code": 400 }
UI: display error (already user-safe). Offer Retry. WebSocket transports
close after this; if the user finishes OAuth after the timeout, their next
message will succeed because the connection is now in place.
| Constant | Value |
|---|---|
MCP_OAUTH_MAX_WAIT_SECONDS | 300 (5 min) |
MCP_OAUTH_POLL_INTERVAL_SECONDS | 10 |