py2mcp.util#
Resolve object references and turn a mapping into CRUD functions.
Two small tools the builders in py2mcp.main rest on, usable on their
own: import_object is how 'module:function' strings from a config file
become callables, and store_to_funcs is the function-level half of
py2mcp.mk_mcp_from_store().
Main entry points:
import_object:'module.path:attr'string to the object it namesstore_to_funcs: list/get/set/delete functions over aMutableMapping
>>> from py2mcp.util import import_object
>>> import_object('os.path:basename')('/a/b/c.txt')
'c.txt'
Functions
|
Prefilled "Add custom connector" link for claude.ai. |
|
Resolve a |
|
Markdown link that installs an MCP server as a claude.ai connector. |
|
Convert a MutableMapping into CRUD functions. |
- py2mcp.util.claude_install_link(name, mcp_url, *, admin=False)[source]#
Prefilled “Add custom connector” link for claude.ai.
There is no true one-click install for an unlisted MCP server (listing requires Anthropic review), but this link opens the add-connector modal with the name and URL already filled in, so the user only has to confirm — which beats “go to Settings, find Connectors, paste this long URL”.
- Parameters:
name (
str) – Connector name to prefill (what the user will see in their list).mcp_url (
str) – Full URL of the MCP endpoint, e.g.https://host/api/x/mcp.admin (
bool) – Target the org-wide install page instead of the per-user one. Use it when an admin is rolling the connector out to a whole workspace; the default (False) is the personal install.
- Return type:
- Returns:
The claude.ai URL, safe to paste into a README or a chat message.
>>> claude_install_link('snout', 'https://example.com/api/snout_mcp/mcp') 'https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=snout&connectorUrl=https%3A%2F%2Fexample.com%2Fapi%2Fsnout_mcp%2Fmcp'
Names and URLs are percent-encoded, so spaces (and
&) can’t break the query string:>>> claude_install_link('my server', 'https://x.io/mcp', admin=True) 'https://claude.ai/admin-settings/connectors?modal=add-custom-connector&connectorName=my%20server&connectorUrl=https%3A%2F%2Fx.io%2Fmcp'
Note that the link is a convenience, not an access grant: if the server is an OAuth resource server with an allowlist, a user who isn’t on it can follow the link, complete the flow, and still be refused. Custom connectors are also a paid-plan feature, so the link goes nowhere for a Free-plan user.
- py2mcp.util.import_object(ref)[source]#
Resolve a
'module.path:attr'(preferred) or'module.path.attr'reference.Useful for building MCP servers from configuration strings (e.g. tool references declared in a file), so callers don’t reimplement the
importlibdance. With a colon, everything before it is the module and everything after it an attribute path; without one, the last dot splits module from attribute, so'pkg.mod.Class.method'cannot be reached in the dotted form (use'pkg.mod:Class.method').- Parameters:
ref (
str) – The reference string; themodule:attrform is preferred.- Return type:
- Returns:
The object the reference names, after importing its module.
- Raises:
ValueError – The reference has no module part or no attribute part.
ImportError – The module part does not import (
ModuleNotFoundErrorwhen the module does not exist; a plainImportErrorif it exists but fails while importing).AttributeError – The attribute path does not exist on the module.
Examples
>>> import_object('json:dumps') <function dumps at ...> >>> import_object('os.path.join') <function join at ...> >>> import_object('no-separator') Traceback (most recent call last): ... ValueError: Invalid object reference 'no-separator'; expected 'module:attr' or 'module.path.attr'.
See also
py2mcp.mk_mcp_from_refs(): build a server from such references.
- py2mcp.util.markdown_install_badge(name, mcp_url, *, admin=False)[source]#
Markdown link that installs an MCP server as a claude.ai connector.
The dominant use of
claude_install_link()is pasting one into a README, so this saves writing the same link syntax around it. Arguments are those ofclaude_install_link().>>> markdown_install_badge('snout', 'https://x.io/mcp') '[Add snout to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=snout&connectorUrl=https%3A%2F%2Fx.io%2Fmcp)'
Brackets and backslashes in the name are escaped in the link text, so a name like
tools [beta]can’t end the link text early and break the link (the URL itself is percent-encoded already):>>> print(markdown_install_badge('tools [beta]', 'https://x.io/mcp').split('](')[0]) [Add tools \[beta\] to Claude
- Return type:
- py2mcp.util.store_to_funcs(store, *, name='item', plural='')[source]#
Convert a MutableMapping into CRUD functions.
The functions close over
storeand operate on it live. The list function takes no arguments; the others takekey(andvaluefor set). Set and delete return a short confirmation string.- Parameters:
store (
MutableMapping[KT,VT]) – The mapping the functions read and write.name (
str) – Singular noun used in the function names.plural (
str) – Plural noun for the list function (defaults to name + ‘s’).
- Return type:
- Returns:
The four functions, in the order list, get, set, delete, named
list_<plural>,get_<name>,set_<name>,delete_<name>.
Examples
>>> projects = {'p1': {'name': 'Project 1'}} >>> funcs = store_to_funcs(projects, name='project') >>> len(funcs) 4 >>> [f.__name__ for f in funcs] ['list_projects', 'get_project', 'set_project', 'delete_project'] >>> list_projects, get_project, set_project, delete_project = funcs >>> set_project('p2', {'name': 'Project 2'}) "Set project 'p2'" >>> list_projects() ['p1', 'p2'] >>> delete_project('p1') "Deleted project 'p1'" >>> projects {'p2': {'name': 'Project 2'}}
See also
py2mcp.mk_mcp_from_store(): the same functions, served as MCP tools.