Stackin
REMOTE · MCP.STACKIN.IO · SCANNED SEP 29
Issue and manage Brazilian fiscal documents: NF-e for goods, NFS-e for services.
Available components
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
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- HSTS check failed: the Strict-Transport-Security header is absent. See how to fix → View diagnostics → Fail
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
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
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
claude mcp add --transport http stackin-io-stackin 'https://mcp.stackin.io/mcp'
{
"mcpServers": {
"stackin-io-stackin": {
"url": "https://mcp.stackin.io/mcp"
}
}
} {
"servers": {
"stackin-io-stackin": {
"type": "http",
"url": "https://mcp.stackin.io/mcp"
}
}
} [mcp_servers.stackin-io-stackin] url = "https://mcp.stackin.io/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"stackin-io-stackin": {
"type": "remote",
"url": "https://mcp.stackin.io/mcp",
"enabled": true
}
}
} openclaw mcp add stackin-io-stackin --url 'https://mcp.stackin.io/mcp' --transport streamable-http
mcp_servers:
stackin-io-stackin:
url: "https://mcp.stackin.io/mcp" {
"McpServers": {
"stackin-io-stackin": {
"Transport": "http",
"Url": "https://mcp.stackin.io/mcp"
}
}
} assistant mcp add stackin-io-stackin -t streamable-http -u 'https://mcp.stackin.io/mcp'
{
"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.
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
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 |
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 →
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.
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| document_type | string | yes | – |
| idempotency_key | – | – | – |
| reason | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| document_type | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| correction | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| document_type | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| content_base64 | string | yes | The PDF bytes, base64-encoded. Decode before saving. |
| content_type | string | – | – |
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.
| Name | Type | Req | Description |
|---|---|---|---|
| invoice_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| attempts | array | – | – |
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| number_end | integer | yes | – |
| number_start | integer | yes | – |
| reason | string | yes | – |
| series | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| client_name | string | yes | – |
| document_type | string | yes | – |
| idempotency_key | – | – | – |
| items | array | yes | – |
| number | – | – | – |
| recipient_address | – | – | – |
| series | – | – | – |
| tax_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| country | string | – | ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess. |
| Name | Type | Req | Description |
|---|---|---|---|
| kinds | array | – | – |
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.
| Name | Type | Req | Description |
|---|---|---|---|
| document_type | string | – | – |
| limit | integer | – | – |
| offset | integer | – | – |
| status | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| data | array | – | 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.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | – |
| offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| data | array | – | – |
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| code | string | yes | The code itself, as published: 84716052 for an NCM, 5102 for a CFOP. Digits only, no dots. |
| country | string | – | ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess. |
| kind | string | yes | cfop, ncm, cest, cst, csosn, ... |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| country | string | – | ISO 3166-1 alpha-2 code. A code means nothing without it, and Brazil is the default rather than a guess. |
| tax_id | string | yes | The exact tax id. A CNPJ is 14 digits. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| access_key | string | yes | – |
| manifestation | string | yes | – |
| reason | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| idempotency_key | – | – | – |
| invoice_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| country | string | – | 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. |
| limit | integer | – | Rows per page. 20 by default. |
| offset | integer | – | 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. |
| Name | Type | Req | Description |
|---|---|---|---|
| data | array | – | – |
| 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.
| Name | Type | Req | Description |
|---|---|---|---|
| document_type | string | yes | – |
| items | array | yes | – |
| recipient_address | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| checked | string | yes | What was checked, so the answer is not read as more than it is. |
| document_type | string | yes | – |
| errors | array | – | – |
| valid | boolean | yes | True when no field rule was broken. It does not promise the authorizer will accept the document. |
No examples provided.
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.