Introduction
When I connect an AI agent to a database, I want to control which AWS connection it can use, what operations it can perform, and whether an unauthorized request can reach the database.
In this walkthrough, I use Tables by ServerlessCreed, a DynamoDB GUI with a built-in MCP server, to connect Codex CLI to a non-production DynamoDB environment and test the access controls around that connection.
The workflow covers starting a local MCP server, exposing a single AWS profile, completing OAuth authorization, retrieving DynamoDB table metadata, and checking what happens when a request is made without authentication.
I also verify the server's network binding independently using PowerShell. This matters because a successful connection alone does not establish whether the server is listening only on the local machine.
Prerequisites
To reproduce the workflow, you need:
- Tables by ServerlessCreed installed. The installer is available from the official download page.
- Access to an approved, non-production DynamoDB environment.
- At least one AWS connection configured in Tables, preferably with read-only permissions.
- An MCP-compatible AI client, such as Codex CLI.
- PowerShell or another tool for verifying local network connections.
For this test, I used:
| Component | Configuration |
|---|---|
| AWS profile | read-only |
| Region | us-east-1 |
| MCP transport | OAuth-protected Streamable HTTP |
| MCP endpoint | http://127.0.0.1:61041/mcp |
| MCP client | Codex CLI 0.167.1 |
| Client model | GPT-6-Luna |
| OAuth consent | Read only |
The endpoint port was assigned during the test and may differ in another session.
1. Starting the MCP server and verifying local access
I opened the Workspace Agent panel in Tables, selected the MCP tab, and enabled the built-in MCP server.
Initially, no AWS profiles were exposed. This allowed the server to start without immediately making any configured AWS connection available to an external agent.
After the server started, Tables displayed the endpoint:
http://127.0.0.1:61041/mcp I then exposed the read-only AWS profile in us-east-1, leaving the other connections unexposed.
Figure 1 — Tables Workspace Agent showing the running MCP server, local endpoint, and exposed read-only AWS profile.
Verifying the loopback binding
Next, I checked whether the MCP server was actually listening on the loopback interface.
I used PowerShell to inspect the listening TCP connection:
$port = 61041 Get-NetTCPConnection -State Listen -LocalPort $port | Select-Object LocalAddress, LocalPort, State, OwningProcess Test-NetConnection 127.0.0.1 -Port $port The results showed:
| Check | Observed result |
|---|---|
| Local address | 127.0.0.1 |
| Port | 61041 |
| Connection state | Listen |
| TCP test | TcpTestSucceeded: True |
PowerShell confirms that the MCP server is listening on 127.0.0.1:61041, with TcpTestSucceeded: True. This independently verifies the observed local binding rather than relying only on the endpoint displayed in Tables.
This was the first important verification point. Rather than relying only on the endpoint shown in Tables, I confirmed that the observed listening socket was bound to the loopback address.
2. Exposing one AWS profile and authorizing Codex
With the server running, I moved to the client connection.
Tables generated a Codex CLI connection command for the exposed read-only profile.
I registered the profile-specific MCP endpoint using:
codex mcp add dynamoconsole-read-only --url "http://127.0.0.1:61041/mcp?profile=read-only" Codex detected OAuth support and opened the browser authorization flow.
The authorization request was then displayed inside the Tables Agent panel.
The request identified:
- Client: Codex
- Requested AWS profile:
read-only - Region:
us-east-1 - Advertised scope:
dynamoconsole:read - Selected permission: Read only
I kept the permission level set to Read only rather than granting broader access.

Codex requests access to the exposed read-only AWS profile in us-east-1. Tables displays the OAuth approval request with Read only permission selected before authorization.

After approving the request, Tables lists Codex as an authorized client with Read only access. The local MCP audit records the authorization approval and displays a verified audit chain.
Figure 3 — Tables showing Codex's OAuth request for the exposed read-only profile, with Read only consent selected.
After approving the connection, the browser displayed an authentication-complete message.
Tables also listed Codex under Approved clients, showing the authorized profile and Read only permission.
The local MCP audit recorded an authorization-approved event and displayed a verified audit-chain indicator.
Figure 4 — After OAuth approval, Tables lists Codex as an authorized MCP client with Read only access. The local audit records the authorization event and displays a verified audit chain.
This step demonstrated that starting the MCP server and granting a client access were separate operations.
The client needed explicit authorization before using the exposed AWS connection.
3. Listing DynamoDB tables through the MCP connection
Once OAuth authorization was complete, I opened Codex and inspected the connected MCP tools.
Codex reported that dynamoconsole-read-only was connected and exposed eight tools, including:
dynoconsole_table_listdynoconsole_table_describedynoconsole_item_getdynoconsole_query_preparedynoconsole_query_run
I began with table discovery rather than retrieving items or executing queries.
I asked Codex to use only the authorized MCP connection to list DynamoDB tables in us-east-1, without accessing item contents or modifying data.
Codex invoked:
dynoconsole_table_list The tool returned 14 DynamoDB tables through the approved read-only profile.
The response also reported:
truncated: false No item retrieval, query execution, or data modification was reported during this operation.
Figure 5 — Codex successfully invokes dynoconsole_table_list through the authorized read-only MCP connection and discovers 14 DynamoDB tables in us-east-1. The response reports truncated: false, with no item retrieval or data modifications performed.
Inspecting table metadata
I then used dynoconsole_table_describe to inspect a non-production table named DemoTable.
The tool returned:
| Attribute | Result |
|---|---|
| Table status | ACTIVE |
| Partition key | userID (String) |
| Sort key | None |
| Indexes | None reported |
| Billing mode | PAY_PER_REQUEST |
| Item count | 4 |
| Table size | 157 bytes |
The metadata request completed without retrieving the individual items stored in the table.
These two operations demonstrated that Codex could discover DynamoDB resources through the OAuth-authorized Tables MCP connection.
4. Testing profile isolation and unauthorized requests
After verifying authorized access, I checked how the connection behaved when the requested access was unavailable.
Attempting to access an unexposed profile
Although I had multiple AWS connections configured in Tables, only read-only was exposed to the MCP client.
I asked Codex to list tables using the unexposed admin-profile, without switching to another AWS connection or using the AWS CLI.
Codex reported that the connected MCP server provided tools only for the single approved profile.
It did not find an administrative-profile-specific tool, and no admin-profile request was executed.
This confirmed the profile restriction visible through the connected client. It was not a separate server-side bypass test.
Sending an unauthenticated MCP request
Next, I tested the MCP endpoint directly, without supplying an OAuth token.
Using PowerShell, I sent a JSON-RPC tools/list request to the local server.
The expected behavior was an authentication rejection rather than successful tool discovery.
The server returned:
HTTP Status: 401 Result: The remote server returned an error: (401) Unauthorized. Figure 6 — An unauthenticated tools/list request was sent directly to the local MCP endpoint using PowerShell. Tables returned HTTP 401 Unauthorized, confirming that the tested endpoint rejected tool discovery without an OAuth token.
This was the main negative security test.
The endpoint was reachable locally, but the unauthenticated request was rejected instead of returning the available MCP tools.
Checking the read-only tool boundary
I also inspected the capabilities available under the granted Read only consent.
Codex reported that the connected server exposed no write-staging or write-execution tools.
No write operation was attempted during this capability inspection.
This verified the restricted tools visible to the authorized client, although it did not independently test a write-capable request against the server.
5. Verifying recovery after an unauthorized request
Finally, I checked whether the rejected request affected an existing authorized connection.
After the unauthenticated request returned HTTP 401, I returned to the same Codex session and requested DynamoDB table discovery through the approved MCP connection.
Codex successfully invoked dynoconsole_table_list again.
The response returned:
Tables found: 14 Profile: read-only Region: us-east-1 truncated: false Figure 7 — After the unauthenticated MCP request was rejected with HTTP 401, Codex successfully retrieved 14 DynamoDB tables through the existing authorized read-only connection without repeating OAuth authorization.
This showed that the unsuccessful request did not prevent the previously authorized client from continuing its permitted read-only workflow.
I did not need to reconfigure the AWS profile or repeat OAuth authorization to perform the recovery check.
Practical takeaways
This test was mainly about whether an MCP client could access DynamoDB through an explicitly authorized connection while remaining within the tested access boundaries.
The important results were:
| Validation | Observed result |
|---|---|
| Local MCP server | Started successfully |
| Loopback binding | Verified on 127.0.0.1 |
| Profile exposure | One read-only profile exposed |
| OAuth consent | Read only approved |
| MCP connectivity | Connected with 8 tools |
| Authorized table listing | 14 tables returned |
| Table metadata inspection | Successful |
| Unexposed profile access | No admin-specific tools available |
| Unauthenticated request | HTTP 401 Unauthorized |
| Authorized recovery | Successful |
The testing demonstrated a working local MCP connection with selective profile exposure, OAuth-based client authorization, and rejection of an unauthenticated tool request.
There were also limits to what this test established. I did not independently validate a server-side profile-isolation bypass attempt, excessive-consent rejection, write staging, or every possible MCP authorization path. Cleanup verification was not part of the completed evidence.
For me, the useful part of this workflow is being able to connect an AI client to DynamoDB without automatically exposing every configured AWS profile or granting write-capable tools.
The test also reinforced why successful client connectivity is only a starting point. Verifying the listening interface, inspecting the granted permissions, testing unauthorized requests, and confirming authorized recovery provide much stronger evidence of how the integration behaves.
Application: Tables by ServerlessCreed
Download: Tables official download page








