Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions app/_components/SubpageList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Link from "next/link";

interface SubpageListProps {
basePath: string;
meta: Record<string, any>;
}

export function SubpageList({ basePath, meta }: SubpageListProps) {
const subpages = Object.entries(meta).filter(([key]) => key !== "index");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SubpageList renders invalid link for theme config key

High Severity

The SubpageList component filters meta entries with key !== "index" but doesn't filter out the "*" key that all meta files use for theme configuration. This causes the component to render a broken link to ${basePath}/* with [object Object] as the link text, since the "*" entry's value ({ theme: { ... } }) lacks a title property and falls through to String(title). All 5 pages using SubpageList will display this broken entry.

Fix in Cursor Fix in Web


return (
<ul className="x:ms-[1.5em] x:not-first:mt-[1.25em] x:list-disc x:[:is(ol,ul)_&]:my-[.75em]">
{subpages.map(([key, title]) => {
const linkText =
typeof title === "string"
? title
: typeof title === "object" && title !== null && "title" in title
? (title as { title: string }).title
: String(title);
return (
<li className="x:my-[.5em]" key={key}>
<Link
className="x:focus-visible:nextra-focus x:text-primary-600 x:underline x:decoration-from-font x:[text-underline-position:from-font] x:hover:no-underline"
href={`${basePath}/${key}`}
>
{linkText}
</Link>
</li>
);
})}
</ul>
);
}
3 changes: 3 additions & 0 deletions app/en/guides/create-tools/_meta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import type { MetaRecord } from "nextra";
export const meta: MetaRecord = {
"tool-basics": {
title: "Build a tool",
href: "/guides/create-tools/tool-basics",
},
"evaluate-tools": {
title: "Evaluate tools",
href: "/guides/create-tools/evaluate-tools",
},
improve: {
title: "Improve an existing toolkit",
Expand All @@ -15,6 +17,7 @@ export const meta: MetaRecord = {
},
"error-handling": {
title: "Handle errors",
href: "/guides/create-tools/error-handling",
},
"migrate-toolkits": {
title: "Migrate from toolkits to MCP servers",
Expand Down
22 changes: 22 additions & 0 deletions app/en/guides/create-tools/error-handling/_meta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { MetaRecord } from "nextra";

const meta: MetaRecord = {
"*": {
theme: {
breadcrumb: true,
toc: true,
copyPage: true,
},
},
index: {
title: "Overview",
},
"retry-tools": {
title: "Retry Tools with Improved Prompt",
},
"useful-tool-errors": {
title: "Provide Useful Tool Errors",
},
};

export default meta;
15 changes: 15 additions & 0 deletions app/en/guides/create-tools/error-handling/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Handle Errors"
description: "Learn how to implement robust error handling in your tools for better user experience"
---

import { SubpageList } from '../../../../_components/SubpageList';
import meta from './_meta';

# Handle Errors

Learn how to implement robust error handling that improves user experience and enables smart retry behavior. Apply these patterns as you develop tools to make them more resilient and user-friendly in production.

Robust error handling is crucial for building reliable tools that provide great user experiences. Arcade provides a comprehensive error handling system that helps you manage different types of errors gracefully.

<SubpageList basePath="/guides/create-tools/error-handling" meta={meta} />
3 changes: 3 additions & 0 deletions app/en/guides/create-tools/evaluate-tools/_meta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const meta: MetaRecord = {
copyPage: true,
},
},
index: {
title: "Overview",
},
"why-evaluate": {
title: "Why evaluate tools?",
},
Expand Down
13 changes: 13 additions & 0 deletions app/en/guides/create-tools/evaluate-tools/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: "Evaluate Tools"
description: "Learn how to systematically test and improve your tools with Arcade's evaluation framework"
---

import { SubpageList } from '../../../../_components/SubpageList';
import meta from './_meta';

# Evaluate Tools

Learn how to systematically test and improve your tools to ensure they work reliably in production. Use these techniques after you've built your initial tools to validate their performance and guide iterative improvements.

<SubpageList basePath="/guides/create-tools/evaluate-tools" meta={meta} />
12 changes: 11 additions & 1 deletion app/en/guides/create-tools/tool-basics/_meta.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import type { MetaRecord } from "nextra";

export const meta: MetaRecord = {
const meta: MetaRecord = {
"*": {
theme: {
breadcrumb: true,
toc: true,
copyPage: true,
},
},
index: {
title: "Overview",
},
"compare-server-types": {
title: "Compare MCP server types",
},
Expand Down
15 changes: 15 additions & 0 deletions app/en/guides/create-tools/tool-basics/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Build a Tool"
description: "Learn the fundamentals of building tools with Arcade's MCP Server framework"
---

import { SubpageList } from '../../../../_components/SubpageList';
import meta from './_meta';

# Build a Tool

Learn how to create custom tools that extend AI agents with powerful capabilities. Start here when you're ready to build your first tool or need to add new functionality to your existing MCP servers.

Building tools with Arcade allows you to extend AI agents with custom capabilities. This section covers everything you need to know about creating powerful, reusable tools using the Model Context Protocol (MCP).

<SubpageList basePath="/guides/create-tools/tool-basics" meta={meta} />
25 changes: 25 additions & 0 deletions app/en/guides/security/_meta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { MetaRecord } from "nextra";

const meta: MetaRecord = {
"*": {
theme: {
breadcrumb: true,
toc: true,
copyPage: true,
},
},
index: {
title: "Overview",
},
"securing-arcade-mcp": {
title: "Securing Arcade MCP",
},
"secure-your-mcp-server": {
title: "Secure your MCP server",
},
"security-research-program": {
title: "Security research program",
},
};

export default meta;
15 changes: 15 additions & 0 deletions app/en/guides/security/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Security"
description: "Learn about security best practices for MCP servers and Arcade tools, plus information about our security research program"
---

import { SubpageList } from '../../../_components/SubpageList';
import meta from './_meta';

# Security

Learn about security best practices for building and deploying secure MCP servers and Arcade tools. Use these resources when implementing production-ready tools that handle sensitive data or require robust security measures.

Security is crucial when building tools that interact with external services, handle user data, or operate in production environments. Arcade provides comprehensive security guidance and actively maintains a security research program.

<SubpageList basePath="/guides/security" meta={meta} />
12 changes: 11 additions & 1 deletion app/en/guides/tool-calling/custom-apps/_meta.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import type { MetaRecord } from "nextra";

export const meta: MetaRecord = {
const meta: MetaRecord = {
"*": {
theme: {
breadcrumb: true,
toc: true,
copyPage: true,
},
},
index: {
title: "Overview",
},
"auth-tool-calling": {
title: "Authorize tool calling",
},
Expand Down
15 changes: 15 additions & 0 deletions app/en/guides/tool-calling/custom-apps/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "In Custom Applications"
description: "Learn how to integrate Arcade tools into your custom applications with authentication and tool management"
---

import { SubpageList } from '../../../../_components/SubpageList';
import meta from './_meta';

# In Custom Applications

Learn how to integrate Arcade tools into your custom applications. Use these guides when building your own tool-calling interfaces and need to handle authentication, status checking, and tool definitions programmatically.

Building custom applications with Arcade tools requires understanding how to manage user authentication, check authorization status, and retrieve properly formatted tool definitions for your specific use case.

<SubpageList basePath="/guides/tool-calling/custom-apps" meta={meta} />
73 changes: 73 additions & 0 deletions app/en/guides/tool-calling/mcp-clients/MCPClientGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use client";
import Link from "next/link";
import meta from "./_meta";

// MCP Client data with logos and descriptions
const mcpClients = [
{
key: "cursor",
name: "Cursor",
description: "AI-powered code editor with built-in MCP support",
},
{
key: "claude-desktop",
name: "Claude Desktop",
description: "Anthropic's desktop app for Claude with MCP integration",
},
{
key: "visual-studio-code",
name: "Visual Studio Code",
description: "Microsoft's code editor with MCP extensions",
},
];

// Logo mapping
const logoSrc = {
cursor: "/images/icons/cursor.png",
"claude-desktop": "/images/icons/claude.png",
"visual-studio-code": "/images/icons/vscode.svg",
};

export function MCPClientGrid() {
const subpages = Object.entries(meta).filter(([key]) => key !== "index");

return (
<div className="mt-6 grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 md:gap-5 lg:grid-cols-3">
{mcpClients.map((client) => {
const clientMeta = subpages.find(([key]) => key === client.key);
if (!clientMeta) return null;

return (
<Link
href={`/guides/tool-calling/mcp-clients/${client.key}`}
key={client.key}
>
<div className="flex h-full flex-col gap-1.5 rounded-xl border border-blue-600/20 bg-blue-600/[0.02] py-3 text-card-foreground shadow-sm backdrop-blur-sm transition-all duration-300 hover:border-primary hover:bg-blue-600/[0.03] hover:shadow-lg dark:bg-gray-900/80">
<div className="@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6">
<div className="flex flex-wrap items-start justify-between gap-2">
<div className="flex items-center space-x-5">
<div className="relative flex h-10 w-10 items-center justify-center overflow-hidden rounded-lg">
<img
alt={`${client.name} logo`}
className="size-9 object-contain"
src={logoSrc[client.key as keyof typeof logoSrc]}
/>
</div>
<div>
<div className="mb-0.5 font-semibold text-base text-gray-900 dark:text-gray-50">
{client.name}
</div>
<div className="text-gray-600 text-xs dark:text-gray-400">
{client.description}
</div>
</div>
</div>
</div>
</div>
</div>
</Link>
);
})}
</div>
);
}
28 changes: 24 additions & 4 deletions app/en/guides/tool-calling/mcp-clients/_meta.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
export default {
cursor: "Cursor",
"claude-desktop": "Claude Desktop",
"visual-studio-code": "Visual Studio Code",
import type { MetaRecord } from "nextra";

const meta: MetaRecord = {
"*": {
theme: {
breadcrumb: true,
toc: true,
copyPage: true,
},
},
index: {
title: "Overview",
},
cursor: {
title: "Cursor",
},
"claude-desktop": {
title: "Claude Desktop",
},
"visual-studio-code": {
title: "Visual Studio Code",
},
};

export default meta;
12 changes: 12 additions & 0 deletions app/en/guides/tool-calling/mcp-clients/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "Connect to MCP Clients"
description: "Learn how to connect your MCP servers to various MCP-compatible clients and development environments"
---

import { MCPClientGrid } from "./MCPClientGrid";

# Connect to MCP Clients

You can connect [Arcade MCP servers](/resources/integrations) to MCP-compatible clients and development environments to unlock powerful flows for your agents.

<MCPClientGrid />
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
Binary file added public/images/icons/claude.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/icons/cursor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions public/images/icons/vscode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading