MCP developer docs

AlphaCreek MCP

Connect your agent to US SEC filings (10-K, 10-Q, 20-F, 6-K, 8-K, DEF 14A) and UK FCA reports (annual, half-year, press). Five read-only tools find a filing, read the sections you need, and return a citation link for each passage.

Get API key →POST https://mcp.alphacreek.ai/mcp

To use AlphaCreek in Claude, ChatGPT, or Cursor without code, see Connect an assistant.

Quickstart

Test the server with curl in two minutes. This test does not use an AI model.

1. Get an API key

Create an API key in the dashboard. API keys need an Integration trial or a paid Integration plan. Keep the key on your server.

2. List the tools

This call needs no key. The commands use curl and jq.

curl -s https://mcp.alphacreek.ai/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  | jq -r '.result.tools[].name'

3. Call the tools with your key

The call_tool helper sends one tools/call request and prints the text result.

export ALPHACREEK_API_KEY="your_api_key"

call_tool() {
  curl -s https://mcp.alphacreek.ai/mcp \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ALPHACREEK_API_KEY" \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"$1\",\"arguments\":$2}}" \
    | jq -r '.result.content[0].text // .error.message // .detail'
}

# Find the latest NVIDIA 10-K. The result has artifact_document_id.
call_tool list_filings '{"ticker":"NVDA","document_type":"10-K","limit":1}'

# Read Item 1A (node 1.2). The result has CITATION_MARKDOWN lines.
call_tool read_node_content '{"artifact_document_id":"NVDA_10-K_000104581026000021","node_ids":["1.2"]}'

# Optional: list all node ids of the filing (long output).
call_tool get_filing_toc '{"artifact_document_id":"NVDA_10-K_000104581026000021"}'

The read_node_content result has a CITATION_MARKDOWN line for each block of text. Your agent copies these links into its answer. See Get citations in answers.

4. Run an agent example

Pick a runnable example for OpenAI, Anthropic, or Gemini. Each script asks “What are NVIDIA’s biggest risks in the latest 10-K?” and prints an answer with citation links.

Connect your agent

EndpointPOST https://mcp.alphacreek.ai/mcp
TransportMCP Streamable HTTP, JSON-RPC 2.0, protocol version 2025-03-26. Each request gets one JSON response. The server does not use a session id.
HeadersContent-Type: application/json and Authorization: Bearer <API key>
No key neededinitialize, tools/list, ping. tools/call needs a key.

The agent loop

  1. Call initialize. Keep result.instructions. It holds the citation rules and the tool workflow.
  2. Call tools/list. Convert each tool to the tool format of your model. Use inputSchema as the parameters: OpenAI parameters, Anthropic input_schema, Gemini parameters_json_schema (Python) or parametersJsonSchema (JavaScript).
  3. Send the question to the model. Put your system prompt and instructions in the system message. See Get citations in answers.
  4. When the model calls a tool, send tools/call with the tool name and arguments. Return result.content[0].text to the model as the tool result.
  5. Repeat step 4 until the model answers without a tool call. Set a maximum number of rounds. The examples use 8.

The core calls with the official mcp Python SDK:

Python
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

MCP_URL = "https://mcp.alphacreek.ai/mcp"
HEADERS = {"Authorization": f"Bearer {ALPHACREEK_API_KEY}"}

async with streamablehttp_client(MCP_URL, headers=HEADERS) as (read, write, _):
    async with ClientSession(read, write) as session:
        init = await session.initialize()
        system = f"{SYSTEM}\n\n{init.instructions or ''}".strip()
        tools = (await session.list_tools()).tools  # name, description, inputSchema

        # Send system, tools, and the question to your model.
        # For each tool call that the model makes:
        result = await session.call_tool(tool_name, tool_arguments)
        tool_output = result.content[0].text  # return this to the model

Runnable examples

Each script asks one question, runs the agent loop, and prints the answer with citation links. The JavaScript scripts use a small fetch client for MCP, so they need only the model SDK.

Needs Python 3.10+. Default model: gpt-5.4-mini. Optional environment variables: OPENAI_MODEL, ALPHACREEK_MCP_URL.

Save the script below as python_openai.py, then run:

pip install mcp openai
export ALPHACREEK_API_KEY="your_alphacreek_api_key"
export OPENAI_API_KEY="your_provider_api_key"
python python_openai.py
Python
#!/usr/bin/env python3
"""OpenAI + AlphaCreek MCP: one question → tools → print answer.

Needs: ALPHACREEK_API_KEY, OPENAI_API_KEY.

Canonical runnable example for the MCP developer docs and the marketing-site full script
(alphacreek-ui src/sections/docs/mcp-openai-python-example.ts, export MCP_OPENAI_PYTHON_FULL_SCRIPT).
Update that embedded string when you change this file.
"""

import asyncio
import json
import logging
import os
import sys
from typing import Any

import mcp.types as T
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
from openai import OpenAI
from openai.types.shared.reasoning import Reasoning

MCP_URL = os.environ.get("ALPHACREEK_MCP_URL", "https://mcp.alphacreek.ai/mcp").strip()
MODEL = os.environ.get("OPENAI_MODEL", "gpt-5.4-mini").strip()
QUESTION = (
    "What are NVIDIA’s biggest risks in the latest 10-K? "
)
SYSTEM = (
    "Use the AlphaCreek tools for questions about SEC and UK FCA filings. "
    "Answer only from text that read_node_content returns. Do not answer from memory. "
    "End each paragraph or bullet that uses filing text with the matching CITATION_MARKDOWN link, copied as is. "
    "Cite the NODE_ID block that is closest to the fact, not the parent TOC node. "
    "If the tools return no text that supports a claim, say so."
)

log = logging.getLogger(__name__)


def _env(name: str) -> str:
    v = (os.environ.get(name) or "").strip()
    if not v:
        sys.exit(f"Missing {name}")
    return v


def _tool_text(r: T.CallToolResult) -> str:
    parts = [b.text for b in (r.content or []) if isinstance(b, T.TextContent) and b.text]
    if parts:
        return "\n".join(parts)
    d: dict[str, Any] = {}
    if isinstance(r.structuredContent, dict):
        d["structuredContent"] = r.structuredContent
    if r.isError:
        d["isError"] = True
    return json.dumps(d or {"isError": r.isError}, ensure_ascii=True)


def _to_fc_tools(tools: list[T.Tool]) -> list[dict[str, Any]]:
    return [
        {
            "type": "function",
            "name": t.name,
            "description": ((t.description or "").strip() or None),
            "parameters": t.inputSchema if isinstance(t.inputSchema, dict) else {"type": "object", "properties": {}},
            "strict": False,
        }
        for t in tools
    ]


def _split_output(items: list[Any]) -> tuple[list[Any], str]:
    calls, texts = [], []
    for it in items or []:
        if getattr(it, "type", None) == "function_call":
            calls.append(it)
        elif getattr(it, "type", None) == "message":
            for b in getattr(it, "content", None) or []:
                if getattr(b, "type", None) == "output_text":
                    tx = getattr(b, "text", "") or ""
                    if tx:
                        texts.append(tx)
    return calls, "\n".join(texts).strip()


async def main() -> None:
    logging.basicConfig(level=logging.INFO, format="%(message)s")
    oai = OpenAI(api_key=_env("OPENAI_API_KEY"))
    reasoning = Reasoning(effort="low")  # type: ignore[arg-type]
    hdrs = {"Authorization": f"Bearer {_env('ALPHACREEK_API_KEY')}"}
    tool_calls = in_tok = out_tok = 0
    async with streamablehttp_client(
        MCP_URL, headers=hdrs, timeout=120, sse_read_timeout=300, terminate_on_close=True
    ) as (read, write, _):
        async with ClientSession(read, write, client_info=T.Implementation(name="demo", version="0")) as s:
            init = await s.initialize()
            system = f"{SYSTEM}\n\n{init.instructions or ''}".strip()
            fcs = _to_fc_tools((await s.list_tools()).tools)
            if not fcs:
                sys.exit("MCP returned no tools")
            prev: str | None = None
            nxt: list[dict[str, Any]] = []
            for _ in range(8):
                common = dict(model=MODEL, tools=fcs, tool_choice="auto", temperature=1, reasoning=reasoning)
                if prev is None:
                    resp = await asyncio.to_thread(
                        oai.responses.create,
                        instructions=system,
                        input=[{"type": "message", "role": "user", "content": QUESTION}],
                        **common,
                    )
                else:
                    resp = await asyncio.to_thread(
                        oai.responses.create, previous_response_id=prev, input=nxt, **common
                    )
                if getattr(resp, "error", None):
                    sys.exit(f"OpenAI error: {resp.error}")
                u = getattr(resp, "usage", None)
                if u:
                    in_tok += int(getattr(u, "input_tokens", 0) or 0)
                    out_tok += int(getattr(u, "output_tokens", 0) or 0)
                prev = resp.id
                calls, text = _split_output(list(resp.output or []))
                if not calls:
                    if not text:
                        sys.exit("No text and no tool calls")
                    pi, po = {"gpt-5.4-mini": (0.75, 4.5)}.get(MODEL, (0.75, 4.5))
                    cost = (in_tok * pi + out_tok * po) / 1_000_000
                    log.info("total tool calls: %d", tool_calls)
                    log.info("total input tokens: %d", in_tok)
                    log.info("total llm cost: $%.6f", cost)
                    print(text)
                    return
                nxt = []
                for c in calls:
                    try:
                        args = json.loads(c.arguments or "{}")
                    except json.JSONDecodeError:
                        args = {}
                    if not isinstance(args, dict):
                        args = {}
                    log.info("tool call: %s %s", c.name, args)
                    tool_calls += 1
                    raw = await s.call_tool(c.name, args)
                    nxt.append(
                        {"type": "function_call_output", "call_id": c.call_id, "output": _tool_text(raw)}
                    )
            sys.exit("Too many tool rounds")


if __name__ == "__main__":
    asyncio.run(main())

Get citations in answers

Each read_node_content result has a CITATION_MARKDOWN link for each block of text. The model must copy these links into its answer. Models do this reliably only when the system prompt tells them to. Do these two steps.

1. Add citation rules to your system prompt

Use the AlphaCreek tools for questions about SEC and UK FCA filings.
Answer only from text that read_node_content returns. Do not answer from memory.
End each paragraph or bullet that uses filing text with the matching CITATION_MARKDOWN link, copied as is.
Cite the NODE_ID block that is closest to the fact, not the parent TOC node.
If the tools return no text that supports a claim, say so.

2. Add the server instructions

initialize returns instructions. They contain the citation rules and the tool workflow. Some MCP clients, such as Cursor, add them for you. In your own agent, add them to the system prompt yourself.

Python
init = await session.initialize()
system = f"{SYSTEM}\n\n{init.instructions or ''}".strip()
JavaScript
const init = await mcp.connect(); // result of the JSON-RPC initialize request
const system = [SYSTEM, init?.instructions].filter(Boolean).join('\n\n');
Show the full server instructions
AlphaCreek MCP provides SEC and UK FCA filing navigation and source text.
<important>Citation required. If your answer uses text from read_node_content, every paragraph or bullet derived from that text MUST end with an inline markdown link from the matching CITATION_MARKDOWN (or build [TITLE](CITATION_URL) the same way). Do not state filing facts without a citation link beside them. Answers without these links are incomplete.</important>
Citation format: paste CITATION_MARKDOWN as-is, e.g. [Risk Factors](https://www.alphacreek.ai/sec/reader?...). Prefer the child NODE_ID block closest to the quoted fact, not the parent TOC node.
Example — good: "Cloud revenue was $33.1B ([MD&A](https://www.alphacreek.ai/sec/reader?...))."
Example — bad: "Cloud revenue was $33.1B." (missing citation link)
Use filing_registry=sec_edgar (default for ticker/company lookups) for US SEC filings. Use filing_registry=fca_nsm for UK FCA NSM reports (annual, half-year, and press). Call get_latest_filing without ticker or company to list newly ingested filings newest-first. Omit filing_registry in that mode to include both SEC and FCA.
1. Choose the filing period first. Multiple fiscal periods may be available per ticker (several 10-K/20-F, 10-Q/6-K, and DEF 14A proxy statements). Call list_filings when you need a specific reporting period, then use the returned artifact_document_id for get_filing_toc and other navigation tools. If artifact_document_id is omitted, get_filing_toc and similar locators resolve the latest filing only. Pass document_type=DEF 14A for proxy statements.
2. Read filings navigation-first. Start with get_filing_toc using the chosen artifact_document_id, then read targeted nodes via read_node_content. Use the node id from each TOC line; these are the same values shown as NODE_ID lines in read_node_content output. Pass one node via node_id or several via node_ids.
3. Prefer source tables for exact financial values. Narrative nodes often explain year-over-year changes, while absolute reported values are usually in nearby sibling or child tables under headings like 'Revenues', 'By type', 'By geography', or 'Segment results'. When text says 'The following table presents...', inspect the adjacent TableElement before answering.
4. Batch reads from the same filing. When reading several nodes from one filing, pass them in one read_node_content call via node_ids to save round-trips. read_node_content returns full node text as plain MCP text only.
5. Cross-company SEC filing search. Use search_sec_event_filings. It searches 8-K, 6-K, 10-K, 10-Q, and 20-F. Omit document_type to search all of those forms. Pass document_type to search only the forms you name. DEF 14A is not in this search. Always pass concept_groups. Groups are AND. any_of terms are OR. Use 2-5 groups for separate parts of the claim. Add synonyms. English stemming covers inflections, not synonyms. Do not require a detail the filing may leave implicit.
Optional query holds exact disclosure phrases. An exact phrase ranks first, so a generic phrase can outrank the causal sentence you want. Omit query for concept-only search. Do not search with query only. Optional document_type is 8-K, 6-K, 10-K, 10-Q, or 20-F. Omit it to search all of those forms.
Each call is one page. There is no total count. If HAS_MORE is true, call again with cursor set to NEXT_CURSOR and the same concept_groups, dates, query, tickers, ne_tickers, document_type, and match_scope. A cursor from different inputs is rejected. If the page is empty and HAS_MORE is true, continue with that cursor. Stop when HAS_MORE is false or when later pages are not relevant.
If a page is mostly co-occurrence, start a new search with no cursor and add a group or exact causal phrases. If results are too few, start a new search with no cursor and drop the least essential group.
ne_tickers omits issuers. It does not load the next page.
Results are candidates. Search cannot by itself prove negation, causality, a numeric threshold, or a change across filings. Call read_node_content with document_id and node_id (node_id may start with sp-) and cite CITATION_MARKDOWN. Pass tickers to limit issuers.
For FCA filings (filing_registry=fca_nsm), TOC node ids are HTML page element ids (for example pf2a, page12, or pageView1) on annual ESEF reports, or sec-parser ids (for example sp-0000001) on half-year RNS HTML reports. Use those ids with read_node_content. CITATION_URL links open the FCA reader scrolled to that node id.
6. After calling read_node_content, map each sentence you plan to write to a CITATION_MARKDOWN / CITATION_URL from that response before answering. A TOC node may expand into more granular child NODE_ID blocks; cite the child closest to the fact.
7. If an AlphaCreek MCP tool fails with a quota or 403 limit message, tell the user their monthly limit is reached and share https://www.alphacreek.ai/dashboard#usage for usage and upgrade.

What the tool returns

This is the result for node 1.2 from the quickstart. A requested node can expand into child blocks. Each block has its own NODE_ID and CITATION_MARKDOWN. Cite the block that holds the fact.

ARTIFACT_DOCUMENT_ID: NVDA_10-K_000104581026000021

NODE_ID: 1.2
TITLE: Item 1A. Risk Factors
NODE_ID: 1.2
CITATION_URL: https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2
CITATION_MARKDOWN: [Item 1A. Risk Factors](https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2)
CONTENT_START
Item 1A. Risk Factors
CONTENT_END
NODE_ID: 1.2.1
CITATION_URL: https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2.1
CITATION_MARKDOWN: [The following risk factors shou...ts of operations or reputation.](https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2.1)
CONTENT_START
The following risk factors should be considered in addition to the other information in this Annual Report on Form 10-K. …
CONTENT_END

---
CITATIONS_IN_THIS_RESPONSE:
- [Item 1A. Risk Factors](https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2)
- [The following risk factors shou...ts of operations or reputation.](https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2.1)

Check the answer

Each paragraph or bullet with a filing fact must end with a link to alphacreek.ai/sec/reader (SEC) or alphacreek.ai/fca/reader (FCA). The link opens the filing at the cited passage.

Good:

NVIDIA states that it is "effectively foreclosed" from competing in China's data center compute market because of U.S. export controls ([We are subject to laws and regu...business and financial results.](https://alphacreek.ai/sec/reader?doc_id=NVDA_10-K_000104581026000021&node_id=sp-1.2.28.1)).

Bad (no citation link):

NVIDIA states that it is "effectively foreclosed" from competing in China's data center compute market because of U.S. export controls.

To test this in code, count the reader links in the final answer. If there are none, make sure that both steps above are in the system prompt.

Tools

The server has five read-only tools. Agents usually call them in this order:

One company, one period
  → list_filings or get_latest_filing  (pick artifact_document_id)
  → get_filing_toc                     (find node ids)
  → read_node_content                  (batch node_ids; plain-text result)
  → answer with CITATION_MARKDOWN beside each claim

Newly ingested filings (no ticker or company)
  → get_latest_filing                  (optional filing_registry, document_type, limit)

Cross-company SEC disclosure
  → search_sec_event_filings           (concept_groups + start_date + end_date)
  → read_node_content                  (DOCUMENT_ID as artifact_document_id)
  → answer with CITATION_MARKDOWN beside each claim

list_filings and get_filing_toc (when artifact_document_id is omitted) need ticker or company. The server resolves a company name to a ticker. See Field reference for filing_registry, document_type, and FilingMetadata.

get_latest_filing

With ticker or company, returns metadata for the newest matching filing. With neither, returns newly ingested filings newest-first (sorted by ingest time). Omit filing_registry in that mode to include both SEC and FCA.

Arguments

FieldTypeRequiredNotes
tickerstringnoStock ticker, for example NVDA. Omit ticker and company to list newly ingested filings.
companystringnoCompany name. The server resolves it to a ticker.
filing_registryenumnosec_edgar or fca_nsm. With a ticker or company, omit means sec_edgar. With neither, omit includes both.
document_typestring or string[]noSEC: 10-K, 10-Q, 20-F, 6-K, 8-K, DEF 14A. FCA: annual, half-year, press.
limitintegernoNewly ingested mode only. Default 25; clamped to 1..50.

Result

Company lookup: { "metadata": FilingMetadata }. Newly ingested list: { "filings": FilingMetadata[] }. The same object is in structuredContent and, as JSON, in content[0].text.

list_filings

Lists available filings newest-first. Use it to pick a reporting period and get its artifact_document_id.

Arguments

FieldTypeNotes
ticker | companystringAt least one required
filing_registryenumsec_edgar (default) or fca_nsm
document_typestring or string[]SEC: 10-K, 10-Q, 20-F, 6-K, 8-K, DEF 14A. FCA: annual, half-year, press. Pass DEF 14A for proxy statements.
limitintegerDefault 25; clamped to 1..50

Result

{ "filings": FilingMetadata[] }.

get_filing_toc

Returns a filing header plus TOC lines. Pass artifact_document_id, or ticker/company with optional document_type and filing_registry (default sec_edgar). Without an artifact id, the server resolves the latest filing only. Pass document_type: "DEF 14A" for US proxy statements. DEF 14A TOC rows use native proxy section labels when the filing has a linked HTML TOC; otherwise they use sec-parser headings.

FCA annual TOC ids are HTML page element ids (pf2a, page12, pageView1). FCA half-year and press TOC ids are sec-parser ids (for example sp-0000001 or a dotted nav_id). Pass those same ids to read_node_content.

Result

content[0].text has the filing header and one line per node: node_id | node_type | title. Indented lines preview the text under each node.

FILING: NVDA 10-K 2026-01-25 | artifact_document_id=NVDA_10-K_000104581026000021

1 | TopSectionTitle | Part I
1.1 | TopSectionTitle | Item 1. Business
1.1.1 | TitleElement | Our Company (~4142 tokens approx)
…
1.2 | TopSectionTitle | Item 1A. Risk Factors (~122 tokens approx)
1.2.2 | TitleElement | Risk Factors Summary (~2438 tokens approx)
…

structuredContent has artifact_document_id, total_nodes, truncated, and toc (array of TOC lines).

read_node_content

Reads one or more nodes from one filing. Pass artifact_document_id (required) and node_id or node_ids. Use node ids from get_filing_toc or from search results. Ids with or without the sp- prefix both work.

The result is plain text only, in content[0].text. There is no structuredContent. The text has:

  • ARTIFACT_DOCUMENT_ID, and NOT_FOUND_NODE_IDS if some ids do not exist.
  • For each block: NODE_ID, TITLE, CITATION_URL, CITATION_MARKDOWN, and the text between CONTENT_START and CONTENT_END.
  • CITATIONS_IN_THIS_RESPONSE: all citation links of the response.

See the output example. Each node returns at most 60,000 characters.

search_sec_event_filings

Searches US SEC filing nodes for a disclosure claim. The corpus is 8-K, 6-K, 10-K, 10-Q, and 20-F. Omit document_type to search all five. DEF 14A and FCA filings are not in this search. Results are candidates. Call read_node_content with the match DOCUMENT_ID as artifact_document_id and the match NODE_ID as node_id, then cite CITATION_MARKDOWN.

Arguments

FieldTypeRequiredNotes
concept_groupsobject[]yes2–6 groups. Every group must match (AND). Each group has name and any_of (OR, max 16 terms). English stemming covers inflections, not synonyms.
start_datestringyesInclusive filing_date, YYYY-MM-DD
end_datestringyesInclusive filing_date, YYYY-MM-DD
querystring or string[]noExact adjacent-token phrases, max 8. Omit for concept-only search. Do not search with query only. An exact phrase ranks first, so a generic phrase can outrank the sentence you want.
document_typestring or string[]no8-K, 6-K, 10-K, 10-Q, 20-F. Omit to search all of those forms.
tickersstring or string[]noLimit issuers. Prefix a symbol with ! to omit it. Max 50.
ne_tickersstring or string[]noOmit these issuers. This does not load the next page. Max 50. Exclude wins if a ticker is in both lists.
limitintegernoPage size. Default 30; max 50. At most 3 matches come from one filing. This is not a total count.
cursorstringnoCopy NEXT_CURSOR when HAS_MORE is true. Pass it only with the same concept_groups, dates, query, tickers, ne_tickers, document_type, and match_scope.
match_scopeenumnonode (default) or window. Both values behave the same.

Result (illustrative)

SEARCH: queries=reduced capital expenditures start=2025-01-01 end=2025-12-31 document_type=8-K,10-K
SEARCH_MODE: hybrid
CONCEPT_GROUP capital_spending: capital expenditure OR CapEx OR capital spending
CONCEPT_GROUP direction: reduce OR lower OR cut
PAGE_MATCHES: 2
HAS_MORE: true
NEXT_CURSOR: n1…

--- Match 1 ---
TICKER: NVDA
TYPE: 8-K
FILING_DATE: 2025-05-28
DOCUMENT_ID: NVDA_8-K_000104581025000123
NODE_ID: sp-1.2
TITLE: Item 2.02 Results of Operations
SNIPPET: …

There is no total count. When HAS_MORE is true, call again with cursor set to NEXT_CURSOR. An empty page with HAS_MORE: true is not the end. If a page is mostly co-occurrence, or too sparse, start a new search with no cursor and add or drop a concept group.

Field reference

filing_registry

Filing source registry. sec_edgar — US SEC EDGAR filings. fca_nsm — UK FCA National Storage Mechanism.

  • list_filings, get_filing_toc, and get_latest_filing with a ticker or company: omit means sec_edgar.
  • get_latest_filing with no ticker and no company: omit includes both registries.

document_type (filter)

Optional document type filter. Canonical values only. Navigation tools accept one string or an array of strings. search_sec_event_filings accepts only the SEC forms listed under that tool.

  • sec_edgar: 10-K, 10-Q, 20-F, 6-K, 8-K, DEF 14A
  • fca_nsm: annual, half-year, press

FilingMetadata

Returned by get_latest_filing and each row of list_filings.

FieldNotes
artifact_document_idStable filing id for get_filing_toc and read_node_content, for example NVDA_10-K_000104581026000021
tickerIssuer ticker
document_typeCanonical type. SEC: 10-K, 10-Q, 20-F, 6-K, 8-K, DEF 14A. FCA: annual, half-year, press.
announcement_typeFCA press subtype when document_type is press; null for annual and half-year. Values: 1st Quarter Results, 2nd Quarter Results, 3rd Quarter Results, 4th Quarter Results, Preliminary Results, Final Results, Trading Update, Share Buyback.
filing_registrysec_edgar or fca_nsm
document_date, filing_dateReport period and publication dates (YYYY-MM-DD)
document_urlLink to the original filing document

Limits and errors

Limits

  • Each successful tools/call counts toward the monthly tool-call quota of your plan. See usage in the dashboard.
  • read_node_content: at most 60,000 characters per node. Text after that limit is cut. Read the child nodes from get_filing_toc to get the rest.
  • list_filings and newly ingested get_latest_filing: limit default 25, max 50.
  • search_sec_event_filings: page size default 30, max 50; at most 3 matches from one filing; 2–6 concept groups.
  • Batch several node_ids from one filing in one read_node_content call. Each call counts once.

Errors

Authentication errors are HTTP status codes. Tool errors come back with HTTP 200 as a JSON-RPC error: error.code is -32000, error.message explains the problem, and error.data.http_status holds the status below.

StatusWhereTypical cause
401HTTP statusMissing or invalid API key or OAuth token
403HTTP statusThe account has no API key access (no Integration plan, or the trial ended), or the token lacks the filings.search scope
400error.data.http_statusMissing ticker or company, invalid document_type, missing node ids, invalid search dates or cursor
403error.data.http_statusMonthly tool-call quota reached. The message has a link to dashboard usage.
404error.data.http_statusNo filing for the ticker and type; filing or node not found; company name not resolved
503error.data.http_statusCompany name lookup is temporarily unavailable

Authentication

API keys

Your own code sends an API key as Authorization: Bearer <API key>. Create and rotate keys in the dashboard. API keys need an Integration trial or a paid Integration plan. Keep keys on your server. Do not put them in browser code.

OAuth 2.1

Assistant connectors, such as Claude and ChatGPT, use OAuth. You need this only if you build an MCP client that signs users in. Clients discover metadata from the MCP origin (https://mcp.alphacreek.ai): /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server/mcp. The flow uses POST /oauth/register, GET /oauth/authorize, and POST /oauth/token with authorization code, PKCE, and refresh tokens.

Supported scopes: filings.search, filings.metadata, filings.navigation, filings.read. Tool calls need filings.search. For setup in Claude, ChatGPT, and Cursor, see Connect an assistant.

Support