eno.vn Partner API MCP server
vn.eno/partner-apieno.vnstreamable-httpv1.0.2Scanned
Manage one storefront: listings, bulk catalogue sync, analytics and webhooks.
15 tools: 6 can delete or cancel things, 3 change things and 6 only read.
- Reads private data · 2
- Reads text others write · 8
- Can send data out · 1
- No findings
Tools listed without sign-in. Remote posture
Anlyon alternative
9 of these tools change something. Run those as governed actions.
Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.
anlyon.dev does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.
Import an OpenAPI spec →Its sign-in does not let Anlyon set up an OAuth client on its own, so there is no link to it here.
What the eno.vn Partner API MCP server can do
The eno.vn Partner API MCP server is published by eno.vn, a domain the MCP Registry verified. It has 15 tools. It can delete or cancel things (6 tools: update_shop, update_listing, set_listing_status, delete_listing and 2 more) and create or change data (3 tools: create_listing, bulk_create_listings and register_webhook). 6 tools only read.
2 tools read private data (analytics_summary and analytics_listings); 8 tools bring in text other people can write (update_shop, create_listing, update_listing and 5 more); 1 tool can send data out of your system (register_webhook). On its own it has all three parts of a prompt-injection exfiltration path: private data, text others write, and a way out.
None of the fixed checks matched anything in its tool definitions. That is not a safety guarantee.
Its remote endpoint lists its tools without sign-in, and its tools changed once since anlyon.dev first saw them.
Last scanned Nov 14, 2026, version 1.0.2.
Tools
Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.
15 tools
Deletes or cancels 6Claude Code: deny
delete_listingPermanently delete one of this shop's listings; it cannot be undone (use set_listing_status hidden to take it down instead).Reads text others writeNo findings
Why it is in this group
- The name "delete_listing" says "delete": a word for removing or ending something.
- The description says "Permanently delete".
- The server marks it destructive (destructiveHint: true).
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Permanently delete one of this shop's listings; it cannot be undone (use set_listing_status hidden to take it down instead). While the shop or the listing is under investigation (an open report, or the account is held or suspended) it is hidden instead of deleted: the result then says `deleted: false, hidden: true` and why.
Annotations the server declares
- title: Delete listing
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
delete_webhookRemove one of this shop's webhook endpoints; eno stops sending it events at once.No findings
Why it is in this group
- The name "delete_webhook" says "delete": a word for removing or ending something.
- The description says "cannot be undone".
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Remove one of this shop's webhook endpoints; eno stops sending it events at once. It cannot be undone: registering the address again gives a new id and a new secret.
Annotations the server declares
- title: Delete webhook
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
- openWorldHint: false
set_listing_statusPut one of this shop's listings on sale (active), mark it sold, or hide it from the site without deleting it.Reads text others writeNo findings
Why it is in this group
- The name "set_listing_status" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Put one of this shop's listings on sale (active), mark it sold, or hide it from the site without deleting it. Use sold when the item is gone and hidden to take it down for now; either can be undone by setting active again. Re-activating is refused with a reason when the account is held or suspended, or with `licence_check_required` while the listing waits for eno's licence check. Returns the status the listing now has.
Annotations the server declares
- title: Set listing status
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
sync_catalogueMake this shop's listings match your own catalogue, matched by your externalId: a new externalId creates a listing, a known one updates it in place, and a row's status can mark it …Reads text others writeNo findings
Why it is in this group
- The name "sync_catalogue" says "sync": a word for a change.
- The server marks it destructive (destructiveHint: true).
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Make this shop's listings match your own catalogue, matched by your externalId: a new externalId creates a listing, a known one updates it in place, and a row's status can mark it sold or hidden. In mode "full", every active listing whose externalId is missing from this payload is also hidden (listings without an externalId, such as ones posted on the website, are never touched). Up to 200 rows per call. Returns counts of created, updated, retired and failed rows and a result per row; when the account may not publish new listings, new rows are refused while edits still apply, and `publish_blocked` says why.
Annotations the server declares
- title: Sync catalogue
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
update_listingChange one of this shop's listings: only the fields you send change.Reads text others writeNo findings
Why it is in this group
- The name "update_listing" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Change one of this shop's listings: only the fields you send change. Photos you send replace the current set (public URLs are copied to eno's storage; the first 8 are used), and text is cut to the same lengths as create_listing. A job's pay is `salaryM`; a `price` sent for a job is read as its monthly salary in VND. An edit of a listing waiting for eno's licence check is saved with the listing kept unpublished until eno approves it (the result says `held: true`); this tool cannot change a subcategory or the licence values.
Annotations the server declares
- title: Update listing
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
update_shopChange this shop's profile: the name, bio, location and logo buyers see on its page, and the contact phone eno shares with a buyer inside its chat.Reads text others writeNo findings
Why it is in this group
- The name "update_shop" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Change this shop's profile: the name, bio, location and logo buyers see on its page, and the contact phone eno shares with a buyer inside its chat. Send only the fields to change; the others stay as they are (get_shop shows the current values). Long text is shortened to fit: name 120 characters, bio 1,000, location 120; a name needs at least 2. A phone number another shop already uses is refused with `phone_taken`. Returns `ok: true` once the change is saved.
Annotations the server declares
- title: Update shop profile
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
Changes things 3Claude Code: ask
bulk_create_listingsPost up to 200 new listings in one call, one row each (category, title, price in VND, optional text and photos as public image URLs).Reads text others writeNo findings
Why it is in this group
- The name "bulk_create_listings" says "create": a word for a change.
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Post up to 200 new listings in one call, one row each (category, title, price in VND, optional text and photos as public image URLs). Rows are independent: a bad row fails alone and the others are created. Returns how many were created and failed, and a result per row with the new id or the reason it failed. To keep eno matched to your own system by your own ids, use sync_catalogue instead.
Annotations the server declares
- title: Create listings in bulk
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
create_listingPost one new listing for this shop: a category, a title and a price in VND (a job gives its monthly salary in `salaryM` instead), and the district where the item is, with optional …Reads text others writeNo findings
Why it is in this group
- The name "create_listing" says "create": a word for a change.
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
Description, as the server wrote it Post one new listing for this shop: a category, a title and a price in VND (a job gives its monthly salary in `salaryM` instead), and the district where the item is, with optional text and condition. Photos are public image URLs that eno copies to its own storage (the first 8 are used): most categories need at least 3 photos of different angles, services need 1 and jobs none. Longer text is cut to fit: title 140 characters, description 5,000, district 80, condition 60. The listing goes live at once unless eno must check it first (`verified: false` in the result). Refused with a reason code, and nothing created, when photos or the district are missing (`photos_min`, `photo_required`, `location_required`), the text holds a phone number, the category is unknown or the account may not post right now. Returns the new listing's `id` (for update_listing and set_listing_status), `verified` (true when it is already public) and `held` (true while it waits for eno's licence check). Use it for a listing the seller has asked to post.
Annotations the server declares
- title: Create listing
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
register_webhookRegister an HTTPS endpoint of yours that eno will POST signed events to when this shop's listings are created, updated, change status or are deleted.Reads text others writeCan send data outNo findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
What it can reach
- untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
- outboundThe input takes a URL (input.url): a request to a URL can carry data to whoever runs it.
Description, as the server wrote it Register an HTTPS endpoint of yours that eno will POST signed events to when this shop's listings are created, updated, change status or are deleted. Returns the webhook with its signing secret, shown only this once: store it to verify each event's signature. A shop can have up to 10 webhooks.
Annotations the server declares
- title: Register webhook
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
Only reads 6Show 6 read-only tools
analytics_listingsRead views and leads (times a buyer opened contact) per listing per day over a date range, the last 30 days unless you choose one, with each listing's all-time totals.Reads private dataNo findings
Why it is in this group
- The description's first verb is "read": a word for reading.
What it can reach
- private-dataThe description's first sentence says "read" and "contact": it reads contacts.
Description, as the server wrote it Read views and leads (times a buyer opened contact) per listing per day over a date range, the last 30 days unless you choose one, with each listing's all-time totals. Answers a page of listings at a time with `next_cursor` for the next. Use analytics_summary for the shop's overall totals. Changes nothing.
Annotations the server declares
- title: Listing analytics
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
analytics_summaryRead this shop's totals in one call: how many listings it has, how many are active, sold or hidden, how many still wait for eno's check, and the total views and leads (times a buye…Reads private dataNo findings
Why it is in this group
- The description's first verb is "read": a word for reading.
What it can reach
- private-dataThe description's first sentence says "read" and "contact": it reads contacts.
Description, as the server wrote it Read this shop's totals in one call: how many listings it has, how many are active, sold or hidden, how many still wait for eno's check, and the total views and leads (times a buyer opened contact) across all of them. For per-listing, per-day figures use analytics_listings. Changes nothing.
Annotations the server declares
- title: Shop analytics summary
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
get_listingRead one of this shop's listings by id, in any status, with all its fields: title, text, price, status, category, location, photos, views and leads.No findings
Why it is in this group
- The name "get_listing" says "get": a word for reading.
Description, as the server wrote it Read one of this shop's listings by id, in any status, with all its fields: title, text, price, status, category, location, photos, views and leads. Use it to see the current values before update_listing. Fails with `not_found` when the id is not one of this shop's listings. Changes nothing.
Annotations the server declares
- title: Get listing
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
get_shopRead the storefront this connection acts for: its id, name, bio, location, phone, logo, trust score and tier, response rate, member-since date and how many listings are live now.No findings
Why it is in this group
- The name "get_shop" says "get": a word for reading.
Description, as the server wrote it Read the storefront this connection acts for: its id, name, bio, location, phone, logo, trust score and tier, response rate, member-since date and how many listings are live now. Use it to confirm which shop this connection acts for. Changes nothing.
Annotations the server declares
- title: Get shop profile
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
list_listingsList this shop's own listings, newest first, in every status unless you ask for one: active (on sale), sold or hidden.No findings
Why it is in this group
- The name "list_listings" says "list": a word for reading.
Description, as the server wrote it List this shop's own listings, newest first, in every status unless you ask for one: active (on sale), sold or hidden. Each page returns the listings with price, status, category and photos, plus `next_cursor` to fetch the next page. Use get_listing to read one listing by id. Changes nothing.
Annotations the server declares
- title: List listings
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
list_webhooksList the webhook endpoints registered for this shop: where events are sent, which events, whether delivery is on, and recent failures.No findings
Why it is in this group
- The name "list_webhooks" says "list": a word for reading.
Description, as the server wrote it List the webhook endpoints registered for this shop: where events are sent, which events, whether delivery is on, and recent failures. Signing secrets are never returned. Changes nothing.
Annotations the server declares
- title: List webhooks
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Exfil surface
Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.
16 paths in this server alone from private data, through text someone else wrote, to a way out. Denying 1 outbound tool breaks every one.
- Reads private data2
- Reads files, mail, messages, databases, secrets, calendars or repositories.
- Reads text others write8
- Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
- Can send data out1
- Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.
{
"permissions": {
"deny": [
"mcp__partner-api__register_webhook"
]
}
}Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.
Remote posture
What anyone on the internet sees at the remote endpoint: an anonymous initialize and tools/list, and the public OAuth metadata.
Looked at Nov 12, 2026, 10:20 UTC, unchanged since Nov 12, 2026. No credentials were sent and no tool was called. What is looked at.
- Reachable
- yes
- HTTP status of an anonymous initialize
- 200
- tools/list served without credentials
- yes
- Tools that change things, listed without credentials
- 11
- Protocol version
- 2025-06-18
- WWW-Authenticate on 401
- not observed
- resource_metadata in WWW-Authenticate
- not observed
- RFC 9728 protected resource metadata
- https://eno.vn/.well-known/oauth-protected-resource/api/mcp
- Authorization servers
- https://eno.vn
- Legacy HTTP+SSE transport
- no
- Dynamic client registration
- no
- Client ID metadata documents
- no
- HighThe whole server
The endpoint served tools/list without credentials, and the list has 11 tools that change things (2 destructive, 1 irreversible, 8 write). Whether a call also works without credentials was not tested: tools are never called.
What this check looks forMatched text
https://eno.vn/api/mcp: tools/list returned 15 tools to an anonymous client, including delete_listing (destructive), delete_webhook (destructive), analytics_listings (irreversible), update_shop (write), create_listing (write) and 6 more
Findings
Matches of fixed checks, with the text they matched.
No check matched anything in these tool definitions. That is not a safety guarantee.
History
Changes to its tool definitions and to its remote endpoint, newest first.
Tools15 changed.~15 changedView diff
- Changed:analytics_listingsOnly readstitledescriptioninputSchemaannotations
- Changed:analytics_summaryOnly readstitledescriptionannotations
- Changed:bulk_create_listingsChanges thingstitledescriptioninputSchemaannotations
- Changed:create_listingChanges thingstitledescriptioninputSchemaannotations
- Changed:delete_listingDeletes or cancelstitledescriptioninputSchemaannotations
- Changed:delete_webhookDeletes or cancelstitledescriptioninputSchemaannotations
- Changed:get_listingOnly readstitledescriptioninputSchemaannotations
- Changed:get_shopOnly readstitledescriptionannotations
- Changed:list_listingsOnly readstitledescriptioninputSchemaannotations
- Changed:list_webhooksOnly readstitledescriptionannotations
- Changed:register_webhookChanges thingstitledescriptioninputSchemaannotations
- Changed:set_listing_statusDeletes or cancelstitledescriptioninputSchemaannotations
- Changed:sync_catalogueDeletes or cancelstitledescriptioninputSchemaannotations
- Changed:update_listingDeletes or cancelstitledescriptioninputSchemaannotations
- Changed:update_shopDeletes or cancelstitledescriptioninputSchemaannotations
Install
Pinned to version 1.0.2. Values in angle brackets are yours to fill in.
claude mcp add --transport http partner-api https://eno.vn/api/mcpclaude mcp add --transport http partner-api https://eno.vn/api/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__partner-api__get_shop",
"mcp__partner-api__list_listings",
"mcp__partner-api__get_listing",
"mcp__partner-api__analytics_summary",
"mcp__partner-api__analytics_listings",
"mcp__partner-api__list_webhooks"
],
"ask": [
"mcp__partner-api__create_listing",
"mcp__partner-api__bulk_create_listings",
"mcp__partner-api__register_webhook"
],
"deny": [
"mcp__partner-api__update_shop",
"mcp__partner-api__update_listing",
"mcp__partner-api__set_listing_status",
"mcp__partner-api__delete_listing",
"mcp__partner-api__sync_catalogue",
"mcp__partner-api__delete_webhook"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as partner-api. Review it before you use it.
Capability tags behind 10 rules
- mcp__partner-api__update_shop untrusted-input
- mcp__partner-api__create_listing untrusted-input
- mcp__partner-api__update_listing untrusted-input
- mcp__partner-api__set_listing_status untrusted-input
- mcp__partner-api__delete_listing untrusted-input
- mcp__partner-api__bulk_create_listings untrusted-input
- mcp__partner-api__sync_catalogue untrusted-input
- mcp__partner-api__analytics_summary private-data
- mcp__partner-api__analytics_listings private-data
- mcp__partner-api__register_webhook untrusted-input, outbound
Pin
Keep the decision: fail CI when the tools change, follow every change, or show a badge.
Pin in CI
Fail a build when the tools you reviewed are not the tools the server serves today.
curl -s "https://anlyon.dev/api/v1/servers/vn.eno/partner-api/verify?hash=e26c7b4066a8981849d8891c7725e62a351147300d0c0efc0e0b3737b23da4a6" | jq -e '.changed == false'Pinned hash e26c7b4066a8, from Nov 14, 2026, 18:18 UTC.
Watch
Get told when its tools change: a new tool, a new description, a new class.
https://anlyon.dev/servers/vn.eno/partner-api/changes.xmlAn Atom feed. Works in any feed reader or Slack's RSS app.
Badge
[](https://anlyon.dev/servers/vn.eno/partner-api)Source: MCP Registry. Synced Nov 14, 2026, 18:18 UTC.
eno.vn Partner API MCP server: questions and answers
Answered from the scan above, not from the publisher's description.
Is the eno.vn Partner API MCP server safe?
- No scan can promise that. What its definitions show: 15 tools, 9 of which can change, send or delete something, and 0 findings from fixed checks. Allow the reads, ask before each change, and deny the deletes; the permissions block on this page does that.
Can the eno.vn Partner API MCP server delete data?
- Yes. 6 tools can delete, cancel or revoke something: update_shop, update_listing, set_listing_status, delete_listing, sync_catalogue and delete_webhook.
Can the eno.vn Partner API MCP server do things that cannot be undone?
- No tool is classed as irreversible: none of them sends, pays, publishes or merges, going by their definitions.
What tools does the eno.vn Partner API MCP server have?
- 15 tools: 6 destructive, 3 write, 6 read. update_shop, update_listing, set_listing_status, delete_listing, sync_catalogue, delete_webhook, create_listing, bulk_create_listings and 7 more.
Does the eno.vn Partner API MCP server need sign-in or OAuth?
- Its remote endpoint listed its tools to an anonymous client, without sign-in.
Does the eno.vn Partner API MCP server send data to outside services?
- 1 tool can carry data out (it sends, posts or publishes, or takes a recipient, channel or URL): register_webhook.
Has the eno.vn Partner API MCP server changed its tools?
- Yes, once since anlyon.dev started tracking it, most recently on Nov 14, 2026. Every change is on this page and in its Atom feed.