ea_analyze
ea_analyze reads a Sparx EA repository and reports on it. It answers questions about what the model contains and how its parts connect: which stereotypes are in use, how connectors are distributed, what is reachable from an element, who changed what in a date range and, when no purpose-built operation fits, what a direct query against the repository returns. It has 13 operations in five groups. Twelve only read. One, execute_sql, can also change the model, and the assistant should ask you before it does.
Skills call these operations for their own jobs: ea-model-hygiene uses the graph operations for pre-delete safety, ea-change-management uses the audit-trail operations, ea-stakeholder-reporting uses the business view and the summaries, and ea-modeling and the ea-mdg-* skills use the summaries and direct queries. If you need an impact or coverage analysis, ask for it in terms of these operations and review the result.
All of these operations are Deterministic: AI Power Tools computes the answer, with no AI judgment involved, and the same question on the same model state gives the same result (Where the AI decides and where AI Power Tools decides). If the model changes, the answer can change, and that is still deterministic. What varies is the question the AI chooses to ask and how it reads and explains the answer. Treat the AI's interpretation as the part to check.
| Group | Operations | What they answer |
|---|---|---|
| Summaries | summarize_connector_patterns, summarize_stereotype_usage, summarize_tagged_value_usage, summarize_observed_metaclasses |
"What does this model actually contain?" Census counts for stereotypes, connector patterns, tag usage and element types |
| Graph and traceability | trace_connectors, find_paths, get_traceability_tree |
"What is connected to what?" Three views of the connector graph |
| Business view | get_element_business_view |
"Describe this element in business terms." |
| Audit trail | get_user_activity, get_updates_in_range |
"Who changed what, and when?" |
| Direct queries | execute_sql, list_ea_tables, describe_table |
"Anything else." Direct queries against the repository, plus the schema reference that keeps them correct |
What applies to every operation
- Every operation except
list_ea_tablesanddescribe_tableneeds Enterprise Architect running with a project open. Without that, the operation fails with a message that names the operation that remedies it (launch_ea, oropen_model/create_model). See ea_repository. - Elements are identified by their numeric element id. If you name an element rather than give an id, the assistant looks the id up first with a name search in Elements.
- In read-only mode (see How tools and operations work),
execute_sqlstill runs but refuses any statement that would write. The other twelve operations never write, so read-only mode does not affect them. - An unrecognized parameter is refused with a suggestion, and a missing required parameter is reported. The assistant corrects these without your involvement.
Summaries
Four census operations. Each reads the whole repository in a small, fixed number of passes, so cost depends on the number of stereotyped elements and connectors, not on how many questions you ask. They are the first calls to make against an unfamiliar model, and they feed the skills that write rulesets, author modeling languages and plan reports.
Three of the four report the same data in two views:
- The plain view uses the stereotype name stored on each element or connector: a bare name with no modeling-language prefix, and only the first stereotype when an element carries several.
- The resolved view uses the stereotype applications EA records, which carry the language-qualified name (
WBA::WBABusinessApplication). It can tell a stereotype that comes from a modeling language from an ad hoc stereotype typed in by hand, and it sees every stereotype on an element that has several. Each application is marked as bound to a language, ad hoc, or (for an unstereotyped end) none.
| Operation | What it does | When you would use it | Changes the model | Logic |
|---|---|---|---|---|
summarize_connector_patterns |
Counts every distinct combination of source-element stereotype, connector stereotype and target-element stereotype across the repository, most frequent first. It also flags connector stereotype names that are used both bound to a language and ad hoc | Learning which kinds of element are really joined to which, and by what kind of connector, before writing connector rules or Quick Linker rules | No | Deterministic |
summarize_stereotype_usage |
Counts elements by stereotype and EA element type. The resolved view also flags names used both bound to a language and ad hoc, and counts elements that carry more than one stereotype | Sizing and orienting an inventory; spotting drift between a modeling language and what people actually typed; choosing stereotypes for a ruleset or a report | No | Deterministic |
summarize_tagged_value_usage |
For each tagged value name, reports how many elements have it, how many of those are actually filled in, how many distinct values appear, and the first 20 sample values. Optionally limited to one stereotype | Checking whether a mandatory tag is really being filled in; inferring picklists for a modeling language from tags with few distinct values | No | Deterministic |
summarize_observed_metaclasses |
For one stereotype, lists the EA element types that host it and flags it when there is more than one | Finding mis-typed elements before a modeling language is authored or a ruleset written | No | Deterministic |
Notes
- Presence is not coverage. EA creates a tag row when a stereotype is applied, whether or not anyone fills the value in. A tag that exists on eight elements and is filled on none is a tag that says nothing anywhere.
summarize_tagged_value_usagereports both numbers; use the filled-in count as the coverage figure. - Ad hoc connector stereotypes are normal. Connector stereotypes in real models are often free text (
Uses,realizes) even when the elements are bound to a modeling language. An ad hoc connector end is common and is not an error. - Counts can legitimately differ between views. The plain view counts elements. The resolved view counts stereotype applications, so an element with two stereotypes counts twice. The resolved connector counts can therefore add up to more than the number of connectors; use the plain view for connector totals.
- Stereotype names are matched exactly.
summarize_tagged_value_usageandsummarize_observed_metaclassestake the stored plain name (WBABusinessApplication, notWBA::WBABusinessApplication) and look only at an element's first stereotype. A name that matches nothing returns an empty result, not an error. - Scope of tags. Tag usage covers element tags only. Tags on connectors, attributes and operations are not counted. A tag a stereotype defines but nobody has created does not appear, so absence from the result is not proof the tag is unused.
- A stereotype that appears on more than one EA element type is flagged as a governance signal. A modeling language normally binds a stereotype to one element type, so a spread usually means elements were created with the wrong base type.
Graph and traceability
Three operations read the connector graph. They are not variations on one query. Each answers a different question and returns a different shape, but they share one engine, so they share limits and the way a connector type is matched.
Choosing between them
| You are asking | Use | You get |
|---|---|---|
| "What is around this element?" | trace_connectors |
A flat neighborhood: the elements within a number of hops, and the connectors between them. A bag of relationships, not a set of routes |
| "How do these two elements connect?" | find_paths |
Every shortest route between two elements, as alternating element and connector steps |
| "What hangs off this element along one relationship?" | get_traceability_tree |
A rooted tree following one set of connector types in one direction, each child labeled with the connector that reached it |
Rules of thumb:
- Blast radius, dependency graphs, "what depends on this before I delete it": use the neighborhood. Walking upstream one hop lists what points at the element.
- "Is there any relationship between these two, and how": use paths. This is also the tool for explaining a surprising dependency.
- Requirement-to-realization chains, service decomposition, "what does this roll up to": use the tree, and name the connector type.
Shared limits
The graph operations stop early rather than run without bound. Each has a depth limit (a default of 4 hops for the neighborhood, 5 for paths and 3 for the tree, never more than 10), a cap on the number of elements collected (2,000 by default) and a time limit (8 seconds by default). A result marked as truncated is partial. Narrow the depth or the connector types and run it again; do not report a truncated result as complete.
The connector filter accepts either a connector stereotype (realizes, dependsOn) or an EA connector type (Association, Realization). A value matches either, so you do not need to know which one holds it. Stereotype names are compared as stored, so the plain name and the language-qualified name are different strings.
Because the engine reads the connector graph in bulk rather than visiting elements one by one, it is the preferred route for traversal. The slower, element-by-element walk, traverse_element_subgraph in Elements, resolves modeling-language display names but is limited to depth 5.
| Operation | What it does | When you would use it | Changes the model | Logic |
|---|---|---|---|---|
trace_connectors |
Returns the connected sub-graph within a number of hops of one element: its elements and the connectors between them. Direction can be downstream (with the arrow), upstream (against it) or both, and can be limited to chosen connector types | Impact analysis before a change or delete; dependency and reporting chains; getting connector detail for a neighborhood in one call | No | Deterministic |
find_paths |
Returns every shortest path between two elements, as alternating element and connector steps. Connectors are followed in both directions, and each step records whether it was crossed with or against its arrow | "How does system A reach system B"; "is there any relationship at all between these two"; tracing a requirement to its implementation | No | Deterministic |
get_traceability_tree |
Returns a rooted tree of everything reachable from an element along the chosen connector types, in one direction | Requirement-to-realization chains; service decomposition; "what does this element roll up to" | No | Deterministic |
Notes
trace_connectorscollapses parallel connectors between the same ordered pair of elements into one, so its connector count can be lower than the number of connectors in the model. A root element that does not exist returns an empty result, not a not-found error.find_pathsfollows connectors both ways, on purpose. A route from a business process to the system that implements it usually crosses at least one connector against its arrow, and a search that respected direction would report no path for a pair that is plainly related. Read the direction on each step together with the element on either side.find_pathsreturns shortest routes only, all of equal length, up to a cap of 20 by default. A longer route that exists but exceeds the depth limit is reported as no route.- "No route" and "no such element" look the same. An unreachable target, a disconnected component and an element id that is not in the model all return an empty result. That is a valid answer, not a failure. If an empty answer is surprising, confirm the ids.
get_traceability_treeneeds a connector filter in practice. Without one it is a neighborhood graph in a tree's shape, andtrace_connectorsdoes that better. Always name the connector types.- Cycles and diamonds. A branch is cut only when an element already appears above it on the path from the root. An element reached by two independent routes appears under both parents, so a tree can show more nodes than the underlying graph has elements. A cut element is marked as a cycle. It is a cut branch, not a leaf: do not report it as "nothing further".
- Sibling order in the tree follows the order the connectors were read and carries no modeling meaning.
Business view
| Operation | What it does | When you would use it | Changes the model | Logic |
|---|---|---|---|---|
get_element_business_view |
Returns one element in business language: its type as a display term, its tagged values as label and value pairs, and each of its connections as a short phrase ("uses", "used by") | Drafting stakeholder summaries, one-pagers and answer cards without exposing technical names | No | Deterministic |
The element and each connected element are read one at a time, so this operation suits single elements, not sweeps. For anything wider, use the summaries or a neighborhood trace.
Notes
- Display terms come from the same lookup as
resolve_display_termin Display terms. Language-qualified forms such asArchiMate_ApplicationComponentare matched against the plain name. - The label of a tagged value is its display term only when the modeling language defines one. Otherwise the label is the tag name. Do not assume a friendly label is always present.
- An element with no stereotype falls back to its EA element type. For an element that carries several stereotypes, which one drives the display term is not specified, so check the result for such elements.
- Connection detail covers every connector on the element in both directions, but not the connected elements' own connections. For more than one hop, use
trace_connectors.
Audit trail
Two repository-wide operations answer "what changed" and "who changed it". Both read the modification date that EA stamps on elements, packages and diagrams. Neither takes a package scope. To answer a package-scoped question, the assistant filters the returned rows by package or uses a direct query.
| Operation | What it does | When you would use it | Changes the model | Logic |
|---|---|---|---|---|
get_user_activity |
Counts how many elements and diagrams each author last modified in a date range, with each author's latest modification time | Audit review; handover; "who has been working in this model" | No | Deterministic |
get_updates_in_range |
Lists the elements, packages or diagrams created or modified in a date range, one row per item with name, type, owning package and modification time. Can be limited to elements, packages or diagrams, or return all three | "What changed this week"; building a change log; scoping a review | No | Deterministic |
Dates. Both operations accept a date alone, a date with minutes or seconds, or an ISO-8601 timestamp.
- A bare end date means the whole day: an end of
2026-09-23runs to 23:59:59. A bare start date means midnight. - A time zone designator is ignored, not converted. EA stores local times with no zone, so the wall-clock value is used as given.
get_updates_in_rangereports when it ignored part of an input. - A date that cannot be read, or a start after the end, is an error. It never returns an empty result.
Notes
- The author is a personal identifier.
get_user_activityreports the login name of the person who last saved each item, not a chosen display name. Do not copy it into shared documents without cause. - Counts are by last modifier. An item edited by two people in the range is credited to whoever saved last, so earlier contributors are understated.
- What is covered. Elements (including the rows EA keeps for packages) and diagrams. Connectors, attributes, operations and tagged values are not tracked on their own. A tag change usually updates the owning element's modification time, but that is EA's behavior, not something the operation guarantees.
- It says that something changed, not what. For field-level detail, compare against a baseline with
compare_baselinein Baselines. - With the whole-model option, a package can appear twice, once as an element and once as a package.
- The result is not paged. A wide range on a large model returns every row; narrow the range.
- Items changed through a direct query carry whatever modification date that query wrote.
Direct queries
Direct access to the repository database, and the reference material for using it correctly. This is how the assistant answers questions no purpose-built operation covers: custom joins, data-quality checks, a look inside EA's own bookkeeping. EA's database naming is inconsistent, so guessing a column name is the usual cause of a failed query. describe_table and a built-in check in execute_sql exist to stop guessed names from reaching EA.
| Operation | What it does | When you would use it | Changes the model | Logic |
|---|---|---|---|---|
execute_sql |
Runs a database statement against the repository through EA and returns the rows (and optionally EA's raw XML). Accepts selects and also statements that insert, update or delete | Anything the typed operations do not cover | Can. Yes, when the statement is a write and writes are permitted. Writes are permitted unless refused | Deterministic |
list_ea_tables |
Lists every repository table the server knows, with its primary key column. Reads a built-in catalog, so it works without EA running | Finding which table holds a kind of data | No | Deterministic |
describe_table |
Returns the column names and types of one table, its key, the columns that need special quoting, and notes on the table's quirks. Works without EA running | Before writing any query whenever a column name is uncertain | No | Deterministic |
Writing through direct queries: ask first
execute_sql is the one operation in ea_analyze that can change the model, and it is not limited to selects. Writes are permitted by default. The assistant should ask you before running any statement that is not a select, and should pass the option that refuses writes for every query meant only to read.
- How the refusal works. The server looks at the first word of the statement against a fixed list of writing verbs (insert, update, delete, drop, alter, create, truncate, replace, merge, grant, revoke). If the statement starts with one and writes are refused, it stops before reaching EA. Read-only mode forces writes to be refused. This is a convenience guard, not a security control: a statement that starts with some other word and ends in a write is not caught, so do not rely on it for untrusted queries.
- A write bypasses EA's own safeguards. It goes to the database directly. An open EA session does not resync, so it can disagree with what is now stored until the model is reloaded, and related caches can drift. A raw write also skips the consistency EA's own editing maintains. For example, every package has a mirror row among the elements, so a hand-written change to one can leave the two out of step.
- Prefer the typed operations in ea_model and ea_diagram for any change. If a query write is unavoidable, take a baseline first (see Baselines), then reload the affected diagrams and re-read the result.
- Whether a write succeeds is up to EA. The server does not check it.
The column check
Before a statement reaches EA, the server checks the column names against its catalog of the repository schema. A bad column name costs a round trip, and a statement EA cannot parse can raise a dialog in EA that blocks the session. The check is a pre-filter, not a full parser: it can miss errors in complex statements and occasionally flags a legitimate name in an unusual construct, in which case the assistant can switch it off for that call. It never bypasses the write rules above. See SQL guard.
Notes
- The query language is that of the repository's database: SQLite for a local
.qeaor.qeaxfile, Jet for.eap, and the database server's own dialect for a server connection or a cloud connection. The assistant writes for the dialect it finds. - A row limit shrinks the response, not the work EA does. To make a query itself cheaper, the assistant adds the database's own row limit to the statement. The server does not rewrite the query.
- An unreadable result is an error, not an empty result. When EA returns a reply the server cannot read as XML, including a reply larger than the server's 64 MB XML limit, the call fails with an error and returns no rows. Narrow the query or add a row limit to the statement. A blank reply is still zero rows, and EA gives a blank reply both when a query matches nothing and for some queries it could not run, so an empty answer can still hide a failed query. If an empty answer is surprising, cross-check with a simple count.
- An empty value and a missing value look the same. EA returns a database NULL and an empty text identically, so the rows a query returns cannot tell them apart. To tell them apart, the test has to be inside the query itself, for example by counting the rows where the value is NULL.
- A call that appears to hang usually means EA has raised a dialog, which the server cannot see. With computer use the assistant reads the dialog in EA's window, uses its message to correct the query, dismisses it and retries. Without computer use, you take a screenshot of the dialog and paste it into the conversation so the assistant can analyze it, then dismiss the dialog so processing can continue (Blocking dialogs in How tools and operations work).
- The catalog covers 98 tables from one EA schema build. A repository created by a newer EA build can hold tables or columns the catalog does not list, and the check does not block a table it does not know. Column types are shown in SQL Server terms, while
.qeaand.eapfiles store the same columns in their own types. describe_tabledescribes structure, not meaning. Which table to use for which kind of information is covered in the ea-modeling skill.