MCP

// app/mcps/adminmcp/adminmcp.go
package adminmcp

import (
	"context"

	"golazy.dev/lazymcp"
)

type AdminMCP struct {
	lazymcp.Base
}

func New(ctx context.Context) *AdminMCP {
	return &AdminMCP{Base: lazymcp.NewBase(ctx)}
}

type UserCountParams struct {
	Active bool `json:"active"`
}

type UserCountResult struct {
	Count int `json:"count"`
}

func (m *AdminMCP) UserCountTool(ctx context.Context) lazymcp.ToolSpec {
	return lazymcp.ToolSpec{
		Desc: "Count users.",
		Fn:   m.UserCount,
		UI:   lazymcp.UI("ui://admin/dashboard"),
	}
}

func (m *AdminMCP) UserCount(ctx context.Context, params UserCountParams) (UserCountResult, error) {
	return UserCountResult{Count: 3}, nil
}

func (m *AdminMCP) DashboardApp(ctx context.Context) lazymcp.AppSpec {
	return lazymcp.AppSpec{
		Name:          "dashboard",
		Desc:          "Admin dashboard.",
		View:          "dashboard",
		UseLayout:     true,
		Domain:        "https://mcp.example.com",
		CSP: lazymcp.AppCSP{
			ConnectDomains:  []string{},
			ResourceDomains: []string{},
		},
	}
}
// init/mcp.go
package appinit

import (
	"context"

	"golazy.dev/lazymcp"
	"sampleapp/app/mcps/adminmcp"
)

func RegisterMCP(ctx context.Context, scope *lazymcp.Scope) error {
	return scope.Register(adminmcp.New(ctx))
}
// init/oauth.go: keep refresh rotation/replay state durable in production.
func OAuth(ctx context.Context) (lazyoauth.Config, error) {
	states, ok := oauthstateservice.FromContext(ctx)
	if !ok {
		return lazyoauth.Config{}, errors.New("refresh token state store is missing")
	}
	return lazyoauth.Config{
		Issuer:             "https://mcp.example.com",
		Resource:           "https://mcp.example.com/mcp",
		Signer:             lazyjwt.Signer{KeyID: "main", Key: []byte(os.Getenv("OAUTH_SIGNING_KEY"))},
		RefreshTokenStates: states,
	}, nil
}
// init/app.go
package appinit

import (
	"golazy.dev/lazyapp"
	"sampleapp/app"
)

func App() *lazyapp.App {
	return lazyapp.New(lazyapp.Config{
		Name:         "sampleapp",
		Drawer:       Draw,
		Public:       app.Public,
		Views:        app.Views,
		Dependencies: Dependencies,
		OAuth:        OAuth,
		MCP:          RegisterMCP,
	})
}
{{/* app/views/mcp/admin/dashboard.html.tpl */}}
<section>
  <h1>Admin</h1>
  <p>Rendered as an MCP Apps UI resource.</p>
</section>