AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Gofastr

mcp-donaldmurillo-gofastr · by DonaldMurillo

The framework that doesn't get in the way of you or your agents.

— No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add mcp-donaldmurillo-gofastr

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ● Network access Used
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-donaldmurillo-gofastr)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● yesterday

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Gofastr? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

GoFastr

[](https://github.com/DonaldMurillo/gofastr/actions/workflows/ci.yml) [](https://github.com/DonaldMurillo/gofastr/releases) [](go.mod) [](https://pkg.go.dev/github.com/DonaldMurillo/gofastr) [](LICENSE) [](https://www.coderabbit.ai)

> The full-stack Go framework that doesn't get in the way of you or your agents.

Docs, component gallery, and live demos →  ·  [Quickstart](#quickstart)  ·  A GoFastr app in production

GoFastr is a pre-v1 full-stack Go framework. The API can still change between releases, under the [deprecation policy](framework/docs/content/stability.md). Declare your domain in Go and get server-rendered screens, REST endpoints, MCP tools, an OpenAPI spec, SQL migrations, and a typed query builder. The output is plain Go you can read, edit, and own: no reflection discovers your entities, no generated code you can't open. Auth, background jobs, search, and storage are opt-in packages, and you can drop to net/http or database/sql at any point.

It is built for both the agentic web and AI-assisted development. The app you ship joins the agentic web: the agents your users bring call your data over MCP, with the same login and permissions your users have. While you build, gofastr dev hands your coding agent, Claude Code or Codex, the app's routes, config, and logs over MCP, to help build and debug it.

Start with [the quickstart](#quickstart). Or scaffold a whole app in one command: screens, API, and auth from gofastr init , or gofastr generate from a one-file declaration ([blueprint tutorial](framework/docs/content/tutorial-blueprint-app.md)).

A shoutout to CodeRabbit: it reviews every PR in this repo and keeps catching what everyone else missed, like six Major findings on #198 while the checks list showed pass. Every finding is triaged on the PR before merge.

Quickstart

Requires Go 1.27+. Install the CLI:

go install github.com/DonaldMurillo/gofastr/cmd/gofastr@latest

Three complete programs, smallest to fullest, the same three the site's homepage shows (examples/site): plain core/, one framework entity, and the full app shape. CI extracts all three from this README, compiles them, boots them, and curls them (cmd/gofastr/readme_quickstart_test.go).

Core only

core/ is stdlib-first building blocks: router, typed handlers, render, a SQL query builder, schema, migrate, mcp. Each is usable without the framework. The basic app is one screen and one API route:

package main

import (
	"context"
	"net/http"

	"github.com/DonaldMurillo/gofastr/core/handler"
	"github.com/DonaldMurillo/gofastr/core/render"
	"github.com/DonaldMurillo/gofastr/core/router"
)

type Pong struct {
	Status string `json:"status"`
}

func main() {
	r := router.New()

	// A server-rendered page.
	r.Get("/", render.HTMLHandler(func(req *http.Request) render.HTML {
		return render.Tag("h1", nil, render.Text("Hello from core."))
	}))

	// A typed JSON route: the adapter binds input and serializes output.
	r.Get("/api/ping", handler.HandlerAdapter(func(ctx context.Context, _ struct{}) (Pong, error) {
		return Pong{Status: "ok"}, nil
	}))

	http.ListenAndServe(":8080", r)
}

Framework

One framework entity is a complete server: a migrated table, REST CRUD, an OpenAPI spec, and MCP tools. Add only what you need from there.

package main

import (
	"database/sql"
	"log"

	"github.com/DonaldMurillo/gofastr/core/schema"
	"github.com/DonaldMurillo/gofastr/framework"
	_ "github.com/DonaldMurillo/gofastr/sqlite/stdlib"
)

func main() {
	db, _ := sql.Open("sqlite3", "app.db")
	app := framework.NewApp(framework.WithDB(db), framework.WithMCP()) // WithMCP serves the tools at /mcp

	// CRUD is auto-on when a DB is set (CRUD *bool: nil = auto).
	app.Entity("posts", framework.EntityConfig{
		Exposure: &framework.ExposureConfig{
			Public: true, // anonymous read AND write; omit it and CRUD requires a session (secure by default)
			MCP:    true, // emit posts_list/get/create/update/delete MCP tools
		},
		Fields: []schema.Field{{Name: "title", Type: schema.String, Required: true}},
	})

	log.Fatal(app.Start(":8080")) // GET/POST /posts, /openapi.json, MCP: all live
}

That's the whole program. No config files, no codegen step, no registration boilerplate. Add entities-as-JSON, batteries, the UI runtime, or the generator when you need them. For how a flat app grows into internal// as boundaries appear, see [project structure](framework/docs/content/project-structure.md).

Donald's Way

The full app shape: server-rendered screens with SEO, an owner-scoped entity API, MCP for agents, and login + sessions, in one binary. A screen is Go too: Render returns HTML, and a small JS runtime hydrates it in place, with no React or Vue on the client:

package main

import (
	"database/sql"
	"log"

	"github.com/DonaldMurillo/gofastr/battery/auth"
	"github.com/DonaldMurillo/gofastr/core-ui/app"
	"github.com/DonaldMurillo/gofastr/core-ui/html"
	"github.com/DonaldMurillo/gofastr/core/render"
	"github.com/DonaldMurillo/gofastr/core/schema"
	"github.com/DonaldMurillo/gofastr/framework"
	"github.com/DonaldMurillo/gofastr/framework/uihost"
	_ "github.com/DonaldMurillo/gofastr/sqlite/stdlib"
)

// A screen is plain Go: Render returns server-rendered HTML.
type HomeScreen struct{}

func (s *HomeScreen) ScreenTitle() string { return "Notes" }
func (s *HomeScreen) Render() render.HTML {
	return html.Heading(html.HeadingConfig{Level: 1}, render.Text("My notes"))
}

func main() {
	db, _ := sql.Open("sqlite3", "notes.db")

	// Server-rendered screens. Each also serves an auto llm.md.
	ui := app.NewApp("Notes")
	ui.Register("/", &HomeScreen{}, nil)

	// SEO for those pages.
	host := uihost.New(ui,
		uihost.WithDescription("A tiny notes app."),
		uihost.WithOpenGraph(uihost.OG{Title: "Notes", Type: "website"}),
		uihost.WithSitemap(uihost.SitemapConfig{BaseURL: "https://notes.example"}),
	)

	// MCP for agents.
	fwApp := framework.NewUIHostApp(host,
		framework.WithDB(db),
		framework.WithAPIPrefix("/api"),
		framework.WithMCP(),
	)

	// Scope.OwnerField scopes rows per user: anonymous → 401, cross-user → 404.
	fwApp.Entity("notes", framework.EntityConfig{
		Scope:    &framework.ScopeConfig{OwnerField: "user_id"},
		Exposure: &framework.ExposureConfig{MCP: true},
		Fields:   []schema.Field{{Name: "title", Type: schema.String, Required: true}},
	})

	// Login + sessions.
	authMgr := auth.New(auth.AuthConfig{
		DevMode:      true, // dev only: mints a per-process JWT secret; set JWTSecret in prod
		UserStore:    auth.NewEntityUserStore(db, "auth_users"),
		SessionStore: auth.NewEntitySessionStore(db, "auth_sessions"),
	})
	authMgr.Use(auth.NewCorePlugin())
	if err := authMgr.Init(fwApp); err != nil {
		log.Fatal(err)
	}
	fwApp.Use(auth.SessionMiddleware(authMgr))

	log.Fatal(fwApp.Start(":8080"))
}

GET / is the rendered screen. Anonymous GET /api/notes answers 401: OwnerField scopes rows per user, and auto-CRUD requires a session unless the entity is Public. /auth/register and /auth/login come from the auth battery, and the MCP tools at /mcp respect the same owner scope as the REST API.

Run it from a clone

To work on the framework itself, or run the examples:

git clone https://github.com/DonaldMurillo/gofastr.git
cd gofastr
go test ./...                        # SQLite; the Postgres halves skip without TEST_POSTGRES_DSN
go run ./cmd/gofastr --help          # CLI overview
go run ./examples/blog               # minimal blog with auto-CRUD on SQLite

Postgres setup and the race pass are under [Contributing](#contributing). Linked Git worktrees of the same app each get their own port and database path, so two coding agents can run side by side ([isolation](framework/docs/content/isolation.md)).

Updating GoFastr

The module dependency and the installed CLI are versioned independently; keep them on the same release. gofastr upgrade reads your go.mod, lists every migration note between your version and the target (breaking changes are marked in the release notes), and points at the affected lines in your code (--apply runs the steps). Manual steps and the full guide: [upgrading](framework/docs/content/upgrading.md), or gofastr docs upgrading.

The code you don't write

The framework emits routes, validation, migrations, pagination, uploads, the spec, and agent tools from one declaration (app.Entity in Go, or an entities: entry in a blueprint). Declarations are optional: core/ routes and hand-written screens run without them. A declaration grows the same way it starts, with fields, enums, relations, and soft delete:

app.Entity("posts", framework.EntityConfig{
    Scope: &framework.ScopeConfig{SoftDelete: true},
    Fields: []schema.Field{
        {Name: "title", Type: schema.String, Required: true},
        {Name: "body", Type: schema.Text},
        {Name: "status", Type: schema.Enum,
            Values: []string{"draft", "published"}, Default: "draft"},
        {Name: "author_id", Type: schema.Relation, To: "users"},
    },
    Exposure: &framework.ExposureConfig{MCP: true},
})

| Output | Auto-generated | |------------------|---------------------------------------------------------------------------------| | HTTP | GET / POST /posts, GET / PUT / PATCH / DELETE /posts/{id} | | Batch endpoints | POST / PATCH / DELETE /posts/_batch: atomic; one tx for all items | | SSE stream | GET /posts/_events: entity.created/updated/deleted, scoped per tenant | | Filtering | ?status=published&views_gte=10&sort=-created_at&page=2 | | Eager loading | ?include=author.profile,comments: flat or nested, validated against the registry | | Cursor paging | ?cursor=&limit=50: keyset paging ([cursor-pagination](framework/docs/content/cursor-pagination.md)) | | Multipart upload | multipart/form-data on Image/File fields → streamed through WithFileStorage | | Validation | Required, unique, enum, min/max, regex pattern, multi-tenant scope | | Migrations | Versioned runner with drift + dirty-state guards; declarative incremental generation ([migrations](framework/docs/content/migrations.md)) | | FK constraints | BelongsTo relations emit FOREIGN KEY clauses; AutoMigrate topo-sorts tables | | Transactions | Create/Update/Delete + hooks share one tx; TxFromContext(ctx) exposes it | | OpenAPI 3 | /openapi.json plus a spec-viewer page at /api/docs/ | | MCP | posts_list, posts_get, posts_create, posts_update, posts_delete | | Soft delete | deleted_at column + automatic filter | | Multi-tenant | tenant_id column + automatic scope from request context | | Hooks | BeforeCreate, AfterUpdate, etc. for custom behaviour | | Custom routes | EntityConfig.Endpoints with optional MCP exposure | | Client SDKs | gofastr generate sdk: a Go module + JS/TS clients, with a live docs site ([sdk](framework/docs/content/sdk.md)) | | Customer CLI | gofastr generate cli: a branded terminal client for your customers, scoped API-token auth |

Try all of it against a running server: [examples/api-tour](examples/api-tour/README.md) is the curl tour, covering eager loading, cursor paging, atomic batch, SSE, uploads, and sparse updates. Hooks run inside the write's transaction ([hooks-and-transactions](framework/docs/content/hooks-and-transactions.md)).

The design bets

  • Two layers. A small core/ of stdlib-first primitives sits under an opinionated framework/. Use the framework for the common path; drop to core and write plain net/http when it's in your way. (The one external touchpoint is core/middleware/tracing.go, which pulls in OpenTelemetry; the rest of core/ is stdlib-only.)
  • Server-rendered UI, hydrated in place. Screens are Go: Render returns HTML and the server sends the full page. A small JS runtime attaches to it. In-page changes like sort, paginate, or add-a-row call the server and swap one region, and cross-page navigation swaps content client-side with a route cache, so there are no hard refreshes. No React or Vue on the client, and no router code for you to write.
  • The interactive layer keeps no server state. Sessions are signed tokens, so any replica serves any request. Updates pull first: client signals, then RPC, then polling. SSE push is reserved for presence and collaboration ([reactivity.md](framework/docs/content/reactivity.md)).
  • Security scopes live in the declaration, fail-closed. owner_field makes auto-CRUD per-user (anonymous → 401, cross-user → 404), access: gates operations behind RBAC permissions (403), multi_tenant scopes by tenant, and gofastr validate flags PII-shaped fields (email, phone, address, …) exposed without any of them. The MCP tools respect the same scopes as the REST routes.
  • You own the output. The generated code is normal Go you read, debug, commit, edit, and compose from your own main. Registration is ordinary Go in the generated files; no reflection discovers your entities, and no platform sits between your binary and your server.
  • Batteries are separate packages. Auth, cache, email, queue, search, storage sit behind narrow interfaces; swap any one without forking.
  • The framework checks whether you're still using it well. gofastr verify runs the 63 rules of the contract catalog (routing, permissions, security, rendering, accessibility) and measures semantic coverage: not "did this line run" but "did a request ever reach this route, did this permission ever get evaluated". Error-severity findings fail the run (--strict makes warnings fail too), with per-line waivers and a baseline mode for existing codebases. See [contracts](framework/docs/content/contracts.md).
  • A blueprint scaffolds the whole app when you want a head start. One gofastr.yml generates the screens and the API in one pass; then it's plain Go you own and edit, and the running app never needs the blueprint again ([blueprint tutorial](framework/docs/content/tutorial-blueprint-app.md)).

The repo in 60 seconds

| Directory | What it is | Depend on it when… | |---|---|---| | core/ | Stdlib-only primitives: router, query, schema, render, mcp, openapi, migrate. Each usable on its own. | you want plain Go building blocks, no framework. | | framework/ | The opinionated entity layer (App, EntityConfig, CRUD, hooks, migrations). A thin facade re-exporting its focused runtime subpackages. | you want one declaration → SQL + REST + OpenAPI + MCP. | | core-ui/ | Server-driven UI runtime: html primitives, patterns, widget islands, signals, the vanilla-JS runtime. Independently usable. | you're rendering HTML from Go. | | battery/ | Opt-in infrastructure: admin, auth, cache, email, semantic, log, notify, print, queue, relay, rtc, search, setup, storage, webhook. Each behind a small interface. | you need a real subsystem; import only the ones you use. | | cmd/gofastr | The CLI: init, generate, pack (lossy app→blueprint snapshot), migrate, build, dev, verify, docs, and more. | you're scaffolding, generating, or checking code. | | kiln | Experimental agent build-mode runtime (mutate an in-memory IR over HTTP). | you're driving the app from an agent. | | examples/ | Runnable reference apps: the meridian blueprint flagship (a SaaS billing console + marketing site), the `ecomme

…

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.