---
title: "Get started with theAuth: human and agent auth"
description: "Install theAuth for TypeScript or Go. Two tracks: human sign-in with sessions, and AI agent auth with scoped tokens and an MCP OAuth 2.1 server. Copy and paste."
canonical: https://theauth.dev/get-started/
lastmod: 2026-10-08
---

Get started

# Pick a track: people signing in, or agents calling.

Most apps need both. A person logs in and gets a session. An AI agent, an MCP client or a script presents a scoped token instead. theAuth handles each with its own mechanism, in one library, in TypeScript or Go.

[Human auth](https://theauth.dev/get-started/#human) [AI agent auth](https://theauth.dev/get-started/#agent)

How the two differ

## A session proves who someone is. A token proves what a caller may do.

[Agent identity in depth](https://theauth.dev/agent-identity/) [Human auth in depth](https://theauth.dev/human-auth/)

People and agents enter through the same library and leave with different credentials. A person gets a server-side session. An agent gets a scoped token with an owner, an expiry and an audit trail.

Track 1

## Human auth in about ten lines.

Install, configure one sign-in method, read the signed-in user. Magic links need no password database to start, and passkeys, TOTP, OAuth and SAML add on top.

1 Scaffold a full app, or add the package to your own.

`pnpm create @glinr/theauth-app`

Or add it to an existing project. The SQLite driver is a peer dependency, so install it too:

`pnpm add @glinr/theauth sql.js`

npm users: npm create @glinr/theauth-app and npm install @glinr/theauth sql.js.

2 Create the instance and send a sign-in link.

auth.ts

```ts
import { createTheAuth } from "@glinr/theauth";

const theauth = await createTheAuth({
  database: { provider: "sqlite", url: "app.db" },
  baseUrl: "http://localhost:3000",
  auth: { session: { secret: process.env.SESSION_SECRET! } }, // 32+ characters
  magicLink: {
    appUrl: "http://localhost:3000",
    sendMagicLink: async (email, _token, url) => {
      console.log(`sign-in link for ${email}: ${url}`);
    },
  },
});

await theauth.magicLink?.sendLink("ada@example.com");
```

[TypeScript quickstart](https://docs.theauth.dev/quickstart) [All sign-in methods](https://docs.theauth.dev/auth) [Guide: human login in Hono](https://theauth.dev/guides/hono-human-and-agent-auth/)

1 Add the module. Keep the /v2 suffix.

`go get github.com/glincker/theauth-go/v2`

Optional embedded SQLite backend (needs Go 1.26):

`go get github.com/glincker/theauth-go/storage/sqlite`

2 Mount it in your router. Imports: theauth, storage/memory, chi.

main.go (fragment)

```go
a, err := theauth.New(theauth.Config{
	Storage: memory.New(),
	BaseURL: "http://localhost:8080",
})
if err != nil {
	log.Fatal(err)
}
defer a.Close()

r := chi.NewRouter()
a.Mount(r) // /auth/*: magic link, passkeys, TOTP, OAuth, sessions
r.With(a.RequireAuth()).Get("/me", func(w http.ResponseWriter, r *http.Request) {
	user, _ := theauth.UserFromContext(r.Context())
	w.Write([]byte("hello " + user.Email))
})
log.Fatal(http.ListenAndServe(":8080", r))
```

[theauth-go overview](https://theauth.dev/go/) [Go quick start](https://docs.theauth.dev/go/getting-started/quick-start) [Runnable SQLite example](https://github.com/glincker/theauth-go/tree/main/examples/single-binary-sqlite)

Track 2

## AI agent auth: identities, scoped tokens, MCP.

Give each agent its own owner, permissions and audit trail, or put an OAuth 2.1 authorization server in front of your MCP server so clients you have never met can register and sign in.

1 Install the core. Add the Hono adapter if you want the MCP OAuth endpoints.

`pnpm add @glinr/theauth sql.js`

`pnpm add @glinr/theauth-hono hono @hono/node-server`

2 Create an agent and authorize a call by its token.

agent.ts

```ts
import { createTheAuth } from "@glinr/theauth";

const theauth = await createTheAuth({
  database: { provider: "sqlite", url: "app.db" },
  agents: { enabled: true },
});

const agent = await theauth.agent.create({
  ownerId: "user-123", // a row that exists in theauth_users
  name: "report-bot",
  type: "autonomous",
  permissions: [{ resource: "reports:*", actions: ["read"] }],
});
// agent.token is "kv_...", shown once. Store it now.

const result = await theauth.authorizeByToken(agent.token, {
  action: "read",
  resource: "reports:q3",
});
// result.allowed === true, result.auditId links to the audit row
```

[Guide: secure an MCP server](https://theauth.dev/guides/mcp-server-typescript/) [Agents docs](https://docs.theauth.dev/agents) [MCP OAuth docs](https://docs.theauth.dev/mcp)

1 The authorization server is in the main module. MCP servers validate tokens with the small resource module.

`go get github.com/glincker/theauth-go/v2`

`go get github.com/glincker/theauth-go/mcpresource`

2 Protect your MCP server's routes with one middleware.

main.go (fragment)

```go
v := mcpresource.New(
	"https://mcp.example.com",                       // your MCP server's resource URI
	mcpresource.WithJWKS("https://auth.example.com/oauth/jwks"),
)

r := chi.NewRouter()
r.Use(v.Middleware) // 401 with resource metadata pointers when the token is bad

r.Get("/tools", func(w http.ResponseWriter, r *http.Request) {
	p, _ := v.Principal(r.Context())
	json.NewEncoder(w).Encode(map[string]any{"subject": p.Subject, "scope": p.Scope})
})
```

[Guide: the authorization server too](https://theauth.dev/guides/mcp-authorization-server-go/) [MCP authorization docs](https://docs.theauth.dev/go/concepts/mcp-authorization) [theauth-go overview](https://theauth.dev/go/)

## Where to go next

[Guides](https://theauth.dev/guides/) [Full quickstart](https://docs.theauth.dev/quickstart) [Compare with other auth tools](https://theauth.dev/compare/) [Multi-agent systems](https://theauth.dev/use-cases/multi-agent/) [Changelog](https://theauth.dev/changelog/)

Commands checked against npm and the Go module proxy on 2026-10-08: @glinr/theauth 0.6.0, @glinr/theauth-hono 4.0.0, @glinr/create-theauth-app 0.3.0, theauth-go v2.7.1.
