> ## Documentation Index
> Fetch the complete documentation index at: https://cadenya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect an MCP server

> Connect a Streamable HTTP MCP server, choose when its tools load, and verify each sync.

Connect the public Faker MCP server and expose its three tools to an [agent variation](/docs/guides/configure-a-simple-agent). This guide starts with an empty workspace and explains both MCP loading modes.

## What you need

* A Cadenya workspace.
* An MCP server with a Streamable HTTP endpoint. This guide uses `https://free.cadenya.com/faker-mcp`.
* `CADENYA_API_KEY` and `CADENYA_WORKSPACE_ID` when you follow the code example.

<Note>
  Cadenya uses the MCP Streamable HTTP transport. A server that only supports the older HTTP+SSE transport cannot connect. Point **Server URL** at the server's Streamable HTTP endpoint, often `/mcp`.
</Note>

## Create the tool set

<Steps>
  <Step title="Configure the connection">
    Select **Tool Sets**, click **Create Tool Set**, and select **MCP**. Enter `https://free.cadenya.com/faker-mcp` as the **Server URL**.

    Add headers when the server requires authentication. Store each credential as a [secret](/docs/guides/store-and-use-secrets), then reference it with `${SECRET_NAME}`:

    ```text theme={null}
    Authorization: Bearer ${MCP_SERVER_TOKEN}
    ```

    <Frame caption="The MCP connection step with the Faker server URL">
      <img src="https://mintcdn.com/cadenya/jVN0RLx9DL3HyxfK/images/docs/quickstart-ui/faker-mcp-connection.webp?fit=max&auto=format&n=jVN0RLx9DL3HyxfK&q=85&s=c27b491514f51d237ef4d40517aa7449" alt="MCP connection settings with the Faker Streamable HTTP endpoint entered as the Server URL" width="1800" height="940" data-path="images/docs/quickstart-ui/faker-mcp-connection.webp" />
    </Frame>

    Click **Generate Preview** before you continue. Preview connects to the server and shows how the current filters affect its tool list without creating the tool set.

    <Frame caption="The three tools returned by the Faker MCP server">
      <img src="https://mintcdn.com/cadenya/jVN0RLx9DL3HyxfK/images/docs/quickstart-ui/faker-tools-preview.webp?fit=max&auto=format&n=jVN0RLx9DL3HyxfK&q=85&s=0bda53775c6b3daf5d6bddd0b99d90d9" alt="MCP Tools Preview listing GenerateCurseWord, GenerateFake, and GetFakerOptions as available" width="1688" height="832" data-path="images/docs/quickstart-ui/faker-tools-preview.webp" />
    </Frame>
  </Step>

  <Step title="Choose when tools load">
    Click **Continue** to open **Tool behavior**. Keep the runtime switch off for this guide. Cadenya syncs the tools ahead of time and pins them to the tool set.

    <Frame caption="Filters, approval policy, and ahead-of-time MCP loading">
      <img src="https://mintcdn.com/cadenya/H-RL7Q6kGrFhr6Gf/images/docs/tool-sets/mcp-tool-behavior.webp?fit=max&auto=format&n=H-RL7Q6kGrFhr6Gf&q=85&s=606b532de148a179a131dc8ecbdec234" alt="Tool behavior step with no filters, no approval requirement, and Just-in-time tool loading turned off" width="1800" height="1686" data-path="images/docs/tool-sets/mcp-tool-behavior.webp" />
    </Frame>

    The setting changes when and where tool discovery happens:

    | Mode         | **Just-in-time tool loading** | Discovery                          | Dashboard tool list                      | Refresh                                      |
    | :----------- | :---------------------------- | :--------------------------------- | :--------------------------------------- | :------------------------------------------- |
    | Synced       | Off                           | After save, then in the background | Pinned tools appear on **Tools**         | Every hour and after adapter updates         |
    | Just in time | On                            | When each objective starts         | No pinned tools; the count stays at zero | Every objective gets the current server list |

    On-demand loading resolves the objective's secrets before it lists tools. Use it when each objective has different credentials or the server exposes a different tool list per caller. Enable **Fail objective when tools cannot be loaded** when continuing without this tool set would make the objective invalid.
  </Step>

  <Step title="Set filters and approvals">
    Leave **Include tools** and **Exclude tools** empty so all three Faker tools remain available. Leave **Approval requirement** on **No approval required**.

    Filters control availability:

    * **Include tools** keeps only matching names, titles, or descriptions.
    * **Exclude tools** removes matching tools after the include rule runs.
    * An excluded synced tool remains visible as **Omitted**. Agents receive only **Available** tools.

    Approval policy controls execution:

    * **No approval required** lets every available tool run.
    * **Always require approval** pauses every call.
    * **Only matching tools require approval** applies the approval rule to a filtered subset.

    The separate [filter and approval guide](/docs/guides/preventing-tool-bloat) builds both policies with a larger tool source.
  </Step>

  <Step title="Name and create the tool set">
    Click **Continue**, enter `Faker MCP` as **Name**, and use `faker-mcp` as **External ID**. Add a description, review the configuration, then click **Create Tool Set**.

    Cadenya validates that the server can list tools before it saves the resource. After creation, the first background sync populates the **Tools** tab.
  </Step>
</Steps>

## Verify the synced tools

Open the new tool set. The **Tools** tab shows three **Available** tools:

* `GenerateCurseWord`
* `GenerateFake`
* `GetFakerOptions`

Select a tool to inspect the description and JSON parameter schema that the MCP server returned.

<Frame caption="Faker MCP tools pinned to the tool set">
  <img src="https://mintcdn.com/cadenya/H-RL7Q6kGrFhr6Gf/images/docs/tool-sets/mcp-tools-synced.webp?fit=max&auto=format&n=H-RL7Q6kGrFhr6Gf&q=85&s=e0cb99db7661ce8bbe9096b2ed23c28a" alt="Faker MCP Tools tab showing three available tools and the selected tool's description and parameter schema" width="3640" height="2136" data-path="images/docs/tool-sets/mcp-tools-synced.webp" />
</Frame>

Open **Sync Events** to audit discovery. A synced MCP tool set runs its first sync after creation and refreshes every hour. Updating its adapter also queues a sync.

<Frame caption="Initial and hourly MCP sync events">
  <img src="https://mintcdn.com/cadenya/H-RL7Q6kGrFhr6Gf/images/docs/tool-sets/mcp-sync-events.webp?fit=max&auto=format&n=H-RL7Q6kGrFhr6Gf&q=85&s=33f44f42948b97a6d8dcdfce235af55b" alt="Faker MCP Sync Events tab showing an initial three-tool sync followed by hourly syncs with no tool changes" width="3640" height="2136" data-path="images/docs/tool-sets/mcp-sync-events.webp" />
</Frame>

The event count is the number of tools changed by that run, not the total tools in the set. An hourly refresh can report `0 tools` while the unchanged three-tool list remains available.

If a sync fails, **Sync Events** records the reason. Common failures include an unreachable URL and a header that references a missing secret.

## Create the same configuration from code

The API returns an active tool set before the background sync finishes. Read its event log when setup code must wait for the tools.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Cadenya from '@cadenya/cadenya';

  const client = new Cadenya({ apiKey: process.env['CADENYA_API_KEY'] });
  const workspaceId = process.env['CADENYA_WORKSPACE_ID']!;

  const toolSet = await client.toolSets.create({
    workspaceId,
    metadata: { name: 'Faker MCP', externalId: 'faker-mcp' },
    spec: {
      adapter: {
        type: 'mcp',
        mcp: {
          url: 'https://free.cadenya.com/faker-mcp',
          justInTime: { enabled: false },
        },
      },
    },
  });

  while (true) {
    const events = await client.toolSets.listEvents(toolSet.metadata.id, {
      workspaceId,
      sortOrder: 'desc',
    });

    let pending = true;
    for await (const event of events) {
      const data = event.event;
      switch (data?.type) {
        case 'syncCompleted':
          console.log(`Synced ${data.syncCompleted.toolsSynced} tools`);
          pending = false;
          break;
        case 'syncFailed':
          throw new Error(data.syncFailed.message);
      }
      if (!pending) break;
    }

    if (!pending) break;
    await new Promise((resolve) => setTimeout(resolve, 1_000));
  }
  ```

  ```bash cURL theme={null}
  curl -X POST \
    "https://api.cadenya.com/v1/workspaces/${CADENYA_WORKSPACE_ID}/tool_sets" \
    -H "Authorization: Bearer ${CADENYA_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "metadata": {
        "name": "Faker MCP",
        "externalId": "faker-mcp"
      },
      "spec": {
        "adapter": {
          "type": "mcp",
          "mcp": {
            "url": "https://free.cadenya.com/faker-mcp",
            "justInTime": { "enabled": false }
          }
        }
      }
    }'
  ```
</CodeGroup>

<Check>
  You now have a vetted MCP tool set with three synced tools. Assign the whole set to an agent variation, or assign one tool when the agent needs a narrower capability.
</Check>

## Next steps

<CardGroup cols={2}>
  <Card title="Create and publish an agent" icon="robot" href="/docs/guides/configure-a-simple-agent">
    Assign Faker MCP to a variation and run it.
  </Card>

  <Card title="Filter a large tool source" icon="filter" href="/docs/guides/preventing-tool-bloat">
    Combine include, exclude, approval, and progressive discovery controls.
  </Card>

  <Card title="Store an MCP credential" icon="key" href="/docs/guides/store-and-use-secrets">
    Keep provider tokens out of tool set configuration.
  </Card>

  <Card title="Tool sets from the SDK" icon="code" href="/docs/guides/sdk/tool-sets">
    Create, update, assign, archive, and inspect tool sets from code.
  </Card>
</CardGroup>
