Open-source project
ATaC-team/ATaC avatar
ATaC-team/ATaC

ATaC: a graph-first tool runtime for agent workflows

Record and Replay AI Agent Trajectories.

309 stars11 forksPythonMIT

At a glance

What is it?
ATaC registers local and MCP tools in one service and lets agent-authored LangGraph code call them by name. It is small, Python 3.13 only, and the README is thinner than the package layout suggests.
Who is it for?
Adopt ATaC if you already write LangGraph workflows and want one registry that spans local tools and MCP servers, with a CLI and an audit UI in the same package. Skip it if you are on Python 3.12 or older, since pyproject.toml requires >=3.13, or if you need documented rollback, versioning or permissions for tool calls, none of which the README describes.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 158 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem ATaC targets: tools that never get reused

An agent that can call a shell command, a database query and an MCP server usually ends up with three registration paths and no shared naming scheme. Each new workflow re-declares the same capabilities. ATaC's answer is a single runtime object, AtacService, that holds every tool the agent may call, whether the tool is a local Python function or something exposed over MCP. The README frames the goal as turning repeated tasks into "reusable, maintainable graph workflows".

The intended user is a Python engineer already working with LangGraph who wants the workflow itself to be code, not a prompt. The project describes itself in pyproject.toml as a "Graph-first tool runtime for agent workflows", and the repository topics include agent-infra, mcp and skills. If your agents are prompt-driven and you have no interest in compiled graphs, this runtime adds a layer you will not use.

How registration and tool_call fit together

The mechanism has two halves. On the setup side, you build an AtacService and hand it tools. The README recommends the native langchain_core.tools.tool decorator for local functions and the official langchain_mcp_adapters.client.MultiServerMCPClient for MCP servers, then a single call to service.register_langgraph_tools(...) for both. That call is the funnel: after it, the two kinds of tool are indistinguishable to the rest of the runtime.

On the execution side, graph code imports get_service from atac and calls service.tool_call(name, arguments). The name is the one the tool was registered under. In the README example the node function run_bash calls tool_call("bash", {"command": ...}) and returns a dict that becomes the next state. So the data flow is: register once at import time, compile a LangGraph StateGraph, and let each node reach back into the service by name rather than closing over the tool object. That indirection is the design choice worth noticing. It keeps graph code free of imports from your tool modules, which is what makes the graph portable, but it also means a typo in the tool name fails at call time, not at import time.

The README also notes one async trap explicitly. If client.get_tools() returns an awaitable and you are already inside a running event loop, the example raises a RuntimeError telling you to await the call before registering. That is a real constraint in async services, and the README handles it rather than hiding it.

Installing atac and running a first graph

The README gives one install command, distributed as a uv tool. It puts an atac executable on your path, matching the [project.scripts] entry atac = "atac.cli.main:cli" in pyproject.toml.

bash
uv tool install atac

After that, the runtime is a library. The README's bootstrap pattern is a module that builds the service once and exposes a getter, so graph code can import it without re-registering tools. Note that the README's own example list points at absolute paths on the author's machine, such as /Users/mob/ATaC/example/demo/bootstrap.py, so you will be reading the example directory in the repository rather than those links.

The first real use is running a compiled graph by module path. The README shows the SDK call with a myapp.graphs:build_graph target, which means the string is resolved as module:attribute at run time.

python
from myapp.bootstrap import get_service

service = get_service()
result = service.run_graph("myapp.graphs:build_graph", {"who": "mob"})

The second argument is the initial state passed into the graph, and result holds whatever the graph returns. The example/langgraph directory in the repository contains run_graph_demo.sh and run_graph_sdk.py, which are the concrete entry points to compare your setup against. The README does not document the CLI's own subcommands, so treat the shell script as the reference for command-line invocation.

Python 3.13 only, and other limits you should weigh

pyproject.toml sets requires-python = ">=3.13" and lists only the 3.13 classifier. That is a hard floor. Teams still on 3.11 or 3.12 cannot install this without a runtime upgrade, and the dependency set (langchain-core>=1.2.17, mcp>=1.26.0, pydantic>=2.12.5) pins you to recent major versions of those libraries, so an existing project on older langchain-core cannot simply add atac alongside it.

The second limit is documentation depth. The README covers registration, graph authoring and one SDK call. It does not describe what happens when a registered tool raises, whether a failed tool_call aborts the graph or returns an error into state, how the service behaves across concurrent graph runs, or whether tool calls are logged. There is an audit-ui directory and a Makefile target ui-build that runs pnpm --dir audit-ui build, which suggests an inspection interface exists, but the README never explains what it records or how to launch it. Anyone evaluating ATaC for production should treat that gap as the main unknown.

Third, the repository layout implies a tested project (tests/, a Makefile with lint and test targets, ruff configured with C4, E, F, I, PERF, UP) but the README does not state a support policy or a compatibility guarantee for the graph API. Version 1.0.3 is the current release in pyproject.toml, and the CHANGELOG.md at the repository root is the place to check what moved between 1.0.1 and v1.0.3.

Where ATaC sits next to LangGraph alone

The obvious alternative is using LangGraph by itself. With plain LangGraph you pass tools directly into the graph or bind them to a model, and the graph file imports those tools. ATaC's difference is the registry: tools are registered into a service object at bootstrap, and graph code resolves them by string name through get_service().tool_call(...). That decoupling is the whole product. It means the same graph module can run against a different set of registered tools without editing the graph, which is what makes an agent-generated graph portable across environments.

The cost is indirection and a runtime dependency. Plain LangGraph has no service singleton to initialize before the graph can run, and no naming contract to keep in sync between registration and call sites. If your tools are few and stable, the registry buys you little. If your agents generate graph code that has to run against whatever tools a given deployment has registered, the indirection is the point. The README's own recommended path, using the native LangChain decorator and the official MCP adapter rather than ATaC-specific wrappers, suggests the project intends to stay thin on top of those libraries rather than replace them.

Maintenance, release cadence and the MIT licence

The last push to the default branch was on 2026-04-14, which is five months before today's date, so this is not a repository with current activity. The releases are clustered: 1.0.1 on 2026-03-09, v1.0.2 on 2026-03-10 and v1.0.3 on 2026-03-19. Three releases in eleven days, then nothing pushed since mid-April. Read that as a burst of work followed by a quiet period rather than a steady cadence, and plan your upgrade path accordingly: there is no evidence of a long-term support line or a deprecation policy.

The licence is MIT, declared in the README badge and in the LICENSE file at the repository root. MIT permits commercial use and modification with the copyright notice retained, but this is a description of the licence text, not legal advice; if you redistribute atac inside a product, have your own counsel confirm the notice requirements. The dependencies carry their own licences, and langchain-core, mcp and fastapi are separate projects with their own terms. Upgrade cost is dominated by those dependencies rather than by atac itself, since the package is small and its public surface in the README is three names: AtacService, register_langgraph_tools and run_graph.

What the README does not answer

Two questions come up immediately when reading the registration example. First, tool name collisions. The README registers a local bash tool and then a list of MCP tools through the same call, and never says what happens if an MCP server exposes a tool with the same name as a local one. Given that tool_call resolves by string, that collision is a real failure mode and the documentation is silent on it.

Second, the audit UI. The repository ships audit-ui/ and packages ui_dist assets into the wheel, and the Makefile builds it with pnpm, but the README never tells you how to open it or what it stores. If you are evaluating ATaC because you want a record of what your agent did, the README does not yet support that evaluation. The CHANGELOG.md and the tests/ directory are the places to look before you rely on it.

Editorial conclusion

Adopt ATaC if you already write LangGraph workflows and want one registry that spans local tools and MCP servers, with a CLI and an audit UI in the same package. Skip it if you are on Python 3.12 or older, since pyproject.toml requires >=3.13, or if you need documented rollback, versioning or permissions for tool calls, none of which the README describes. Before committing, verify that service.run_graph resolves your own module path, and read the CHANGELOG for what changed between 1.0.1 and v1.0.3.

Frequently asked questions

What does ATaC stand for?

The README does not expand the name. It presents ATaC as a tool runtime for agent workflows, with the package published on PyPI as atac and described in pyproject.toml as a graph-first tool runtime.

How do I install ATaC?

The README gives a single command, uv tool install atac, which installs the atac executable defined in pyproject.toml. Note that the package requires Python 3.13 or newer.

Does ATaC work with MCP tools?

Yes. The README recommends building MCP tools with the official langchain_mcp_adapters.client.MultiServerMCPClient and registering the resulting list through service.register_langgraph_tools(...), the same call used for local tools.

Which Python version does ATaC need?

pyproject.toml sets requires-python to >=3.13 and lists only the Python 3.13 classifier, so older interpreters are not supported by the published package metadata.

Official sources

  1. ATaC-team/ATaC on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Community notes

Community notes