Skip to main content
Glama
alexwoolford

SEC Ownership Graph

by alexwoolford

SEC Ownership Graph

Every SEC ownership filing as one graph, keyed on CIK — so you can ask who moved first on a target, who operates as a coalition, and who really controls an issuer. Built on Neo4j. Every answer cites an SEC accession number, and abstains when the data doesn't support one.

Data: Schedule 13D/13G (beneficial ownership), Form 3/4/5 (insiders and directors), Form 13F (institutional holdings). Straight from EDGAR — no paid data vendor. Depth per layer, and what that does and doesn't support, is in Honest limits.

New to SEC filings? docs/data_sources_and_forms.md explains what each form is, what triggers it, and exactly which node or edge it became — including which four edges are derived rather than filed. Start there if the form names above aren't familiar.


The demo in one question

"Who can actually move this company — and can you prove it from two independent filings?"

$ make demo

Stake + board seat — issuers where a holder clears a Fed control-presumption tier
AND currently sits on the board. Two independent filing types agreeing:

  TICKER        SIZE   STAKE  13D    SEAT     HOLDER
  BRK-B      $479.9B   37.0%  2024   2026-05  BUFFETT WARREN E
  TMUS        $92.6B   74.3%  2013   2025-10  DEUTSCHE TELEKOM AG
  CHTR        $22.4B   26.1%  2014   2026-06  Liberty Broadband Corp
  RDDT        $20.5B   61.5%  2024   2026-06  Huffman Steve Ladd

The stake comes from a Schedule 13D; the board seat comes from Form 3/4/5. A screener sells you either list — the pairing is the finding, and it is the join a single-table query cannot do for you. Note the two date columns: Liberty Broadband declared 26.1% of Charter in 2014, and its director was on file in 2026. A 13D has no exit obligation below 5%, so an old stake proves nothing alone; the current seat is what corroborates it.

And when there is nothing to say, it says so — ten of ten mega-caps abstain on control:

$ control_chain("AAPL")
No graph-grounded answer for 'Apple Inc.' (no_verified_control_chain).
Issuer has no >=50% verified 13D control edge on a chain.

→ Full walkthrough: docs/demo_script_governance_desk.md (five questions, ~10 minutes, including what this cannot tell you.)


Related MCP server: edgar-mcp

What is actually graph-native here

Three questions need a relationship followed to a depth the data decides — one declarative Cypher pattern, executed next to the data:

Question

Cypher

Why a traversal

Who ultimately controls this issuer?

(root)-[:CONTROLS|SAME_ENTITY_AS*1..N]->(target)

chain depth is unknown up front

Who operates as a coalition with X?

(seed)-[:CO_TARGETS*0..N]-(m)

the component is emergent, not a fixed join

Who bridges these two boards?

shortestPath((a)-[:SHARES_DIRECTOR*..N]-(z))

reachability, not "who sits on ≥2 boards"

Stated precisely, because overclaiming here loses technical audiences: SQL cannot express a single query whose traversal depth is decided by the data. A warehouse can still reach the same answers with a recursive CTE. The advantage is one indexed declarative pattern next to the data — not that the answer is unobtainable elsewhere.

make prove runs both legs for real — Cypher inside Neo4j, and genuine WITH RECURSIVE CTEs over identical rows — and publishes the agreement, with timings for both. At this scale SQL is faster on the chain (~0.7 ms vs ~13 ms) and slower on the path (~20 ms vs ~1 ms). Anyone evaluating this should read those numbers before the prose.


Quickstart

# 1. Install (project-local venv — required for the MCP launcher)
uv venv && source .venv/bin/activate
uv pip install -e ".[dev,llm]"   # or: make install
cp .env.sample .env              # fill in NEO4J_PASSWORD and SEC_USER_AGENT

# 2. Check preconditions in seconds, before committing to a multi-hour build
make preflight

# 3. Point at a graph. Either build it (hours — downloads from EDGAR):
make build                  # dry-run: prints the full phased plan + preflight, writes nothing
make build-exec             # for real

# 4. Ask it things
make demo                   # the activist convergence screen
make prove                  # graph vs SQL, head to head
make smoke-mcp              # curated tool catalog + demo queries against the live DB
make serve                  # curated MCP tools over stdio (or use Cursor — see below)

What a build needs

Neo4j

Enterprise (or Docker neo4j:enterprise) + the GDS plugin. Phase 0 runs CREATE DATABASE; the density gate runs gds.wcc.write. Community/Aura expose one database — use make build-exec DB=neo4j.

SEC_USER_AGENT

Required. SEC fair access rejects generic agents with HTTP 403. The built-in default is a placeholder on the reserved domain example.com; make preflight refuses to start until you set a real contact string.

OpenAI key

Effectively required for a fresh build. reference/control_figures.csv covers only the EDGAR window it was exported from, so any 13D filed since needs classifying — and the build runs that gap fill unconditionally rather than leaving those edges unclassified (an unclassified edge silently vanishes from control and influence answers). It is cheap and scales with the gap: a regex resolves 93% of edges for free, so only the remainder reaches gpt-4o-mini — **$0.21 to classify all 10.6k edges**, cents for a year of drift, and $0 when the CSV is already current. Pass --skip-uncovered to build without a key and accept a knowingly incomplete layer.

Time & disk

Several hours, ~20 GB. Dominated by the ~8,000-issuer 13D/G crawl and the 13F load, both bounded by SEC's 10 req/s ceiling.

make preflight checks every one of these. Each used to surface only after minutes-to-hours of crawling, as a generic non-zero exit from a child script.

Curated MCP (Cursor / Claude Desktop)

Seven read-only tools — activist_convergence, campaign_timeline, activist_coalition, ownership_snapshot, control_chain, board_interlock_path, get_secgraph_schema. Curated, not raw text2cypher: no Cypher passthrough and no write path, so the scrubs and thresholds that make the answers correct cannot be bypassed.

Cursor: open this repo; .cursor/mcp.json uses ${workspaceFolder} and scripts/run_ownership_mcp.sh so a clone needs no path edits after .venv exists. Enable secgraph-ownership, reload MCP, then ask the demo questions in natural language. If a user-level ~/.cursor/mcp.json also defines secgraph-ownership, point it at the same launcher (bare python scripts/serve_ownership_mcp.py fails outside the venv).

Claude Desktop: root .mcp.json is the same shape; Claude does not expand ${workspaceFolder} — set command once to the absolute path of scripts/run_ownership_mcp.sh (the launcher still finds .venv relative to the repo).

make smoke-mcp proves the tool catalog and the demo queries against a live secgraph DB without an MCP client.


How it is built

Layer 3  MCP server        curated read-only tools ─► Claude Desktop / any agent
Layer 2  Query core        traversals + evidence + abstain (transport-agnostic)
Layer 1  Reproducible DB   phased build, density gate, freshness manifest

make build runs the phases in order, aborting on the first failure: create the database → load the filer universe → stage and load Form 3/4/5 insiders → density GO/NO-GO gate (fail-closed: the build stops if the insider layer is too sparse to support the wins) → materialize the derived edges (SHARES_DIRECTOR, CONTROLS, SAME_ENTITY_AS, CO_TARGETS) → load 13D/13G and 13F. A successful run writes results/secgraph_freshness.json, which every served answer reports as its "as of" date.

schema/graph_schema.yaml is the single source of truth — 4 node labels, 10 relationship types. tests/unit/test_schema_consistency.py scans every .py file and fails the build if any Cypher references something undeclared.

Architecture detail: docs/reference_architecture_secgraph.md What the forms mean and where each element came from: docs/data_sources_and_forms.md Bloom demo runbook (six acts, ~18 min): docs/demo_runbook_bloom.md Bloom visualization build brief: docs/bloom_perspective_spec.md Field-level schema (generated): docs/graph_schema.md


Honest limits

Read these before demoing — they are part of what makes the rest credible.

  • No prediction. The alpha question was tested and came back null. Efficient markets; 13Ds are public. This is a structural and temporal map, not a signal.

  • Size is a threshold, not a market cap — and there are two measures. size_usd is what filters and ranks: it prefers total_assets_usd, a filed balance-sheet total from the SEC Financial Statement Data Sets (63% of the universe), and falls back to institutional_value_usd, one quarter of 13F holdings (75%). Combined coverage is 83%; size_source records which applied, and 17% have neither and are excluded from size-filtered results rather than ranked. Each has a distinct limit: 13F measures free float, so it understates concentrated-ownership issuers and counts ETFs; total assets are not comparable across sectors — a bank's assets are its balance sheet, so JPMorgan's $4.4T is not "bigger than" a $200B industrial in any meaningful sense. Still no revenue and no true market cap, so this does not support leverage or coverage ratios.

  • Activist screens trade recall for precision. Gated to a curated franchise list; ungated detection is dominated by micro-cap founders crossing 5% and by filing-group artifacts (one manager filing through seven affiliated vehicles). First-time activists are missed by design.

  • Only 13D/13G dates are a time series. Board and officer edges are a keep-latest snapshot; 13F has a 2024 coverage step-up. Don't read trends into them.

  • 13D/13G history is capped, so "1994→present" holds only for light filers. The crawl reads each issuer's filings.recent (~1,000 most recent filings) and takes at most 40 Schedule 13D/G per subject. For a company that files hundreds of Form 4s a year, recent may reach back only a year or two, and its older 13D/Gs are invisible. Small caps — where the control chains are — get the full history; mega caps do not.

  • At this scale, a warehouse is a real alternative. The three wins run on ~1,100 derived edges, measured depth is overwhelmingly 1-2 hops with a maximum of 3, and a recursive CTE answers all three in single-digit milliseconds. The honest case for a graph here is authoring cost per new question, GDS algorithms with no SQL equivalent (Louvain, betweenness), and the curated serving layer — not tractability. Tractability would only become the argument at a far larger universe than 8,000 tickered issuers.

  • Rebuilds drift, by construction. The staging window resolves against the run date, and EDGAR keeps accruing filings, so a rebuild today will not reproduce the figures below exactly. New 13Ds can also remove a convergence hit, because the screen measures a total span rather than a rolling window. Compare against results/secgraph_freshness.json (as_of) before concluding something broke.

  • Chain depth is a small-cap signal; single-hop control is not. 39 of 825 controlled issuers are ≥$10B by size_usd and 150 are ≥$1B — Deutsche Telekom holds 74.3% of T-Mobile US ($219.2B in assets), Ergen holds 51.8% of EchoStar ($43.0B). Those counts were 20 and 97 when size was 13F float alone: a controlled issuer has little float by definition, so the float proxy was hiding exactly this population — EchoStar has no 13F coverage at all. But the multi-hop pyramids top out near $1.5B, so read a deep chain as a small-cap governance screen and a single-hop one as general-purpose. Most large caps have no ≥50% holder and correctly abstain.

  • Board-interlock path existence is uninformative. Measured: every well-connected pair links within 4 hops. The named bridging director is the signal, not the connection.

  • CIK-keyed only. Deliberately conservative — understates family/affiliate structure rather than inventing links through fuzzy name matching.

  • Custodians and index funds are labelled, not deleted. They're excluded at query time so the underlying co-filing facts stay in the graph and the precision choice stays auditable.

Development

make test        # unit suite: fully mocked, no database needed
make check       # lint + tests (note: `make lint` rewrites source via ruff --fix)
make preflight   # verify build preconditions against your Neo4j

There is no CI. make check is the stand-in; pre-commit install gets ruff + gitleaks on commit.

License

MIT. SEC filing data is public domain.

Available Tools

8 tools
activist_coalitionA
Read-onlyIdempotent

Find the de-facto activist coalition (wolf-pack) around a named 13D filer.

Two activists are linked when they co-target >=min_shared_targets of the same issuers via 13D. Custodial/broker hubs are scrubbed before the connected component is formed (precision discipline), so the coalition reflects coordinated activists, not shared custodians. Returns members + coalition diameter. Abstains when the filer sits in no multi-member coalition (or was scrubbed as a custodial hub).

Example: activist_coalition("ICAHN CARL C") -> the ~22-member scrubbed cluster (Bulldog/Goldstein, GAMCO/Gabelli, Karpus, Icahn, Dolan family).

ParametersJSON Schema
NameRequiredDescriptionDefault
activistYes
min_shared_targetsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only and non-destructive behavior. The description adds valuable algorithmic details: scrubbing of custodial/broker hubs, the precision discipline, and abstention behavior. It clearly explains what the tool does internally, going beyond the safety annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose. The three sentences cover purpose, methodology, and abstention, followed by an illustrative example. No wasted words; every sentence contributes to understanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not detail return shape, but it still mentions 'Returns members + coalition diameter.' The tool's complexity is moderately high, and the description covers the key behavioral aspects, edge cases, and parameter semantics, making it complete for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explicitly explains both parameters: 'activist' is the named filer (illustrated in the example), and 'min_shared_targets' is the threshold for linking activists. The description fully covers parameter meaning, going beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Find the de-facto activist coalition (wolf-pack) around a named 13D filer.' It clearly distinguishes what the tool does and includes a concrete example, making the purpose unambiguous even without explicit sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (to find coalitions around a filer) and provides an edge-case condition ('Abstains when the filer sits in no multi-member coalition'), but it does not explicitly mention alternative tools or when-not-to-use scenarios. Usage is inferred rather than explicitly contrasted with siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

activist_convergenceA
Read-onlyIdempotent

Screen for issuers where several known activist franchises filed 13D close together.

The "what is heating up" screen, and the best starting point for an event-driven question. since is an ISO date (e.g. '2025-01-01'). Returns each issuer with the franchises involved, the span in days, and the filing sequence with accession numbers.

Gated to a curated list of recognised activist franchises (Icahn, GAMCO/Gabelli, Saba, Bulldog, Karpus, Elliott, Starboard, RA Capital, OrbiMed, ...) — precision over recall. Without that gate the output is dominated by micro-cap founders crossing 5% and by filing-group artifacts where one manager files through several affiliated entities.

Example: activist_convergence(since='2023-01-01') surfaces MNRO (GAMCO then Icahn, 96 days apart) and SION (OrbiMed then RA Capital, 5 days apart).

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo
window_daysNo
min_activistsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond annotations by explaining the internal gate (curated activist list), its rationale (precision over recall), and what would happen without it (dominance by micro-cap founders and filing-group artifacts). This adds meaningful behavioral context beyond the readOnly/idempotent hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the primary purpose, followed by context, parameter detail, and a concrete example. Every sentence adds value and there is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite lacking explanations for two parameters, the description covers the tool's purpose, return contents (franchises, span, accession numbers), limitations (gate), and provides a realistic example. This is complete enough for an agent to select and reasonably invoke the tool, especially with an output schema present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explicitly explains the `since` parameter with an ISO date format and example, but provides no guidance on `window_days` or `min_activists`. Given the input schema has no parameter descriptions (coverage 0%), the description fails to compensate for these two parameters, leaving their semantics ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description provides a specific verb ('screen') and resource ('issuers'), with clear scope (13D filings close together). It does not explicitly differentiate from sibling tools like activist_coalition, but the focus on filing timing and activist franchises is distinctive enough to imply a unique purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly frames when to use the tool ('the what is heating up screen', 'best starting point for an event-driven question'), which gives useful context. However, it does not explicitly mention alternatives or when not to use it, so it stops short of full guideline coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

board_interlock_pathA
Read-onlyIdempotent

Name the director(s) who bridge two companies' boards.

Walks the persisted SHARES_DIRECTOR edge, returning the alternating company chain and the bridging director(s) per hop. Abstains when no shared-director path exists within max_hops.

Read the bridging director, not the path's existence. In this dataset every well-connected pair of companies is linked within 4 hops (measured), so "are these boards connected?" is essentially always yes and carries no information. The useful output is who the named connector is, and how short the link is.

Example: board_interlock_path("AAPL", "JPM") -> AAPL — JPM via BELL JAMES A (1 hop).

ParametersJSON Schema
NameRequiredDescriptionDefault
max_hopsNo
to_companyYes
from_companyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare the tool read-only, idempotent, and non-destructive. The description goes further by explaining the traversal behavior (walks SHARES_DIRECTOR edge, returns alternating company chain and director per hop) and the abstain condition when no path exists. This provides useful behavioral context beyond what annotations offer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear opening, a bolded usage warning, and an illustrative example. It is slightly verbose but every section adds value, making it an efficient and purposeful text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description doesn't need to detail return values. It covers the tool's purpose, the domain insight about always-connected boards, the traversal behavior, and the abstain condition, making it complete for a graph traversal tool with minimal complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. The example ('board_interlock_path("AAPL", "JPM")') clarifies from_company and to_company, but max_hops is only implicitly referenced ('within max_hops'), without explaining its meaning or default. The parameter semantics are partially covered but not fully explicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb+resource: 'Name the director(s) who bridge two companies' boards.' It also differentiates itself from siblings by emphasizing that the output is the bridging director, not the path's existence, which distinguishes it from tools like control_chain or influence_map.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use the tool (find the bridging director) and when not to (don't use it to test connectivity, since it's essentially always connected within 4 hops). It does not name alternative tools but offers a clear contextual warning that shapes usage appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

campaign_timelineA
Read-onlyIdempotent

Show who moved first on an issuer, who followed, and who is merely index money.

Returns every dated 13D/13G filing on the issuer in chronological order, each filer classified as activist / insider_or_other / passive_index / custodian, with percent_of_class and the accession number. Also reports the first mover and, for each follower, how many days later they arrived. Abstains when the issuer has no dated ownership filing.

Only 13D/13G filing dates are used — they are the one trustworthy time series in this graph (board and 13F layers are snapshots).

Example: campaign_timeline("MNRO") shows GAMCO at 4.0% on 2025-08-01, then ICAHN CARL C at 14.79% exactly 96 days later.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo
companyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavioral context beyond the annotations: it explains the classification categories, the abstention behavior, the reliance solely on 13D/13G dates, and includes a concrete example. This is particularly valuable given the readOnly and idempotent hints already provided, and it does not contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed and includes a helpful example, with all sentences contributing meaningful information. It is slightly longer than necessary but remains front-loaded and scannable, earning a strong score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description does not need to explain return formats; it covers behavior, classifications, abstention, and data source caveats. The main gap is the undocumented 'since' parameter, but overall the description is complete enough for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It clarifies the 'company' parameter via the example 'campaign_timeline("MNRO")' and the term 'issuer,' but it entirely omits any explanation of the optional 'since' parameter, leaving its semantics ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Show who moved first on an issuer, who followed, and who is merely index money,' then details the exact output (chronological 13D/13G filings with filer classifications). It clearly distinguishes itself from sibling snapshot tools by emphasizing that it provides a time series, not a snapshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context by stating that only 13D/13G filing dates are used and that board and 13F layers are snapshots, implying this tool is for chronological ownership events. It also mentions abstention when no dated filing exists. However, it does not explicitly name sibling tools or provide direct 'use X instead' guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

control_chainA
Read-onlyIdempotent

Trace the transitive >=50% ownership control chain through a public issuer.

direction='up' = who ultimately controls this issuer; 'down' = what this issuer controls. Each step carries percent_of_class and the 13D accession number as citation. Abstains (abstained=True) when the issuer has no verified control edge — never fabricates a chain from sub-50% or unclassified stakes.

Scope, precisely. Single-hop control reaches large caps: 20 of 825 controlled issuers carry >=$10B of institutional ownership and 97 carry >=$1B. It is the MULTI-HOP pyramids that are small-cap — those top out around $1.5B — so treat chain depth as a small-cap governance signal while single-hop control is general-purpose. Most large caps still have no >=50% holder and correctly abstain.

Each step carries institutional_value_usd (a 13F size proxy, null for the ~25% of issuers with no institutional coverage) so results can be ranked by materiality.

Examples: control_chain("TMUS") returns Deutsche Telekom -> T-Mobile US (74.3%, $95B). control_chain("Income Opportunity Realty") returns the 3-hop pyramid Basic Capital -> American Realty (62%) -> Transcontinental (83%) -> Income Opportunity (85%).

ParametersJSON Schema
NameRequiredDescriptionDefault
companyYes
max_hopsNo
directionNoup

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses important behavioral traits beyond the readOnly/openWorld/idempotent annotations: it abstains (abstained=True) when no verified edge exists, never fabricates chains from sub-50% or unclassified stakes, and explains per-step fields like percent_of_class, 13D accession, and institutional_value_usd (null for ~25% of issuers). This is rich, honest behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear first sentence, a scoped details paragraph, and concrete examples. It is longer than strictly necessary, but each section earns its place by adding behavioral or usage context. The only minor issue is that some statistics (20 of 825, 97 of 825) could be tightened without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity and the presence of an output schema, the description is nearly complete: it covers abstention behavior, direction semantics, field meanings, and materiality ranking. The missing explicit explanation of `max_hops` is the main gap, but the examples and scope discussion provide enough context for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It thoroughly explains the `direction` parameter and provides examples that clarify `company`, but it never explicitly describes `max_hops` or its default value, even though the multi-hop discussion implies its existence. Partial compensation, but not complete for all three parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Trace the transitive >=50% ownership control chain through a public issuer,' which names a specific verb (trace), a resource (ownership control chain), and a clear threshold (>=50%). It also defines direction='up' vs 'down' and gives concrete examples, distinguishing this from sibling graph tools like influence_map or ownership_snapshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Scope, precisely' paragraph gives clear context: single-hop control is general-purpose, multi-hop chains are a small-cap governance signal, and most large caps have no >=50% holder and will abstain. This effectively tells the agent when to use the tool, but it does not explicitly name alternative tools or state when-not-to-use in favor of a sibling, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_secgraph_schemaA
Read-onlyIdempotent

Return the curated secgraph ownership schema and tool catalog for grounding.

A hand-curated summary (nodes, relationship semantics, temporal-trust caveats, and the curated tool catalog) — not a raw graph dump — so an agent can pick the right tool. Includes the honest limits (CIK-only, snapshot vs dated layers, no prediction).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, idempotent, and safe behavior. The description adds value by explaining the output is a curated summary, includes 'temporal-trust caveats,' and 'honest limits (CIK-only, snapshot vs dated layers, no prediction).' This goes beyond the annotations to inform the agent about content and limitations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences that immediately state the core purpose and then expand with important context. There is no fluff; every sentence adds value, and the structure is clear and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema and rich annotations, the description provides sufficient context: it explains what is returned (schema, tool catalog, limits), why it exists (grounding, tool selection), and its honest limitations. This fully equips an agent to invoke the tool appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the input schema is empty (100% coverage by default). The description does not need to elaborate on parameters. As a no-parameter tool, the baseline is 4, and no additional param semantics are required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns the 'curated secgraph ownership schema and tool catalog for grounding.' This is a specific verb+resource, and the clarification that it is 'a hand-curated summary... not a raw graph dump' distinguishes it from sibling tools that return specific analyses. The purpose is unambiguous and contextually differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for grounding and tool selection: 'so an agent can pick the right tool' and 'for grounding.' It also notes 'not a raw graph dump' to set expectations. While it does not explicitly name sibling tools or state when not to use, the intended use case is clear enough for an agent to decide appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

influence_mapA
Read-onlyIdempotent

Issuers where a holder has a big stake AND currently sits on the board.

The strongest single output here, and the best place to start a governance or counterparty question. It is the two-limb test from 12 CFR 225.2(e) — the Federal Reserve's control presumptions — and its force comes from the conjunction of two independent filing types: a Schedule 13D on one side, Form 3/4/5 board activity on the other. A screener can give you either list; the pairing is the finding.

Requiring a current board seat also fixes a freshness problem. 13D carries no exit obligation below 5%, so half the stakes on file predate 2020 and are last-known rather than current — but board activity runs to the present, so a recent seat corroborates an old declaration. Liberty Broadband's 26.1% of Charter was declared in 2014; its director was seen in 2026.

min_tier is a presumption tier (10/15/25/50). min_value_usd filters on the 13F size proxy so results are recognizable names rather than nano-caps.

Caveat to state if asked: percent_of_class is percent of the class covered by the filing, NOT voting power — and several of the largest names are dual-class (Berkshire, the Liberty complex, Carvana, Sea), where economic and voting stakes diverge.

Example: influence_map() returns Buffett/Berkshire 37% (seat 2026-05), Liberty Broadband/Charter 26.1% (seat 2026-06), Huffman/Reddit 61.5% (seat 2026-06).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
min_tierNo
min_value_usdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds crucial behavioral context: the freshness problem with 13D filings (no exit obligation below 5%), the use of current board seats to validate old stakes, and the caveat that percent_of_class is not voting power (dual-class divergence). This goes well beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place: definition, regulatory basis, data-source rationale, freshness fix, caveat, and concrete example. It is front-loaded with the core purpose and structured logically, with no filler or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the tool and the presence of an output schema, the description covers the underlying logic, data sources, freshness issue, dual-class caveat, and expected results with a named example. It is self-contained enough for an agent to invoke correctly without additional clarification.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It explains min_tier as a presumption tier with values 10/15/25/50 and min_value_usd as a 13F size proxy to filter out nano-caps. The limit parameter is not explicitly described, but its default and purpose are self-evident.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool identifies issuers where a holder has a big stake AND currently sits on the board, citing a specific regulatory test (12 CFR 225.2(e)). It differentiates from simple screeners by emphasizing 'the pairing is the finding,' distinguishing it from sibling tools that might return either list independently.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly recommends the tool as 'the best place to start a governance or counterparty question' and explains why the conjunction of 13D and Form 3/4/5 is uniquely valuable. It does not name specific alternatives or explicitly state when not to use it, but the context is strong enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ownership_snapshotA
Read-onlyIdempotent

Supporting ownership context for one issuer: top holders, board size, control status.

Grounds the headline chain/path/coalition answers with the surrounding facts — the largest 13D/13G beneficial owners (with percent_of_class), director/officer counts, and whether any verified >=50% control edge exists. Abstains only if the company can't be resolved.

ParametersJSON Schema
NameRequiredDescriptionDefault
top_nNo
companyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds valuable details: it returns percent_of_class for top holders, director/officer counts, and verified >=50% control edges. It also discloses abstention when the company can't be resolved, which is beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the purpose, and every clause adds value. No redundant information or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with two parameters and an output schema, so the description covers the key inputs and outputs. It explains the data included, the abstention condition, and the read-only nature. Minor gaps remain around top_n semantics, but the overview is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It mentions top holders and company context, but does not explicitly define top_n or company parameters. The mapping is implied but not stated, leaving some ambiguity about the exact meaning of top_n (e.g., number of holders vs. threshold).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides supporting ownership context for one issuer, listing specific components (top holders, board size, control status). It distinguishes itself from siblings by explicitly positioning itself as grounding the headline chain/path/coalition answers, which are likely from other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage as supplementary context for chain/path/coalition investigations, and it mentions abstention if the company cannot be resolved, which is a clear condition. It doesn't explicitly name alternatives, but the context is sufficiently clear that an agent would know when to invoke it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedactivist_coalition
    • First observedactivist_convergence
    • First observedboard_interlock_path
    • First observedcampaign_timeline
    • First observedcontrol_chain
    • First observedget_secgraph_schema
    • First observedinfluence_map
    • First observedownership_snapshot

TDQS

A4.4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct analytical question: convergence screens issuers, coalition groups filers, influence_map pairs stake with board seat, timeline sequences filings, chain traces control, path finds board bridges, snapshot gives current context, and schema is meta. Even the two activist-related tools differ by perspective (issuer-centric vs. filer-centric), and descriptions reinforce those boundaries.

Naming Consistency4/5

Nearly all names follow a consistent snake_case noun_phrase pattern (activist_convergence, influence_map, campaign_timeline, control_chain, board_interlock_path, activist_coalition, ownership_snapshot). The lone 'get_secgraph_schema' deviates with a verb prefix, but it is a minor exception and still recognizable within the same style.

Tool Count5/5

Eight tools is well within the ideal 3-15 range and each tool covers a meaningful aspect of ownership analysis without redundancy. The count feels intentional for the scope: screening, historical timeline, control tracing, interlocks, coalitions, and snapshot context.

Completeness5/5

The tool set covers the core workflows for SEC ownership graph analysis: identifying activist activity (convergence, coalition), assessing influence (influence_map, snapshot), understanding control (control_chain), and analyzing board connections (interlock_path). A schema grounding tool fills the meta-need, and there are no obvious dead ends. One could imagine a search tool, but the descriptions imply names are directly resolvable, so gaps are minimal.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for the Graphite Financial Knowledge Graph, enabling natural language queries about companies, supply chains, executives, regulations, and patents via MCP-compatible clients.
    7
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP server providing read-only access to SEC EDGAR filings, allowing LLMs to look up companies, search filings, and retrieve securities offering data.
    3
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Hosted MCP server that gives AI agents real-time access to SEC EDGAR filings search, 10-K/8-K reading, XBRL financial facts, and insider-trade (Form 4) alerts.
    13 npm
    1
    MIT