Model Context Protocol (MCP)
カスタム MCP server を作成し、AI agent が標準 MCP protocol 経由でバックエンドツールにアクセスできるようにします。
MCP を使用する理由
AI agent が外部 server でホストされているツールを呼び出す必要がある場合、または MCP-compatible client が検出して呼び出せるツールとして独自のバックエンドロジックを公開したい場合に使用します。
MCP がなければ、agent とツールの接続ごとにカスタム integration ロジックを構築する必要があります。MCP を使用すると、server 上でツールを定義でき、互換性のある agent は標準 protocol を通じてそれらを検出・呼び出しできます。
- TypeScript
- Python
// Backend: define an MCP server with a tool
@mcpServer({
name: 'weather',
id: 'weather',
description: 'Provides weather data',
version: '1.0.0',
})
export class WeatherMcpService extends SquidService {
@mcpTool({
description: 'Returns the current weather for a city',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name' },
},
required: ['city'],
},
})
async getWeather({ city }: { city: string }): Promise<string> {
return `The weather in ${city} is sunny, 25°C.`;
}
}
# Backend: define an MCP server with a tool
@mcp_server({
'name': 'weather',
'id': 'weather',
'description': 'Provides weather data',
'version': '1.0.0',
})
class WeatherMcpService(SquidService):
@mcp_tool({
'description': 'Returns the current weather for a city',
'inputSchema': {
'type': 'object',
'properties': {
'city': {'type': 'string', 'description': 'City name'},
},
'required': ['city'],
},
})
async def get_weather(self, args: dict) -> str:
return f"The weather in {args['city']} is sunny, 25°C."
これで、MCP-compatible AI agent は標準 protocol を通じて weather ツールを検出・呼び出しできるようになります。
概要
MCP (Model Context Protocol) は、AI agent が外部 server 上のツールを検出・呼び出す方法を標準化する open protocol です。Squid はバックエンドでの MCP server 作成を組み込みでサポートしており、agent が JSON-RPC 経由で呼び出せる decorated method としてツールを定義できます。
MCP を使用する場合
| ユースケース | 推奨事項 |
|---|---|
| 任意の MCP-compatible agent にバックエンドツールを公開する | MCP server |
| MCP client に Squid agent 全体を公開する | agent を MCP server として公開するを参照 |
| 会話中に agent がカスタム server-side ロジックを必要とする | AI functionsを使用 |
| agent が外部 MCP server 上のツールを呼び出す必要がある | MCP connectorを使用 |
| agent が接続済み service(CRM、API など)にアクセスする必要がある | connected integrationを使用 |
仕組み
SquidServiceを拡張する service 内で、class を@mcpServerで decorate します- その class 内の method に
@mcpToolを使用して server にツールを追加します - Squid は deploy 時に MCP server を登録し、JSON-RPC endpoint として公開します
- MCP-compatible client は接続して
tools/list経由で利用可能なツールを検出し、tools/call経由で呼び出します - 任意で、アクセスを制御するために OAuth を有効化するか、
@mcpAuthorizermethod を追加します
クイックスタート
前提条件
- TypeScript
- Python
ステップ 1: ツールを持つ MCP server を作成する
SquidService を拡張する service class を作成し、@mcpServer で decorate して、ツールを追加します。
- TypeScript
- Python
import { mcpServer, mcpTool, SquidService } from '@squidcloud/backend';
@mcpServer({
name: 'greetingServer',
id: 'greetingServer',
description: 'A simple MCP server that greets users',
version: '1.0.0',
})
export class McpService extends SquidService {
@mcpTool({
description: 'Returns a greeting for the given name',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: 'The name to greet' },
},
required: ['name'],
},
})
async greet({ name }: { name: string }): Promise<string> {
return `Hello, ${name}!`;
}
}
from squidcloud_backend import SquidService, mcp_server, mcp_tool
@mcp_server({
'name': 'greetingServer',
'id': 'greetingServer',
'description': 'A simple MCP server that greets users',
'version': '1.0.0',
})
class McpService(SquidService):
@mcp_tool({
'description': 'Returns a greeting for the given name',
'inputSchema': {
'type': 'object',
'properties': {
'name': {'type': 'string', 'description': 'The name to greet'},
},
'required': ['name'],
},
})
async def greet(self, args: dict) -> str:
return f"Hello, {args['name']}!"
Python のツール method は、TypeScript のような destructured object ではなく、inputSchema の properties に一致する単一の args: dict を受け取ります。
ステップ 2: service を登録する
- TypeScript
- Python
service が service index file から export されていることを確認します。
export * from './mcp-service';
個別の登録手順は不要です。Python は module が import されると各 @mcp_server class を自動的に登録するため、class は src/main.py 内に存在するか、そこから import されているだけで十分です。
ステップ 3: backend を deploy する
ローカル開発では、Squid CLI を使用して backend をローカルで実行します。
squid start
cloud へ deploy するには、backend の deployを参照してください。
ステップ 4: MCP server を agent に接続する
deploy 後、MCP server を connector として追加し、agent の abilities に接続します。
- Squid Console で、deploy 済みの MCP server を指す MCP connector を追加します
- Agent Studio で agent の abilities に connector を追加します
これで agent は会話中に MCP ツールを検出・呼び出しできるようになります。
コアコンセプト
@mcpServer decorator
@mcpServer decorator は、SquidService class を MCP server としてマークします。以下の field を持つ configuration object を受け取ります。
| Field | Type | 必須 | 説明 |
|---|---|---|---|
id | string | はい | MCP endpoint URL で使用される一意の identifier |
name | string | はい | MCP manifest で公開される server 名 |
description | string | はい | server の目的を説明します |
version | string | はい | MCP manifest で公開される server version |
oauth | McpOAuthOptions | いいえ | すべての request で OAuth 2.0 bearer token を要求します。OAuth authenticationを参照してください。 |
各 id は、application 内のすべての MCP server で一意である必要があります。ID の重複は deployment error の原因になります。
- TypeScript
- Python
import { mcpServer, SquidService } from '@squidcloud/backend';
@mcpServer({
id: 'inventory',
name: 'inventoryServer',
description: 'Provides product inventory lookup and management tools',
version: '1.0.0',
})
export class InventoryMcpService extends SquidService {
// Tools go here
}
from squidcloud_backend import SquidService, mcp_server
@mcp_server({
'id': 'inventory',
'name': 'inventoryServer',
'description': 'Provides product inventory lookup and management tools',
'version': '1.0.0',
})
class InventoryMcpService(SquidService):
pass # Tools go here
@mcpTool decorator
@mcpTool decorator は、MCP client が検出・呼び出しできるツールとして method を公開します。以下の field を持つ configuration object を受け取ります。
| Field | Type | 必須 | 説明 |
|---|---|---|---|
description | string | はい | ツールの機能と呼び出すタイミングを agent に伝えます |
inputSchema | JSONSchema | はい | ツールの input parameter を定義する JSON Schema |
outputSchema | JSONSchema | いいえ | ツールの output format を説明する JSON Schema |
method 名が MCP manifest 内のツール名になります。各ツール名は server 内で一意である必要があります。
- TypeScript
- Python
@mcpTool({
description: 'Looks up the current stock level for a product by SKU',
inputSchema: {
type: 'object',
properties: {
sku: {
type: 'string',
description: 'The product SKU code',
},
},
required: ['sku'],
},
})
async getStockLevel({ sku }: { sku: string }): Promise<number> {
// Look up the product using your own data layer.
const product = await this.findProduct(sku);
if (!product) {
throw new Error(`Product with SKU ${sku} not found`);
}
return product.stockLevel;
}
@mcp_tool({
'description': 'Looks up the current stock level for a product by SKU',
'inputSchema': {
'type': 'object',
'properties': {
'sku': {
'type': 'string',
'description': 'The product SKU code',
},
},
'required': ['sku'],
},
})
async def get_stock_level(self, args: dict) -> int:
sku = args['sku']
# Look up the product using your own data layer.
product = await self.find_product(sku)
if product is None:
raise RuntimeError(f"Product with SKU {sku} not found")
return product['stockLevel']
Input schema
inputSchema は JSON Schema format に従います。TypeScript ではツール method は schema に一致する properties を持つ単一の destructured object を受け取り、Python では method は単一の args: dict を受け取り、key で各 property を読み取ります。
- TypeScript
- Python
@mcpTool({
description: 'Searches products by category and price range',
inputSchema: {
type: 'object',
properties: {
category: {
type: 'string',
description: 'Product category to search',
enum: ['electronics', 'clothing', 'home', 'sports'],
},
maxPrice: {
type: 'number',
description: 'Maximum price in USD',
},
inStockOnly: {
type: 'boolean',
description: 'If true, only return items currently in stock',
},
},
required: ['category'],
},
})
async searchProducts({
category,
maxPrice,
inStockOnly,
}: {
category: string;
maxPrice?: number;
inStockOnly?: boolean;
}): Promise<string> {
// Query logic here
return JSON.stringify(results);
}
@mcp_tool({
'description': 'Searches products by category and price range',
'inputSchema': {
'type': 'object',
'properties': {
'category': {
'type': 'string',
'description': 'Product category to search',
'enum': ['electronics', 'clothing', 'home', 'sports'],
},
'maxPrice': {
'type': 'number',
'description': 'Maximum price in USD',
},
'inStockOnly': {
'type': 'boolean',
'description': 'If true, only return items currently in stock',
},
},
'required': ['category'],
},
})
async def search_products(self, args: dict) -> str:
category = args['category']
max_price = args.get('maxPrice')
in_stock_only = args.get('inStockOnly')
# Query logic here
return json.dumps(results)
Output schema
任意の outputSchema はツールの戻り値の構造を説明し、client が response format を理解するのに役立ちます。
- TypeScript
- Python
@mcpTool({
description: 'Returns product details for a given SKU',
inputSchema: {
type: 'object',
properties: {
sku: { type: 'string', description: 'Product SKU' },
},
required: ['sku'],
},
outputSchema: {
type: 'object',
properties: {
name: { type: 'string' },
price: { type: 'number' },
inStock: { type: 'boolean' },
},
},
})
async getProduct({ sku }: { sku: string }) {
return { name: 'Widget', price: 9.99, inStock: true };
}
@mcp_tool({
'description': 'Returns product details for a given SKU',
'inputSchema': {
'type': 'object',
'properties': {
'sku': {'type': 'string', 'description': 'Product SKU'},
},
'required': ['sku'],
},
'outputSchema': {
'type': 'object',
'properties': {
'name': {'type': 'string'},
'price': {'type': 'number'},
'inStock': {'type': 'boolean'},
},
},
})
async def get_product(self, args: dict) -> dict:
return {'name': 'Widget', 'price': 9.99, 'inStock': True}
@mcpAuthorizer decorator
@mcpAuthorizer decorator は、MCP server へのすべての request の前に実行される method を指定します。これを使用して、incoming request を検証し、権限のない caller を拒否します。
authorizer method は McpAuthorizationRequest object を受け取り、boolean(または Promise<boolean>)を返す必要があります。request を許可するには true を、"Unauthorized" error で拒否するには false を返します。
- TypeScript
- Python
import { mcpAuthorizer, McpAuthorizationRequest, mcpServer, mcpTool, SquidService } from '@squidcloud/backend';
@mcpServer({
name: 'secureMcp',
id: 'secureMcp',
description: 'An MCP server with authorization',
version: '1.0.0',
})
export class SecureMcpService extends SquidService {
@mcpAuthorizer()
async authorize(request: McpAuthorizationRequest): Promise<boolean> {
const token = request.headers['authorization'];
return token === `Bearer ${this.secrets['MCP_AUTH_TOKEN']}`;
}
@mcpTool({
description: 'Returns sensitive data',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'The data query' },
},
required: ['query'],
},
})
async getSensitiveData({ query }: { query: string }): Promise<string> {
// This tool is only accessible if the authorizer returns true
return `Results for: ${query}`;
}
}
from squidcloud_backend import (
McpAuthorizationRequest,
SquidService,
mcp_authorizer,
mcp_server,
mcp_tool,
)
@mcp_server({
'name': 'secureMcp',
'id': 'secureMcp',
'description': 'An MCP server with authorization',
'version': '1.0.0',
})
class SecureMcpService(SquidService):
@mcp_authorizer()
async def authorize(self, request: McpAuthorizationRequest) -> bool:
headers = request.get('headers') or {}
token = headers.get('authorization')
return token == f"Bearer {self.secrets['MCP_AUTH_TOKEN']}"
@mcp_tool({
'description': 'Returns sensitive data',
'inputSchema': {
'type': 'object',
'properties': {
'query': {'type': 'string', 'description': 'The data query'},
},
'required': ['query'],
},
})
async def get_sensitive_data(self, args: dict) -> str:
# This tool is only accessible if the authorizer returns True
return f"Results for: {args['query']}"
McpAuthorizationRequest field
| Field | Type | 説明 |
|---|---|---|
body | any | parse 済み JSON-RPC request body |
queryParams | Record<string, string> | request URL の query parameter |
headers | Record<string, string> | request の HTTP header |
auth | McpAuthContext | undefined | 検証済み auth context。OAuth validationを通過した request にのみ存在します |
@mcpAuthorizer method が定義されておらず、OAuthも有効でない場合、MCP server へのすべての request が許可されます。
OAuth authentication
Claude やその他の MCP-compatible assistant など、エンドユーザーが使用する MCP client では共有 secret token は実用的ではありません。ユーザーごとに自身の identity で sign in する必要があるためです。@mcpServer に oauth option を追加すると、すべての request で有効な OAuth 2.0 bearer token が必要になります。
import { mcpServer, mcpTool, SquidService } from '@squidcloud/backend';
@mcpServer({
id: 'crm',
name: 'crmServer',
description: 'Provides CRM lookup tools',
version: '1.0.0',
oauth: {
integrationId: 'my-auth0',
},
})
export class CrmMcpService extends SquidService {
// Tools go here
}
McpOAuthOptions には 1 つの field があります。
| Field | Type | 必須 | 説明 |
|---|---|---|---|
integrationId | string | はい | この app に登録されている auth integration の ID |
MCP OAuth は現在、Auth0 auth integration をサポートしており、TypeScript Backend SDK でのみ利用できます。Python の @mcp_server decorator は oauth option を受け付けません。
oauth が設定されると、Squid は OAuth flow の resource-server 側を自動的に処理します。
- 有効な bearer token のない request には、server の protected resource metadata を指す
WWW-Authenticatechallenge を含む HTTP401 Unauthorizedresponse が返されます。 - Squid は
<mcp-server-url>/.well-known/oauth-protected-resourceで OAuth 2.0 Protected Resource Metadata document を公開し、authorization server として Auth0 tenant を一覧表示します。MCP client はこれを検出し、ユーザーを Auth0 login へ自動的に案内します。 - Squid は、参照される integration に対してすべての request の bearer token を検証します。token は Auth0 tenant によって RS256-signed されている必要があり(その JWKS を介して検証)、tenant domain を issuer、integration の client ID を audience とする必要があります。
要求される scope は、openid、profile、email、および offline_access です。
oauth が有効で、かつ @mcpAuthorizer がない場合、integration からの有効な token を含むすべての request が許可されます。
OAuth と authorizer の組み合わせ
特定のユーザーや domain にアクセスを制限するなど、token validation に加えて独自ルールを適用するには、@mcpAuthorizer を追加します。authorizer は OAuth validation 成功後に実行され、検証済み context は request.auth で利用できます。
import { mcpAuthorizer, McpAuthorizationRequest, mcpServer, mcpTool, SquidService } from '@squidcloud/backend';
@mcpServer({
id: 'crm',
name: 'crmServer',
description: 'Provides CRM lookup tools',
version: '1.0.0',
oauth: {
integrationId: 'my-auth0',
},
})
export class CrmMcpService extends SquidService {
@mcpAuthorizer()
async authorize(request: McpAuthorizationRequest): Promise<boolean> {
const email = request.auth?.claims['email'] as string | undefined;
return !!email && email.endsWith('@my-company.com');
}
// Tools go here
}
McpAuthContext field:
| Field | Type | 説明 |
|---|---|---|
type | 'oauth' | この context を生成した auth mechanism |
integrationId | string | request の検証に使用された auth integration の ID |
claims | Record<string, unknown> | 検証済み JWT claims(sub、aud、iss、exp、custom claims) |
検証済み claims は @mcpAuthorizer 内でのみ使用できます。@mcpTool method は input argument のみを受け取ります。ツール内で user ごとの context を想定するのではなく、authorizer で identity-based access を一元的に強制してください。
Error Handling
ツールエラー
ツール method が error を throw すると、MCP server はそれを catch し、isError: true を持つツール response として返します。呼び出し元の agent は error message を受け取り、それを伝達するか、どのように続行するかを判断できます。
agent が有用な feedback を提供できるよう、明確で説明的な error を throw してください。
- TypeScript
- Python
@mcpTool({
description: 'Cancels an order by ID',
inputSchema: {
type: 'object',
properties: {
orderId: { type: 'string', description: 'The order ID to cancel' },
},
required: ['orderId'],
},
})
async cancelOrder({ orderId }: { orderId: string }): Promise<string> {
// Look up the order using your own data layer.
const order = await this.findOrder(orderId);
if (!order) {
throw new Error(`Order ${orderId} not found`);
}
if (order.status === 'shipped') {
throw new Error(`Order ${orderId} has already shipped and cannot be cancelled`);
}
await this.updateOrderStatus(orderId, 'cancelled');
return `Order ${orderId} has been cancelled`;
}
@mcp_tool({
'description': 'Cancels an order by ID',
'inputSchema': {
'type': 'object',
'properties': {
'orderId': {'type': 'string', 'description': 'The order ID to cancel'},
},
'required': ['orderId'],
},
})
async def cancel_order(self, args: dict) -> str:
order_id = args['orderId']
# Look up the order using your own data layer.
order = await self.find_order(order_id)
if order is None:
raise RuntimeError(f"Order {order_id} not found")
if order['status'] == 'shipped':
raise RuntimeError(f"Order {order_id} has already shipped and cannot be cancelled")
await self.update_order_status(order_id, 'cancelled')
return f"Order {order_id} has been cancelled"
Protocol-level error
MCP server は protocol-level の問題に対して標準 JSON-RPC error code を使用します。
| Error Code | 意味 | 原因 |
|---|---|---|
-32001 | Unauthorized | @mcpAuthorizer method が false を返しました |
-32601 | Method not found | 要求された JSON-RPC method またはツール名が存在しません |
-32000 | Server error | MCP server ID が見つからなかったか、internal error が発生しました |
OAuthが有効な場合、bearer token がない、または無効な bearer token を持つ request は、JSON-RPC processing の前に WWW-Authenticate challenge を含む HTTP 401 Unauthorized response で拒否されます。
よくある問題
| 問題 | 原因 | 解決策 |
|---|---|---|
| deployment が ID 重複 error で失敗する | 2 つの @mcpServer class が同じ id を使用している | 各 MCP server に一意の id を使用する |
| deployment がツール名重複で失敗する | 1 つの server 内で 2 つの @mcpTool method が同じ名前を持つ | いずれかの method の名前を変更する |
| agent がツールを一度も呼び出さない | ツール description が user prompt と一致しない | ツールの機能を明確に示すよう description を書き直す |
| authorization が常に失敗する | token または header の check が正しくない | debug のために McpAuthorizationRequest field を log する |
OAuth がすべての request で 401 invalid_token を返す | token の issuer または audience が integration と一致しない | token が integration の Auth0 tenant からのものであることを確認します。audience は integration の client ID である必要があります |
| OAuth-enabled server がすべての request を拒否する | oauth.integrationId が登録済み Auth0 integration を参照していない | app 用の Auth0 integration を登録し、その ID を使用する |
ベストプラクティス
明確なツール description を記述する
description は、agent がツールを呼び出すタイミングを判断する主な手段です。ツールの機能と、返す情報を具体的に記述してください。
Good: 'Returns the current stock level for a product. Use when asked about inventory or availability.'
Bad: 'Gets product info'
Input schema を慎重に設計する
- ツールが parameter なしでは機能しない場合にのみ、parameter を
requiredとしてマークします enumを使用して値を既知の集合に制限します- agent が提供すべき format を理解できるよう、各 property に明確な
descriptionfield を記述します - 適切な JSON Schema type(
string、number、boolean、array、object)を使用します
MCP server を保護する
- server が機密性の高い operation を公開する場合は、必ず
@mcpAuthorizerを追加します - hardcoded value ではなく、保存済み secret に対して authorization token を検証します
- authentication(誰が呼び出しているか)と authorization(何を実行できるか)の両方を確認します
- Claude などの user-facing MCP client には、共有 token よりも OAuth authenticationを優先し、
request.auth?.claimsを介して authorizer 内で user ごとのルールを適用します
ツール input を検証する
input schema は type constraint を提供しますが、edge case を処理するためにツール method 内でも input を検証してください。
- TypeScript
- Python
@mcpTool({
description: 'Transfers funds between accounts',
inputSchema: {
type: 'object',
properties: {
fromAccount: { type: 'string', description: 'Source account ID' },
toAccount: { type: 'string', description: 'Destination account ID' },
amount: { type: 'number', description: 'Amount to transfer in USD' },
},
required: ['fromAccount', 'toAccount', 'amount'],
},
})
async transferFunds({
fromAccount,
toAccount,
amount,
}: {
fromAccount: string;
toAccount: string;
amount: number;
}): Promise<string> {
if (amount <= 0) {
throw new Error('Transfer amount must be positive');
}
if (fromAccount === toAccount) {
throw new Error('Source and destination accounts must be different');
}
// Process transfer...
return `Transferred $${amount} from ${fromAccount} to ${toAccount}`;
}
@mcp_tool({
'description': 'Transfers funds between accounts',
'inputSchema': {
'type': 'object',
'properties': {
'fromAccount': {'type': 'string', 'description': 'Source account ID'},
'toAccount': {'type': 'string', 'description': 'Destination account ID'},
'amount': {'type': 'number', 'description': 'Amount to transfer in USD'},
},
'required': ['fromAccount', 'toAccount', 'amount'],
},
})
async def transfer_funds(self, args: dict) -> str:
from_account = args['fromAccount']
to_account = args['toAccount']
amount = args['amount']
if amount <= 0:
raise RuntimeError('Transfer amount must be positive')
if from_account == to_account:
raise RuntimeError('Source and destination accounts must be different')
# Process transfer...
return f"Transferred ${amount} from {from_account} to {to_account}"
ツールの焦点を絞る
各ツールは 1 つのことを適切に実行するようにしてください。多くの operation を扱う単一のツールよりも、小さく焦点を絞った複数のツールを推奨します。これにより、agent はタスクに適したツールを選択しやすくなります。
agent を MCP server として公開する
ここまででは、あなたの backend ツールから MCP server を構築しました。逆方向も利用可能です。backend code をまったく記述せずに、任意の Squid agent 自体を MCP server として公開できます。server は prompt を agent に転送する単一の ask ツールを公開するため、IDE assistant などの MCP client は、instructions、connectors、knowledge bases がすでに接続された agent に問い合わせできます。
endpoint は、標準 MCP Streamable HTTP transport を介して /mcp/<agentId> で提供されます。
設定には API key が必要なため、backend code から実行してください。
const agent = this.squid.ai().agent('banking-copilot');
// Let Squid draft the descriptions from the agent's instructions and connected resources.
// This returns them without saving, so you can review or edit them first.
const generated = await agent.generateMcpDescriptions();
await agent.updateMcpServer({
enabled: true,
description: generated.description,
toolDescription: generated.toolDescription,
requireApiKey: true,
});
Configuration option
| Field | 説明 |
|---|---|
enabled | agent を MCP server として公開するかどうか。 |
description | MCP initialize result の instructions field として提供されます。デフォルトは agent description です。 |
toolDescription | tools manifest 内の ask ツールの description。デフォルトは汎用的な description です。 |
oauthIntegrationId | auth connector の bearer token を使用して endpoint を OAuth 保護します。 |
requireApiKey | agent 自身の API key を bearer token として要求します。 |
endpoint を保護する
oauthIntegrationId と requireApiKey のどちらも設定されていない場合、MCP endpoint は public です。agent ID を知っている人は誰でもこれを呼び出すことができ、呼び出しのたびに AI quota が消費されます。意図的に公開する agent でない限り、必ず少なくとも一方を設定してください。
requireApiKey を使用する場合、caller は agent の API key を Authorization: Bearer <key> または x-squid-agent-api-key header で提示します。これは application API key ではなく agent-scoped key であるため、その 1 つの agent へのアクセスのみを許可し、それ以外は許可しません。backend code からこれを取得または rotate できます。
const agent = this.squid.ai().agent('banking-copilot');
const key = await agent.getApiKey();
const rotated = await agent.regenerateApiKey();
oauthIntegrationId と requireApiKey の両方を設定すると、いずれかの credential を受け入れます。これにより、interactive client は OAuth で sign in でき、automated client は agent key を提示できます。
次のステップ
- MCP connectors - Squid Console を通じて agent を MCP server に接続する
- Auth0 authentication - MCP OAuth で使用する Auth0 integration をセットアップする
- Abilities - MCP connector やその他のツールを agent に接続する
- AI functions - backend logic を agent に公開する別の方法
- AI agent documentation - AI agent を構築・設定する