# Getting Started with MCP Gateway - Agent

<WizardSteps build="mcp-gateway" method="agent" />

<MethodTabs build="mcp-gateway" method="agent" />

Have a coding agent build a local MCP Gateway in front of Linear. You'll
complete the browser authorization yourself and verify a real Linear tool call.

## Prerequisites

- [Node.js](https://nodejs.org/en/download) 24 or later.
- A [Zuplo account](https://portal.zuplo.com).
- An installed coding agent and a Linear account with access to a workspace.
- An MCP client that can connect to a local HTTP server and complete OAuth.

This tutorial uses Zuplo's local `dev-login` shortcut. For a hosted gateway with
your identity provider, use the [Portal tutorial](./portal.mdx).

## Build your MCP Gateway with an agent

<Stepper>

1. **Create your project**

   Run:

   ```bash
   npx create-zuplo-api@latest linear-mcp-gateway
   cd linear-mcp-gateway
   ```

   When prompted, choose **Yes** to create a matching Portal project, complete
   sign-in, and select your Zuplo account. Select the coding agent you use when
   asked. The CLI creates and links the hosted project. See
   [`create-zuplo-api`](../../cli/create-zuplo-api.mdx).

   :::tip{title="Zuplo skills"}

   The scaffold installs Zuplo skills in this project for Codex and Cursor and
   configures the Claude Code plugin. If setup fails, follow
   [Agent Skills](../../build-with-ai.mdx#agent-skills) from this directory
   before starting your agent.

   :::

2. **Give the agent the gateway configuration task**

   Open your agent in the project directory and use this prompt:

   ```text
   Read the project instructions and bundled Zuplo MCP Gateway docs. Build a
   local gateway in front of Linear using the dev-login shortcut. Use
   http://127.0.0.1:9000 consistently for local URLs.

   In modules/zuplo.runtime.ts, export runtimeInit(runtime: RuntimeExtensions),
   import RuntimeExtensions from @zuplo/runtime and McpGatewayPlugin from
   @zuplo/runtime/mcp-gateway, and register new McpGatewayPlugin().

   config/policies.json must be an object containing a policies array. Add:

   1. name "dev-oauth", policyType "mcp-oauth-inbound", handler module
      "$import(@zuplo/runtime/mcp-gateway)", export "McpOAuthInboundPolicy".
      options.oidc has issuer "http://127.0.0.1:9000" and jwksUrl
      "http://127.0.0.1:9000/jwks". options.browserLogin.url is
      "http://127.0.0.1:9000/__zuplo/oauth/dev-login".
      The OIDC values are placeholders required for local dev-login; don't
      create a JWKS route or claim that /jwks exists.

   2. name "mcp-token-exchange-linear", policyType "mcp-token-exchange-inbound",
      handler module "$import(@zuplo/runtime/mcp-gateway)", export
      "McpTokenExchangeInboundPolicy". Its options are:
      {
        "displayName": "Linear",
        "protectedResourceMetadataUrl": "https://mcp.linear.app/.well-known/oauth-protected-resource",
        "authMode": "user-oauth",
        "scopes": [],
        "clientRegistration": { "mode": "auto" }
      }

   In config/routes.oas.json, add /mcp/linear-v1 with method key "get,post",
   operationId "linear-mcp-server", and x-zuplo-route.corsPolicy "none".
   Use McpProxyHandler from $import(@zuplo/runtime/mcp-gateway), with options
   { "rewritePattern": "https://mcp.linear.app/mcp" }.
   Attach inbound policies in this order: dev-oauth, mcp-token-exchange-linear.

   Run npm run dev and send an unauthenticated tools/list POST to the route.
   Verify 401 and a WWW-Authenticate header identifying the protected-resource
   metadata URL. This is only the first check; do not claim Linear works until
   I complete browser OAuth and run a real tool. Do not deploy dev-login.
   Show me the diff and the client URL.
   ```

   The [Editor tutorial](./local.mdx) shows these files as copyable examples.
   See [How it works](../../mcp-gateway/how-it-works.mdx) for the gateway's
   sign-in and upstream authorization flows.

3. **Verify authentication is attached**

   Review the diff, then run `npm run dev` if it isn't already running. In
   another terminal, send:

   ```bash
   curl -i -X POST http://127.0.0.1:9000/mcp/linear-v1 \
     -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
   ```

   Expect `401 Unauthorized` and a `WWW-Authenticate` header pointing to
   `/.well-known/oauth-protected-resource/mcp/linear-v1`. A `404` suggests a
   route mismatch; for a `500`, inspect the gateway's terminal output.

4. **Authorize Linear in your MCP client**

   Add `http://127.0.0.1:9000/mcp/linear-v1` as an HTTP MCP server in your
   client. See
   [Connect MCP clients](../../mcp-gateway/connect-clients/overview.mdx) for
   client-specific setup.

   Keep `127.0.0.1` in the client URL to match the policy. During the browser
   OAuth flow, dev-login signs you in locally. On the gateway's consent page,
   click **Connect** for Linear, authorize your Linear account, then click
   **Authorize** to complete the gateway connection.

   Complete these actions yourself; the coding agent doesn't need your Linear
   password or tokens.

5. **Run a real tool**

   Ask your client to `List my open Linear issues`. Approve the tool call. Check
   that it returns your issues, or an empty result if you have none, without an
   authentication error.

   If connection fails, check that the local server is running and the client
   uses `127.0.0.1` throughout. See
   [Local development](../../mcp-gateway/code-config/local-development.mdx).

</Stepper>

## Deploy with your identity provider

Dev-login works only on loopback origins. Before sharing the gateway, replace it
with your identity provider using
[Configure local and deployed environments](../../mcp-gateway/code-config/local-development.mdx#configure-local-and-deployed-environments),
then follow [Deploy to the edge](../gateway/deploy-to-the-edge/local.mdx).
Repeat the full browser authorization and tool call against the hosted URL.

## Next steps

- [Front more upstream servers](../../mcp-gateway/code-config/multi-upstream.mdx).
- [Filter tools and other capabilities](../../mcp-gateway/capability-filtering.mdx).
- [Choose an identity provider](../../mcp-gateway/auth/overview.mdx).
