Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Stackin

REMOTE · MCP.STACKIN.IO · SCANNED SEP 29

Issue and manage Brazilian fiscal documents: NF-e for goods, NFS-e for services.

Available components

+3 this week 86 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security91
Transport & Reachability100
Schema Quality & AI Usability78
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 2798 tokens (~174/item across 16 items; 16 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management67
  • Stability observed for 20 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage78
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 23% of tool parameters carry a description.Partial
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 16 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 17 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the Stackin MCP server?

Stackin is a hosted endpoint at https://mcp.stackin.io/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · mcp.stackin.io

# add to Claude Code
claude mcp add --transport http stackin-io-stackin 'https://mcp.stackin.io/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "stackin-io-stackin": {
      "url": "https://mcp.stackin.io/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "stackin-io-stackin": {
      "type": "http",
      "url": "https://mcp.stackin.io/mcp"
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.stackin-io-stackin]
url = "https://mcp.stackin.io/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "stackin-io-stackin": {
      "type": "remote",
      "url": "https://mcp.stackin.io/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add stackin-io-stackin --url 'https://mcp.stackin.io/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  stackin-io-stackin:
    url: "https://mcp.stackin.io/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "stackin-io-stackin": {
      "Transport": "http",
      "Url": "https://mcp.stackin.io/mcp"
    }
  }
}
# add to Vellum
assistant mcp add stackin-io-stackin -t streamable-http -u 'https://mcp.stackin.io/mcp'
// mcp.json
{
  "mcpServers": {
    "stackin-io-stackin": {
      "type": "http",
      "url": "https://mcp.stackin.io/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 28 Sept 26 +1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 26 Sept 26 +1
    • Server version: 0.1.0 → 0.2.1 functional
  • 25 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 24 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes. Other categories moved too: Endpoint Security rose 1.

  • 22 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes. Other categories moved too: Endpoint Security rose 1.

  • 20 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

  • 17 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes. Other categories moved too: Endpoint Security rose 1.

  • 15 Sept 26 +1
    • First check of Authorization: pass security
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 29 Sept 2026 · Probed https://mcp.stackin.io/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=mcp.stackin.io CN=Amazon RSA 2048 M04,O=Amazon,C=US 6 Sept 2026 22 Mar 2027 RSA 2048 SHA256-RSA 694ef604c679a3522b84112981821dd
SANs: mcp.stackin.io, www.mcp.stackin.io
CN=Amazon RSA 2048 M04,O=Amazon,C=US (CA) CN=Amazon Root CA 1,O=Amazon,C=US 23 Aug 2022 23 Aug 2030 RSA 2048 SHA256-RSA 773124f2a952e3ed18a58bdb85d1bc0ce5f27
CN=Amazon Root CA 1,O=Amazon,C=US (CA) CN=Starfield Services Root Certificate Authority - G2,O=Starfield Technologies\, Inc.,L=Scottsdale,ST=Arizona,C=US 25 May 2015 31 Dec 2037 RSA 2048 SHA256-RSA 67f944a2a27cdf3fac2ae2b01f908eeb9c4c6

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of mcp.stackin.io. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
io. present 57355 8 Verified
stackin.io. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication Enforced and verified

The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.

Result Enforced and verified
Enforced On tool calls
HTTP status 200

WWW-Authenticate challenge Bearer resource_metadata="https://mcp.stackin.io/.well-known/oauth-protected-resource"

Bearer resource_metadata="https://mcp.stackin.io/.well-known/oauth-protected-resource"

Protected resource metadata

Document https://mcp.stackin.io/.well-known/oauth-protected-resource
Retrieved Yes
Resource https://mcp.stackin.io
Authorisation server https://api.stackin.io

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://mcp.stackin.io/mcp Verified 200
http (plaintext) http://mcp.stackin.io/mcp HTTPS enforced
MCP tools · 16 exposed · ~2,662 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
cancel_invoice ~183

Cancel an authorized invoice. Legal cancellation, with fiscal and accounting effect, inside a window the NFS-e authorizer enforces for the municipality. Ask the human to confirm before calling; never call it speculatively. The reason reaches the tax authority verbatim and must be at least 15 characters. Pass idempotency_key to make a retry safe: repeating the same key with the same access key and reason replays the first answer instead of cancelling a second time. Reuse the key only when retrying that exact call; a genuinely new cancellation needs a new key, or none. Nothing generates one for you — two calls without a key are two cancellations.

NameTypeReqDescription
access_keystringyes–
document_typestringyes–
idempotency_key–––
reasonstringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

consult_invoice ~45

Look up an invoice's current status by its access key. Read-only: it never changes the document.

NameTypeReqDescription
access_keystringyes–
document_typestringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

correct_invoice ~152

File an electronic correction letter (CC-e) against an NF-e. NF-e only: there is no correction letter for an NFS-e, where a wrong document is cancelled and issued again. It corrects wording and non-fiscal fields only. It cannot change values, taxes, the recipient or the products — those still require cancelling and issuing again, and telling the user a CC-e will fix an amount is wrong in a way they only discover at an audit. Each letter supersedes the previous one and the SEFAZ keeps at most 20 per document. The text reaches the tax authority verbatim.

NameTypeReqDescription
access_keystringyes–
correctionstringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

get_invoice_pdf ~105

Return the printable rendering of a document, as a PDF. Works for both types — a DANFE for nfe, a DANFSe for nfse. The PDF comes back base64-encoded in content_base64; the XML, not this, is the legally valid document. A 502 from here means the authorizer is unavailable, not that the invoice is wrong.

NameTypeReqDescription
access_keystringyes–
document_typestringyes–
NameTypeReqDescription
access_keystringyes–
content_base64stringyesThe PDF bytes, base64-encoded. Decode before saving.
content_typestring––

No examples provided.

get_invoice_submissions ~166

Show every attempt made for one invoice and what came back. This is the tool that answers "why was it rejected". consult_invoice gives the status; this gives the tax authority's own code, its message, and the request and response exactly as they went over the wire. Read-only. It takes the invoice_id, like reissue_invoice — a rejected document has no access key to look it up by. Get the id from list_invoices. The rows are attempts, not documents: a reissued invoice has more than one, oldest first, and only the last describes the current state. Quote the authority's message rather than paraphrasing it; the code is what the user will search for.

NameTypeReqDescription
invoice_idstringyes–
NameTypeReqDescription
attemptsarray––
invoice_id–––

No examples provided.

invalidate_numbering ~169

Declare an NF-e numbering range reserved but never used. NF-e numbering has to be continuous, so a gap left by a failed issuance is explained to the SEFAZ with this — not with a new document. Irreversible: a number declared unused can never be used. Only for numbers that were never authorized. An authorized document is cancelled, never invalidated. Confirm the range with the user and read it back before calling: the range is inclusive, and one digit wrong burns numbers the company still needs. The SDK refuses a backwards range and a reason outside 15-255 characters before anything is transmitted.

NameTypeReqDescription
number_endintegeryes–
number_startintegeryes–
reasonstringyes–
seriesstringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

issue_invoice ~366

Issue a Brazilian fiscal document: NFS-e or NF-e. This produces a legal fiscal document. Confirm the data with the user before calling when you inferred any field. Every item needs a price: unit_price is what one unit costs and amount is the line's gross total. Send unit_price with quantity when the user quotes a price per unit, amount when they quote the line. Sending both asserts they agree and is refused if they do not. document_type nfse is a service invoice: each item needs a description and a price, the recipient address is optional, and service_code (LC 116/2003 item.subitem) falls back to the company's fiscal profile when omitted. document_type nfe is for goods, and the SEFAZ rejects a partial one: every item needs ncm and cfop, and recipient_address is required with street, number, neighborhood, city, state, zip_code and city_code all filled. Call validate_invoice_payload first when any of that was inferred rather than given. Pass idempotency_key when a retry is possible: repeating the same key with the same payload replays the first answer instead of issuing a second document. Without one, a retry after a lost response issues again — another credit, another number burned, and undoing it means cancelling, which has a deadline. Nothing generates the key for you; use one per business event, not per call.

NameTypeReqDescription
client_namestringyes–
document_typestringyes–
idempotency_key–––
itemsarrayyes–
number–––
recipient_address–––
series–––
tax_idstringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

list_fiscal_kinds ~89

Which classifications this country has data for, right now. Ask this before assuming a classification exists. The answer grows as the source data does, so a name absent here is absent today rather than absent forever.

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess.
NameTypeReqDescription
kindsarray––

No examples provided.

list_invoices ~195

List the invoices this company issued, newest first. One document type at a time: pass nfse for services or nfe for goods. A company that issues both has to be asked twice. Use it for "my last invoices", "what was rejected today", and to find a document whose access key the user does not have at hand. Read-only. An authorized document is stored as issued, which is the value the rows carry; authorized is accepted as a synonym and asks for the same thing. Every row carries both identifiers the other tools need: id, which reissue_invoice takes, and access_key, which consult_invoice, cancel_invoice and get_invoice_pdf take. A rejected row has an id and no access key — the authorizer never assigned one.

NameTypeReqDescription
document_typestring––
limitinteger––
offsetinteger––
status–––
NameTypeReqDescription
dataarray–The rows on this page.
next_page–––
page–––
per_page–––
prev_page–––
total––How many exist, not how many are here.
total_pages–––

No examples provided.

list_received_invoices ~125

List NF-e documents other companies issued against this one. The mirror of list_invoices: that one shows what this company issued, this one what it received. Read-only. It reads what the API already collected and never calls the tax authority, which caps how often a company may ask per day. Each row carries the issuer, the amount and, once one was filed, the manifestation. Before a manifestation the authority sends a summary only; the full document arrives after one.

NameTypeReqDescription
limitinteger––
offsetinteger––
NameTypeReqDescription
dataarray––
next_page–––
page–––
per_page–––
prev_page–––
total–––

No examples provided.

lookup_fiscal_code ~223

Resolve one code of one classification, when you know both. Use this to confirm a code before putting it on a document — an NCM that does not exist is rejected by the tax authority after issuing, which costs a cancellation. A code that is not there answers 404. That means the code is wrong, not that the lookup failed; do not retry it. `metadata` differs per kind and is passed through as published: utrib on an NCM, ncm_code on a CEST, tax_type on a CST, and nothing at all on an ISS service.

NameTypeReqDescription
codestringyesThe code itself, as published: 84716052 for an NCM, 5102 for a CFOP. Digits only, no dots.
countrystring–ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess.
kindstringyescfop, ncm, cest, cst, csosn, ...
NameTypeReqDescription
code–––
country–––
description–––
kind––cfop, ncm, cest, cst, csosn, ...
metadata––Whatever the classification carries beyond a code and a description, and it differs per kind: utrib on an NCM, ncm_code on a CEST, tax_type on a CST, null on an ISS service.

No examples provided.

lookup_taxpayer ~201

Look up one taxpayer by exact tax id, to confirm who it is. Use it to check a recipient's name before issuing against them. It takes the id exactly — punctuation is fine, but there is no search by name, by prefix or by state, and there will not be: the registry holds the names and addresses of real people. A 404 does not mean the company does not exist. The registry reloads monthly from the RFB's dump, so a recently registered CNPJ is simply not in it yet. Say that to the user rather than reporting the tax id as invalid, and never turn a 404 here into a validation rule.

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess.
tax_idstringyesThe exact tax id. A CNPJ is 14 digits.
NameTypeReqDescription
activity_code–––
city_code–––
country–––
kind––Whether it is a company or a person.
metadata––Whatever the registry holds beyond these.
name–––
postal_code–––
started_at–––
state–––
status–––
tax_id–––
trade_name–––

No examples provided.

manifest_received_invoice ~178

Declare this company's position on a document issued against it. Legally binding and irreversible once the tax authority accepts it — ask the human to confirm before calling, and read back which document and which of the four positions is being filed. Denying a document (210220) or declaring the operation did not happen (210240) is an accusation against whoever issued it. Never pick either because the user sounds unsure — ask. 210200 confirms the operation happened, 210210 acknowledges the document exists, 210220 denies knowing it, and 210240 states the operation was not carried out. Only 210240 takes a reason, and it requires one; the others are refused if a reason is sent.

NameTypeReqDescription
access_keystringyes–
manifestationstringyes–
reason–––
NameTypeReqDescription
access_key–––
manifestation––The code that was filed.
protocol––The receipt, when the authority gave one.
status–––

No examples provided.

reissue_invoice ~99

Retry a rejected invoice after the data that caused the rejection was fixed. Takes the local invoice_id, not the access key: a rejected document never got one. Consumes a credit like a new issuance, so it takes an idempotency_key for the same reason issue_invoice does. An authorized invoice is corrected or cancelled, never reissued.

NameTypeReqDescription
idempotency_key–––
invoice_idstringyes–
NameTypeReqDescription
access_key––The authorizer's key. Absent while the document is not authorized.
id––Local id. Use it for reissue and for submissions, and when a document was rejected and has no key.
protocol––The authorization protocol, when granted.
status––issued, rejected or cancelled.

No examples provided.

search_fiscal_codes ~231

Find a code from a description, or page through a table. This is the tool for "what NCM is a keyboard" — the one the user actually asks. Prefer it over guessing a code from memory: the tables change, and a plausible wrong code is worse than a lookup. Leaving `kind` unset searches every classification of that country at once, which is the most expensive call here. Set it whenever the question already names one. Rows come back ordered by kind then code; there is no sort argument, and asking for one changes nothing.

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess.
kind––Narrows to one classification. All if unset.
limitinteger–Rows per page. 20 by default.
offsetinteger–Rows to skip. Use it to page, not to narrow — a term is cheaper than paging to find one row.
term––Matches the code or the description.
NameTypeReqDescription
dataarray––
next_page–––
page–––
per_page–––
prev_page–––
total–––

No examples provided.

validate_invoice_payload ~135

Check invoice data against the field rules without issuing anything. Nothing is sent to the tax authority and no document is created. The SDK models check field formats, and for nfe the rules the SEFAZ refuses a document over: ncm and cfop on every item, and a complete recipient address. Worth calling before issue_invoice whenever a field was inferred rather than given. This does not replace issuing: the authorizer's cross-field and fiscal rules are only checked when the document is transmitted.

NameTypeReqDescription
document_typestringyes–
itemsarrayyes–
recipient_address–––
NameTypeReqDescription
checkedstringyesWhat was checked, so the answer is not read as more than it is.
document_typestringyes–
errorsarray––
validbooleanyesTrue when no field rule was broken. It does not promise the authorizer will accept the document.

No examples provided.

Common questions

What is the Stackin MCP server?

Stackin is an MCP server listed in the public MCP registry as io.github.stackin-io/stackin. Issue and manage Brazilian fiscal documents: NF-e for goods, NFS-e for services. This page covers its hosted endpoint (https://mcp.stackin.io/mcp).

Is the Stackin MCP server safe to use?

Stackin scores 86 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Stackin MCP server expose?

Stackin exposes 16 tools: issue_invoice, consult_invoice, cancel_invoice, get_invoice_pdf, reissue_invoice, and 11 more. Their descriptions and schemas cost roughly 2,662 tokens of context every time the server is loaded.

Does the Stackin MCP server require authentication?

Yes. Stackin asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

Is the Stackin MCP server still maintained?

Stackin is still listed as active in the MCP registry. We last reached this channel on 29 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.