AgentStack
MCP verified Apache-2.0 Self-run

Galdor

mcp-yassercr-galdor · by YasserCR

A Go-native framework for LLM agents, with OpenTelemetry observability built in.

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add mcp-yassercr-galdor

✓ 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 No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution Used

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-yassercr-galdor)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

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 Galdor? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

galdor

> galdor (n., Old English, c. 9th century): incantation, spell, a chanted word that bends reality.

A Go-native framework for building, orchestrating and observing AI agents. Native OpenTelemetry. Embedded dashboard. One binary. No external SaaS. Apache 2.0.

[](https://pkg.go.dev/github.com/YasserCR/galdor) [](LICENSE) [](https://go.dev)


Why galdor

The table below was last verified against each project's repo, releases and official docs in May 2026. Sources are linked under the table; PRs welcome when something drifts.

| | galdor | LangChain Python + LangSmith | LangChainGo | Eino | Genkit Go | |---|---|---|---|---|---| | Latest release | v1.0.0 (Jun 2026) | langchain-core v1.4.0 (May 2026) | v0.1.14 (Oct 2025) | v0.8.13 stable, v0.9.0-alpha active (May 2026) — pre-1.0 | mcp plugin v1.8.0 GA (May 2026) | | Language / runtime | Go | Python | Go | Go | Go | | Observability story | OTel-native, with an embedded SQLite trace store + dashboard served from the same binary | LangSmith (closed-source SaaS) | callbacks only, no OTel | callbacks; the shipped tracing target is Langfuse, not OTel | OTel-native; Genkit Monitoring (the hosted dashboard) is Google-Cloud only | | End-to-end self-hostable (incl. dashboard) | yes | no — self-hosted LangSmith requires the paid Enterprise plan | yes (BYO observability stack) | yes (Apache framework + self-hosted Langfuse) | partial — OTel exporters point anywhere, but the polished Genkit Monitoring dashboard is GCP-only | | Dependency footprint | core module pulls 6 direct + 13 indirect (the OTel + SQLite stack) | n/a | monolithic module; go.sum is 1,523 lines (≈200+ unique upstream modules) | core + per-component modules under eino-ext | per-plugin Go packages under firebase/genkit/go/plugins/* | | MCP (Anthropic spec) | client + server; stdio, SSE, Streamable HTTP | client + tool-as-server, first-party | client only, via 3rd-party adapters (e.g. i2y/langchaingo-mcp-adapter) | client only, first-party | client + server, first-party (stdio / SSE / StreamableHTTP) | | A2A (Google spec) | client + server | not first-party | no | no | no — even though Google authored A2A, its Go support lives in the separate a2aproject/a2a-go SDK and in ADK Go, not in Genkit | | Multi-agent built in | Supervisor + Swarm in pkg/council | LangGraph: supervisor, hierarchy, swarm | agents package (ReAct, conversational); no supervisor/swarm/hierarchy | DeepAgent (supervisor + sub-agent delegation) + graph orchestration | Flows + tool-calling agents; supervisor/swarm not first-class | | Replay (record real run → deterministic re-run) | yes (record-to-fixture, replay anywhere) | LangSmith dataset replay (in the SaaS) | no (mock + conformance suite, not record/replay) | no | no documented offline fixture replay | | Eval framework | yes, in-tree | langchain.evaluation + LangSmith eval UI | none | none | yes, evaluators plugin | | License | Apache 2.0 | LangChain MIT; LangSmith proprietary | MIT | Apache 2.0 | Apache 2.0 |

galdor's distinctive position: OTel-native + a single-binary self-hosted dashboard + first-party MCP server + first-party A2A server, all in Go. None of the other four projects ship all of those today.

If your stack runs Python comfortably and you're happy paying for LangSmith, LangChain is the most mature option. If you need broad Go provider coverage today (more adapters than galdor's four), Eino is further along — at the cost of no OTel and no A2A. If you need Go and MCP server-side exposure and A2A interop in one place, galdor is currently the only framework that ships both first-party.

Sources (verified May 2026): langchain-ai/langchain, LangSmith self-host docs, tmc/langchaingo, cloudwego/eino + eino-ext, firebase/genkit/go/plugins/mcp, firebase/genkit/go/plugins, a2aproject/a2a-go.


Status

v1.0.0 released. Looking for early integrators.

The 10-phase roadmap is functionally complete: provider abstraction (Anthropic, OpenAI/MiniMax/Groq/Together/DeepSeek/vLLM/Ollama via BaseURL or [providerset](providerset/), Google Gemini, AWS Bedrock) · type-safe tools with reflection-derived JSON schemas · directed graph runtime with checkpoints, interrupt/resume and branch-map conditional edges · ReAct and Plan-and-Execute agent helpers · native OTel observability with embedded SQLite trace store, auto-WAL-checkpointing exporter, auto-stamped run ids, and an orphan-span warning banner · embedded web dashboard with live SSE, per-run DAG, time-travel · short-term memory windows + long-term memory backends (in-mem, SQLite/BM25, pgvector, qdrant, S3 Vectors) · provider-backed and HTTP/TEI embedders · Council multi-agent patterns (Supervisor, Swarm) · MCP client + server over stdio, SSE, and Streamable HTTP · A2A protocol (Google) · inline eval framework with LLM-as-judge · schema-bound structured output (a Go struct in, a decoded value out) · deterministic replay with prompt fingerprinting · per-provider retry/backoff, run/node timeouts, panic recovery, structured logging, goroutine leak gates, capability-aware validation · thinking-block strip middleware for OpenAI-compat thinking models.

What's next: real-world integration feedback. If you're shipping agents in Go and the table at the top resonates, try galdor on your stack and open an issue — the framework has covered the surface; the remaining edges only show up in actual deployments. The pragma-galdor retro is one such report, and it shaped most of v0.1.0; more would be welcome.

As of v1.0.0, the public API under pkg/ is stable under SemVer: breaking changes only land in a future v2. See [ROADMAP.md](ROADMAP.md) for full phase tracking and what's next.


Install

go get github.com/YasserCR/galdor@v1.0.0
# plus the provider(s) you need:
go get github.com/YasserCR/galdor/providers/anthropic@v1.0.0
go get github.com/YasserCR/galdor/providers/openai@v1.0.0
# or pick a provider at runtime via env var:
go get github.com/YasserCR/galdor/providerset@v1.0.0

The core module pulls only what it needs — providers, memory backends and protocol adapters live in their own Go modules so your dependency tree stays tight.

For the CLI + dashboard:

go install github.com/YasserCR/galdor/cmd/galdor@v1.0.0
galdor ui --db ./traces.db   # open http://127.0.0.1:7777

If galdor isn't found after installing, the go install bin directory isn't on your PATH — add it (export PATH="$(go env GOPATH)/bin:$PATH"), or run galdor doctor from the full path to diagnose your setup.


Quickstart

A complete ReAct agent in 20 lines:

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/YasserCR/galdor/pkg/agent"
	anthropic "github.com/YasserCR/galdor/providers/anthropic"
)

func main() {
	p, err := anthropic.New(anthropic.Config{APIKey: os.Getenv("ANTHROPIC_API_KEY")})
	if err != nil {
		log.Fatal(err)
	}

	answer, err := agent.Run(context.Background(), agent.Config{
		Provider: p,
		Model:    "claude-haiku-4-5",
	}, "What is the capital of Ecuador?")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(answer)
}

Swap anthropic for openai (works with MiniMax / Groq / Together / Mistral via BaseURL), google (Gemini), or bedrock and nothing else changes.


Highlights

Type-safe tools (generics + reflection-derived JSON Schema)

import (
	"context"
	"github.com/YasserCR/galdor/pkg/tool"
)

type weatherIn struct {
	City string `json:"city" jsonschema:"required, city to look up"`
}
type weatherOut struct {
	Temp float64 `json:"temp_c"`
	Sky  string  `json:"sky"`
}

weather := tool.MustNewTool("weather", "Look up the weather for a city",
	func(ctx context.Context, in weatherIn) (weatherOut, error) {
		return weatherOut{Temp: 18.5, Sky: "clear"}, nil
	})

reg, _ := tool.NewRegistry(weather)

answer, _ := agent.Run(ctx, agent.Config{
	Provider: p, Tools: reg, Model: "claude-haiku-4-5",
}, "How's the weather in Quito?")

In and Out are real Go types — the JSON schema published to the LLM is derived from In's reflection metadata. No magic strings, no interface{}.

Native OpenTelemetry — built in, not bolted on

import (
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"github.com/YasserCR/galdor/pkg/observability"
)

exporter, _ := observability.NewSQLiteExporter("./traces.db")
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
tracer := tp.Tracer("my-agent")

// Wrap your provider — every LLM call now produces a span.
p = observability.InstrumentProvider(p, tracer,
	observability.WithCaptureContent(true))

Every LLM call, tool invocation, and graph node becomes an OTel span following the GenAI semantic conventions. Inspect them with galdor ui or pipe them to your existing Datadog / Honeycomb / Grafana stack — same data, your choice of consumer.

Multi-agent: Supervisor and Swarm built in

import "github.com/YasserCR/galdor/pkg/council"

supervisor, _ := council.NewSupervisor(council.SupervisorConfig{
	Provider: p, Model: "claude-haiku-4-5",
	Workers: []council.Worker{
		{Name: "billing", Description: "handles invoices, refunds",
			Run: billingWorker},
		{Name: "technical", Description: "diagnoses bugs, outages",
			Run: technicalWorker},
	},
})

final, _ := supervisor.Invoke(ctx, council.SupervisorState{Input: userMessage})

A scripted-LLM routing supervisor that delegates each turn to specialists. See the full example: [examples/integration-support-bot](examples/integration-support-bot/).

Human-in-the-loop with InterruptBefore

g := graph.New[TransferState]().
	AddNode("validate", validate).
	AddNode("execute", execute).
	AddEdge(graph.START, "validate").
	AddEdge("validate", "execute").
	InterruptBefore("execute")  // ← pause for human approval

r, _ := g.Compile()
ckpt := graph.NewMemoryCheckpointer[TransferState]()

// Phase 1: run until the gate. Returns ErrInterrupted.
_, err := r.InvokeWith(ctx, init, graph.RunOptions[TransferState]{
	RunID: runID, Checkpointer: ckpt,
})

// Phase 2: human reviews and edits state.
ck, _, _ := ckpt.Load(ctx, runID)
decision := promptHuman(ck.State)  // your UI / Slack bot / etc.

// Phase 3: resume with the decision injected.
final, _ := r.Resume(ctx, graph.RunOptions[TransferState]{
	RunID: runID, Checkpointer: ckpt, OverrideState: &decision,
})

Auditable, safe-by-construction approval flows. See [examples/integration-approval-gate](examples/integration-approval-gate/).

Replay: paid-API → fixture → deterministic test

// One-time: record a real run with prompt/completion capture on,
// then export the recording.
//
//   galdor scry replay  -o fixture.json

// Forever after: replay the run for free in CI.
rec, _ := replay.LoadFromFile("fixture.json")
mock := replay.NewProvider(rec.Calls, replay.ModeStrict)

r, _ := agent.NewReAct(agent.Config{Provider: mock, Model: "...", Tools: reg})
final, _ := r.Invoke(ctx, state)
// If your prompts drifted, ErrPromptMismatch tells you exactly which call.

Regression tests for prompts and agents that don't hit the network and don't burn tokens. See [examples/integration-cost-tracked](examples/integration-cost-tracked/) for the complementary budget-enforcement pattern.

MCP server: expose your tools to Claude Desktop in 20 lines

import (
	"github.com/YasserCR/galdor/pkg/mcp"
	"github.com/YasserCR/galdor/pkg/tool/builtins"
)

func main() {
	now, _ := builtins.NewTimeTool()
	math, _ := builtins.NewMathTool()
	reg, _ := tool.NewRegistry(now, math, yourCustomTool)

	srv := mcp.NewServer(reg, mcp.ServerInfo{Name: "my-tools", Version: "0.1"})
	transport := mcp.NewStdioTransport(os.Stdin, os.Stdout)
	_ = srv.Serve(context.Background(), transport)
}

Build the binary, point Claude Desktop's claude_desktop_config.json at it, restart Claude Desktop. Your tools appear in the picker. Full instructions in [examples/integration-mcp-server](examples/integration-mcp-server/).

For long-lived daemons that many clients share, swap the transport — SSE for IDE-compatibility today, Streamable HTTP for the post-2024-11-05 spec:

// pre-2024-11-05 spec (the SSE transport Cursor/Claude Desktop still default to)
transport := mcp.NewSSETransport(":4000")
// 2024-11-05 spec (single endpoint, session id via Mcp-Session-Id header)
transport := mcp.NewStreamableHTTPTransport(":4000")

Pick a provider at runtime

import "github.com/YasserCR/galdor/providerset"

// Reads LLM_PROVIDER, LLM_API_KEY, LLM_BASE_URL, LLM_HTTP_TIMEOUT.
// Supports anthropic, openai, google, bedrock + 7 OpenAI-compatible
// aliases: groq, together, mistral, minimax, deepseek, vllm, ollama.
p, err := providerset.FromEnv()

The equivalent of LiteLLM for Go: one switch, every supported provider, no per-app boilerplate. Lives in its own module so the core stays lean. See [docs/concepts/providerset.md](docs/concepts/providerset.md).

Self-hosted embeddings via HTTP

import "github.com/YasserCR/galdor/pkg/embedder"

// Works against HuggingFace TEI, Infinity, vLLM-embeddings, or any
// OpenAI-compatible /embeddings endpoint. Stdlib-only, no CGO.
emb, _ := embedder.NewHTTPEmbedder(embedder.HTTPConfig{
    URL:   "http://localhost:8080",
    Shape: embedder.ShapeTEI,
})

Plugs into memory.Retriever directly; satisfies memory.Embedder. See [docs/concepts/embedder.md](docs/concepts/embedder.md).

Thinking-model output, sanitized

import "github.com/YasserCR/galdor/pkg/provider"

// Opt-in middleware that strips ... blocks emitted
// inline by OpenAI-compat thinking models (MiniMax, DeepSeek, Qwen).
// Handles closing tags split across stream deltas.
p = provider.StripThinkingBlocks(p)

Production hardening (Phase 10)

import "github.com/YasserCR/galdor/pkg/provider"

// Automatic retry with exponential backoff + jitter; respects the
// server's Retry-After header; never retries auth/invalid-request.
p = provider.Retry(p, provider.RetryConfig{
	MaxAttempts: 5,
	OnRetry: func(n int, d time.Duration, err error) {
		slog.Warn("retrying", "attempt", n, "delay", d, "err", err)
	},
})

// Per-run and per-node timeouts; panic recovery in nodes, tools,
// and hooks; structured logging via slog.
final, err := r.InvokeWith(ctx, state, graph.RunOptions[State]{
	Timeout:     2 * time.Minute,
	NodeTimeout: 30 * time.Second,
	Logger:      slog.New(slog.NewJSONHandler(os.Stdout, nil)),
})

Architecture (at a glance)

┌─────────────────────────────────────────────────────────────┐
│  CLI (galdor scry/ui)    Web dashboard with SSE + per-run DAG│
├─────────────────────────────────────────────────────────────┤
│  Eval Framework  │  Replay Engine  │  Time-travel UI        │
├─────────────────────────────────────────────────────────────┤
│  Agent Runtime (graph executor over goroutines + channels)  │
├─────────────────────────────────────────────────────────────┤
│  Tools  │  Memory  │  Embedder  │  Council  │  MCP  │  A2A  │
├─────────────────────────────────────────────────────────────┤
│  Provider Abstraction + Providerset (env-driven selection)  │
├─────────────────────────────────────────────────────────────┤
│  Observability Core (OTel-native, embedded SQLite backend)  │
└─────────────────────────────────────────────────────────────┘

See [ARCHITECTURE.md](ARCHITECTURE.md) for the full module map and [docs/adr/](docs/adr/) for design decisions.


Complete examples

Each one is a runnable end-to-end demo with its own README.

|

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.