---
title: "Manual Install | Getting Started"
description: Set up a Mastra project manually without using the create mastra CLI.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import Steps from "@site/src/components/Steps";
import StepItem from "@site/src/components/StepItem";

# Manual Install

:::info
Use this guide to manually build a standalone Mastra server step by step. In most cases, it's quicker to follow a [getting-started guide](/docs/v1/getting-started/start), which achieves the same result using the [`mastra create`](/reference/v1/cli/create-mastra) command. For existing projects, you can also use [`mastra init`](/reference/v1/cli/mastra#mastra-init).
:::

If you prefer not to use our automatic CLI tool, you can set up your project yourself by following the guide below.

<Steps>

<StepItem>

Create a new project and change directory:

```bash
mkdir my-first-agent && cd my-first-agent
```

Initialize a TypeScript project and install the following dependencies:

<Tabs>
<TabItem value="npm" label="npm">

```bash
npm init -y
npm install -D typescript @types/node mastra@beta
npm install @mastra/core@beta zod@^4
```

</TabItem>
<TabItem value="pnpm" label="pnpm">

```bash
pnpm init
pnpm add -D typescript @types/node mastra@beta
pnpm add @mastra/core@beta zod@^4
```

</TabItem>
<TabItem value="yarn" label="yarn">

```bash
yarn init -y
yarn add -D typescript @types/node mastra@beta
yarn add @mastra/core@beta zod@^4
```

</TabItem>
<TabItem value="bun" label="bun">

```bash
bun init -y
bun add -d typescript @types/node mastra@beta
bun add @mastra/core@beta zod@^4
```

</TabItem>
</Tabs>

Add `dev` and `build` scripts to your `package.json` file:

```json title="package.json" /,/ /"dev": "mastra dev",/ /"build": "mastra build"/
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "mastra dev",
    "build": "mastra build"
  }
}
```

</StepItem>

<StepItem>

Create a `tsconfig.json` file:

```bash
touch tsconfig.json
```

Add the following configuration:

```json title="tsconfig.json"
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "outDir": "dist"
  },
  "include": ["src/**/*"]
}
```

:::info

Mastra requires modern `module` and `moduleResolution` settings. Using `CommonJS` or `node` will cause resolution errors.

:::

</StepItem>

<StepItem>

Create an `.env` file:

```bash
touch .env
```

Add your API key:

```bash title=".env"
GOOGLE_GENERATIVE_AI_API_KEY=<your-api-key>
```

:::note

This guide uses Google Gemini, but you can use any supported [model provider](/models/v1), including OpenAI, Anthropic, and more.

:::

</StepItem>

<StepItem>

Create a `weather-tool.ts` file:

```bash
mkdir -p src/mastra/tools && touch src/mastra/tools/weather-tool.ts
```

Add the following code:

```ts title="src/mastra/tools/weather-tool.ts"
import { createTool } from "@mastra/core/tools";
import { z } from "zod";

export const weatherTool = createTool({
  id: "get-weather",
  description: "Get current weather for a location",
  inputSchema: z.object({
    location: z.string().describe("City name"),
  }),
  outputSchema: z.object({
    output: z.string(),
  }),
  execute: async () => {
    return {
      output: "The weather is sunny",
    };
  },
});
```

:::info

We've shortened and simplified the `weatherTool` example here. You can see the complete weather tool under [Giving an Agent a Tool](/docs/v1/agents/using-tools).

:::

</StepItem>

<StepItem>

Create a `weather-agent.ts` file:

```bash
mkdir -p src/mastra/agents && touch src/mastra/agents/weather-agent.ts
```

Add the following code:

```ts title="src/mastra/agents/weather-agent.ts"
import { Agent } from "@mastra/core/agent";
import { weatherTool } from "../tools/weather-tool";

export const weatherAgent = new Agent({
  id: "weather-agent",
  name: "Weather Agent",
  instructions: `
      You are a helpful weather assistant that provides accurate weather information.

      Your primary function is to help users get weather details for specific locations. When responding:
      - Always ask for a location if none is provided
      - If the location name isn't in English, please translate it
      - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
      - Include relevant details like humidity, wind conditions, and precipitation
      - Keep responses concise but informative

      Use the weatherTool to fetch current weather data.
`,
  model: "google/gemini-2.5-pro",
  tools: { weatherTool },
});
```

</StepItem>

<StepItem>

Create the Mastra entry point and register your agent:

```bash
touch src/mastra/index.ts
```

Add the following code:

```ts title="src/mastra/index.ts"
import { Mastra } from "@mastra/core";
import { weatherAgent } from "./agents/weather-agent";

export const mastra = new Mastra({
  agents: { weatherAgent },
});
```

</StepItem>

<StepItem>

You can now launch [Studio](/docs/v1/getting-started/studio) and test your agent.

<Tabs>
<TabItem value="npm" label="npm">

```bash
npm run dev
```

</TabItem>
<TabItem value="pnpm" label="pnpm">

```bash
pnpm run dev
```

</TabItem>
<TabItem value="yarn" label="yarn">

```bash
yarn run dev
```

</TabItem>
<TabItem value="bun" label="bun">

```bash
bun run dev
```

</TabItem>
</Tabs>

</StepItem>

</Steps>
